Use graph lens for inlining constraints in horizontal class merging
Change-Id: I737a19fc847c64e76f5d9105be788ab75bda3103
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 8631e64..3457111 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -259,7 +259,7 @@
case Opcodes.INVOKEINTERFACE:
// Could have changed to an invoke-virtual instruction due to vertical class merging
// (if an interface is merged into a class).
- type = graphLens.lookupMethod(target, null, Type.INTERFACE).getType();
+ type = graphLens.lookupMethod(target, context.getReference(), Type.INTERFACE).getType();
assert type == Type.INTERFACE || type == Type.VIRTUAL;
break;
@@ -269,7 +269,7 @@
assert noNeedToUseGraphLens(target, type, graphLens);
} else if (target.holder == context.getHolderType()) {
// The method could have been publicized.
- type = graphLens.lookupMethod(target, null, Type.DIRECT).getType();
+ type = graphLens.lookupMethod(target, context.getReference(), Type.DIRECT).getType();
assert type == Type.DIRECT || type == Type.VIRTUAL;
} else {
// This is a super call. Note that the vertical class merger translates some invoke-super
@@ -287,7 +287,8 @@
case Opcodes.INVOKESTATIC:
{
// Static invokes may have changed as a result of horizontal class merging.
- MethodLookupResult lookup = graphLens.lookupMethod(target, null, Type.STATIC);
+ MethodLookupResult lookup =
+ graphLens.lookupMethod(target, context.getReference(), Type.STATIC);
target = lookup.getReference();
type = lookup.getType();
}
@@ -306,7 +307,7 @@
}
// Virtual invokes may have changed to interface invokes as a result of member rebinding.
- MethodLookupResult lookup = graphLens.lookupMethod(target, null, type);
+ MethodLookupResult lookup = graphLens.lookupMethod(target, context.getReference(), type);
target = lookup.getReference();
type = lookup.getType();
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/DontInlinePolicy.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/DontInlinePolicy.java
index 912f4d3..0fb2284 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/DontInlinePolicy.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/DontInlinePolicy.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.horizontalclassmerging.SingleClassPolicy;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -38,7 +37,7 @@
CfCode cfCode = code.asCfCode();
ConstraintWithTarget constraint =
- cfCode.computeInliningConstraint(method, appView, GraphLens.getIdentityLens(), method);
+ cfCode.computeInliningConstraint(method, appView, appView.graphLens(), method);
if (constraint == ConstraintWithTarget.NEVER) {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 5e65379..65d3583 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -380,21 +380,26 @@
// * Have access to the no-arg constructor of its first non-serializable superclass
return false;
}
- TraversalContinuation result =
- sourceClass.traverseProgramInstanceInitializers(
- method -> {
- AbortReason reason = disallowInlining(method, targetClass);
- if (reason != null) {
- // Cannot guarantee that markForceInline() will work.
- if (Log.ENABLED) {
- reason.printLogMessageForClass(sourceClass);
+
+ // If there is a constructor in the target, make sure that all source constructors can be
+ // inlined.
+ if (!Iterables.isEmpty(targetClass.programInstanceInitializers())) {
+ TraversalContinuation result =
+ sourceClass.traverseProgramInstanceInitializers(
+ method -> {
+ AbortReason reason = disallowInlining(method, targetClass);
+ if (reason != null) {
+ // Cannot guarantee that markForceInline() will work.
+ if (Log.ENABLED) {
+ reason.printLogMessageForClass(sourceClass);
+ }
+ return TraversalContinuation.BREAK;
}
- return TraversalContinuation.BREAK;
- }
- return TraversalContinuation.CONTINUE;
- });
- if (result.shouldBreak()) {
- return false;
+ return TraversalContinuation.CONTINUE;
+ });
+ if (result.shouldBreak()) {
+ return false;
+ }
}
if (sourceClass.getEnclosingMethodAttribute() != null
|| !sourceClass.getInnerClasses().isEmpty()) {
@@ -1683,12 +1688,6 @@
Code code = method.getDefinition().getCode();
if (code.isCfCode()) {
CfCode cfCode = code.asCfCode();
-
- // If we can't find a context to perform the inlining check on, abort.
- if (Iterables.isEmpty(context.programInstanceInitializers())) {
- return AbortReason.UNSAFE_INLINING;
- }
-
ConstraintWithTarget constraint =
cfCode.computeInliningConstraint(
method,
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
index dd1b6ca..109b0bc 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
@@ -34,6 +34,9 @@
.addKeepMainRule(Main.class)
.addOptionsModification(
options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+ .addHorizontallyMergedClassesInspector(
+ inspector ->
+ inspector.assertMerged(A.class, B.class).assertMergedIntoDifferentType(B.class))
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()