Add a testing option to disable inlining of outlines
Bug: b/335083074
Change-Id: I03aa2c73e00846fb7719090dd5d8aac10b808791
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
index 20f7598..55a301c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
@@ -72,6 +72,7 @@
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackDelayed;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackIgnore;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.KeepMethodInfo.Joiner;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
import com.android.tools.r8.utils.ListUtils;
@@ -1402,6 +1403,7 @@
},
executorService);
List<ProgramMethod> outlineMethods = buildOutlineMethods(eventConsumer);
+ disallowInlining(outlineMethods);
MethodProcessorEventConsumer methodProcessorEventConsumer =
MethodProcessorEventConsumer.empty();
converter.optimizeSynthesizedMethods(
@@ -1431,6 +1433,21 @@
timing.end();
}
+ private void disallowInlining(List<ProgramMethod> outlineMethods) {
+ if (appView.testing().allowInliningOfOutlines) {
+ return;
+ }
+ appView
+ .getKeepInfo()
+ .mutate(
+ keepInfo -> {
+ for (ProgramMethod outlineMethod : outlineMethods) {
+ keepInfo.registerCompilerSynthesizedMethod(outlineMethod);
+ keepInfo.joinMethod(outlineMethod, Joiner::disallowInlining);
+ }
+ });
+ }
+
private void forEachSelectedOutliningMethod(
IRConverter converter,
ProgramMethodSet methodsSelectedForOutlining,
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index b883be0..2f02791 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -417,9 +417,9 @@
for (Pair<DexMethod, DexClassAndMethod> pair : targets) {
DexMethod method = pair.getFirst();
DexClassAndMethod target = pair.getSecond();
- DexMethod bridgeMethod =
+ DexMethod bridgeMethodReference =
method.withHolder(bridgeHolder.getType(), appView.dexItemFactory());
- if (bridgeHolder.getMethodCollection().getMethod(bridgeMethod) == null) {
+ if (bridgeHolder.getMethodCollection().getMethod(bridgeMethodReference) == null) {
DexEncodedMethod targetDefinition = target.getDefinition();
DexEncodedMethod bridgeMethodDefinition =
targetDefinition.toForwardingMethod(
@@ -445,21 +445,19 @@
assert !bridgeMethodDefinition.belongsToVirtualPool()
|| !bridgeMethodDefinition.isLibraryMethodOverride().isUnknown();
bridgeHolder.addMethod(bridgeMethodDefinition);
+ ProgramMethod bridgeMethod = bridgeMethodDefinition.asProgramMethod(bridgeHolder);
if (!appView.options().debug) {
// TODO(b/333677610): Register these methods in debug mode as well.
- appView
- .getKeepInfo()
- .registerCompilerSynthesizedMethod(bridgeMethodDefinition.getReference());
+ appView.getKeepInfo().registerCompilerSynthesizedMethod(bridgeMethod);
}
- eventConsumer.acceptMemberRebindingBridgeMethod(
- bridgeMethodDefinition.asProgramMethod(bridgeHolder), target);
+ eventConsumer.acceptMemberRebindingBridgeMethod(bridgeMethod, target);
}
assert appView
.appInfo()
.unsafeResolveMethodDueToDexFormat(method)
.getResolvedMethod()
.getReference()
- .isIdenticalTo(bridgeMethod);
+ .isIdenticalTo(bridgeMethodReference);
}
});
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 78023f5..a021521 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -4223,7 +4223,7 @@
minimumSyntheticKeepInfo.forEach(
(method, minimumKeepInfoForMethod) -> {
- enqueuer.getKeepInfo().registerCompilerSynthesizedMethod(method.getReference());
+ enqueuer.getKeepInfo().registerCompilerSynthesizedMethod(method);
enqueuer.applyMinimumKeepInfoWhenLiveOrTargeted(method, minimumKeepInfoForMethod);
});
}
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index 0ce4107..32835e2 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -91,7 +91,7 @@
*/
public abstract KeepMethodInfo getMethodInfo(DexEncodedMethod method, DexProgramClass holder);
- public abstract KeepMethodInfo registerCompilerSynthesizedMethod(DexMethod method);
+ public abstract void registerCompilerSynthesizedMethod(ProgramMethod method);
/**
* Base accessor for keep info on a field.
@@ -528,10 +528,9 @@
}
@Override
- public KeepMethodInfo registerCompilerSynthesizedMethod(DexMethod method) {
- assert !keepMethodInfo.containsKey(method);
- keepMethodInfo.put(method, SyntheticKeepMethodInfo.newEmptyJoiner().join());
- return keepMethodInfo.get(method);
+ public void registerCompilerSynthesizedMethod(ProgramMethod method) {
+ assert !keepMethodInfo.containsKey(method.getReference());
+ keepMethodInfo.put(method.getReference(), SyntheticKeepMethodInfo.bottom());
}
public void registerCompilerSynthesizedMethods(KeepInfoCollection keepInfoCollection) {
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 27b7af9..4dd6e38 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -2334,6 +2334,7 @@
public boolean allowClassInliningOfSynthetics = true;
public boolean allowInjectedAnnotationMethods = false;
+ public boolean allowInliningOfOutlines = true;
public boolean allowInliningOfSynthetics = true;
public boolean allowNullDynamicTypeInCodeScanner = true;
public boolean allowTypeErrors =