Avoid that force inlining marks are overridden by delayed optimization feedback
Bug: 141735091
Change-Id: I1cad2d2da08c5f917c2e2840ab748ffd70dd4dd4
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
index 376e186..08aefe9 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
@@ -19,6 +19,8 @@
public interface MethodOptimizationFeedback {
+ void markForceInline(DexEncodedMethod method);
+
void markInlinedIntoSingleCallSite(DexEncodedMethod method);
void markMethodCannotBeKept(DexEncodedMethod method);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
index 162642c..d185a37 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
@@ -107,6 +107,11 @@
// METHOD OPTIMIZATION INFO:
@Override
+ public void markForceInline(DexEncodedMethod method) {
+ getMethodOptimizationInfoForUpdating(method).markForceInline();
+ }
+
+ @Override
public synchronized void markInlinedIntoSingleCallSite(DexEncodedMethod method) {
getMethodOptimizationInfoForUpdating(method).markInlinedIntoSingleCallSite();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
index ea5afa0..79b2e7f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
@@ -44,6 +44,9 @@
// METHOD OPTIMIZATION INFO:
@Override
+ public void markForceInline(DexEncodedMethod method) {}
+
+ @Override
public void markInlinedIntoSingleCallSite(DexEncodedMethod method) {}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
index 537cbd1..9119b4b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
@@ -52,6 +52,11 @@
// METHOD OPTIMIZATION INFO.
@Override
+ public void markForceInline(DexEncodedMethod method) {
+ // Ignored.
+ }
+
+ @Override
public synchronized void markInlinedIntoSingleCallSite(DexEncodedMethod method) {
method.getMutableOptimizationInfo().markInlinedIntoSingleCallSite();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroup.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroup.java
index a90efc7..4ce3033 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroup.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroup.java
@@ -79,6 +79,10 @@
}
}
+ public final boolean allLambdas(Predicate<LambdaInfo> predicate) {
+ return !anyLambda(lambda -> !predicate.test(lambda));
+ }
+
public final boolean anyLambda(Predicate<LambdaInfo> predicate) {
assert verifyLambdaIds(false);
for (LambdaInfo info : lambdas.values()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
index f399ad6..89451c9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -228,6 +228,11 @@
// sequential lambda ids, create group lambda classes.
Map<LambdaGroup, DexProgramClass> lambdaGroupsClasses = finalizeLambdaGroups();
+ // Mark all the implementation methods for force inlining.
+ for (LambdaGroup group : lambdaGroupsClasses.keySet()) {
+ group.forEachLambda(info -> info.clazz.virtualMethods().forEach(feedback::markForceInline));
+ }
+
// Fixup optimization info to ensure that the optimization info does not refer to any merged
// lambdas.
LambdaMergerOptimizationInfoFixer optimizationInfoFixer =
@@ -238,7 +243,6 @@
this.strategyFactory = (method, code) -> new ApplyStrategy(method, code, optimizationInfoFixer);
// Add synthesized lambda group classes to the builder.
-
for (Entry<LambdaGroup, DexProgramClass> entry : lambdaGroupsClasses.entrySet()) {
DexProgramClass synthesizedClass = entry.getValue();
appView.appInfo().addSynthesizedClass(synthesizedClass);
@@ -254,6 +258,18 @@
synthesizedClass.forEachMethod(
encodedMethod -> encodedMethod.markProcessed(ConstraintWithTarget.NEVER));
}
+
+ // Verify that all implementation methods are marked for force inlining (i.e., check that the
+ // delayed optimization feedback has been flushed).
+ assert lambdaGroupsClasses.keySet().stream()
+ .allMatch(
+ group ->
+ group.allLambdas(
+ lambda ->
+ lambda.clazz.virtualMethods().stream()
+ .map(DexEncodedMethod::getOptimizationInfo)
+ .allMatch(MethodOptimizationInfo::forceInline)));
+
converter.optimizeSynthesizedClasses(lambdaGroupsClasses.values(), executorService);
// Rewrite lambda class references into lambda group class
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
index 4226daa..15d4160 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
@@ -105,14 +105,6 @@
// anyways and our new method is a product of inlining.
MethodAccessFlags accessFlags = MAIN_METHOD_FLAGS.copy();
- // Mark all the impl methods for force inlining
- // LambdaGroupVirtualMethodSourceCode relies on.
- for (DexEncodedMethod implMethod : implMethods) {
- if (implMethod != null) {
- implMethod.getMutableOptimizationInfo().markForceInline();
- }
- }
-
DexMethod method = factory.createMethod(group.getGroupClassType(), methodProto, methodName);
result.add(
new DexEncodedMethod(