Widen vertical class merge policy slightly

Allow merging classes and interfaces with single a implementer if the
super type has no direct instantiations and no static fields or methods.

Change-Id: Ife712132da6bbd604b43fe6a292a714d4f9b3b7a
diff --git a/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoClassInitializationChangesPolicy.java b/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoClassInitializationChangesPolicy.java
index 8d137ee..870469d 100644
--- a/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoClassInitializationChangesPolicy.java
+++ b/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoClassInitializationChangesPolicy.java
@@ -6,7 +6,9 @@
 import static com.android.tools.r8.utils.MapUtils.ignoreKey;
 
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ObjectAllocationInfoCollection;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.verticalclassmerging.VerticalMergeGroup;
 import com.google.common.collect.Sets;
@@ -43,6 +45,23 @@
         return false;
       }
     }
+
+    ObjectAllocationInfoCollection objectAllocationInfoCollection =
+        appView.appInfo().getObjectAllocationInfoCollection();
+    // When the source class does not declare a class initializer, then we can merge
+    // regardless of the class initialization side effects in the target class if
+    // there is no way to trigger the class initialization side effects of the source
+    // class directly.
+    //
+    // We therefore check if the source class is not instantiated by a new-instance
+    // instruction, and that there cannot be any invoke-static of static-get
+    // instructions that target the source class.
+    if ((sourceClass.isInterface()
+            || !objectAllocationInfoCollection.isInstantiatedDirectly(sourceClass))
+        && !sourceClass.hasStaticFields()
+        && !sourceClass.getMethodCollection().hasDirectMethods(DexEncodedMethod::isStatic)) {
+      return true;
+    }
     assert !sourceClass.hasClassInitializer() || !targetClass.hasClassInitializer();
     return !targetClass.classInitializationMayHaveSideEffects(
             appView, type -> type.isIdenticalTo(sourceClass.getType()))