Wrapper around desugaring event consumers for profile rewriting
This CL rewrites the uses of {D8,R8}CfInstructionDesugaringEventConsumer to program up against the CfInstructionDesugaringEventConsumer.
This enables the introduction of a wrapper around these two, which can augment the ART baseline profile (if any) when desugaring happens.
The wrapper introduced by this CL currently only forwards to the {D8,R8}CfInstructionDesugaringEventConsumer, and is not currently being attached (i.e., it is still effectively unused).
Bug: b/265729283
Change-Id: Icfdc24e458604857762febc2f6cd1cb2fa62a5a0
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index 71d88d5..1ccb991 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.itf.InterfaceProcessor;
import com.android.tools.r8.utils.MapUtils;
import com.android.tools.r8.utils.ThreadUtils;
@@ -145,8 +144,8 @@
methodProcessor.addScheduled(clazz);
}
- D8CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumer =
- CfInstructionDesugaringEventConsumer.createForD8(methodProcessor);
+ CfInstructionDesugaringEventConsumer instructionDesugaringEventConsumer =
+ CfInstructionDesugaringEventConsumer.createForD8(appView, resultBuilder, methodProcessor);
// Process the wave and wait for all IR processing to complete.
methodProcessor.newWave();
@@ -157,8 +156,7 @@
// Finalize the desugaring of the processed classes. This may require processing (and
// reprocessing) of some methods.
- List<ProgramMethod> needsProcessing =
- instructionDesugaringEventConsumer.finalizeDesugaring(appView, resultBuilder);
+ List<ProgramMethod> needsProcessing = instructionDesugaringEventConsumer.finalizeDesugaring();
if (!needsProcessing.isEmpty()) {
// Create a new processor context to ensure unique method processing contexts.
methodProcessor.newWave();
@@ -212,10 +210,10 @@
}
abstract void convertClass(
- DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer);
+ DexProgramClass clazz, CfInstructionDesugaringEventConsumer desugaringEventConsumer);
void convertMethods(
- DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
+ DexProgramClass clazz, CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
converter.convertMethods(clazz, desugaringEventConsumer, methodProcessor, interfaceProcessor);
}
@@ -233,7 +231,7 @@
@Override
void convertClass(
- DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
+ DexProgramClass clazz, CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
convertMethods(clazz, desugaringEventConsumer);
}
@@ -257,7 +255,7 @@
@Override
void convertClass(
- DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
+ DexProgramClass clazz, CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
// Classes which has already been through library desugaring will not go through IR
// processing again.
LibraryDesugaredChecker libraryDesugaredChecker = new LibraryDesugaredChecker(appView);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index dc31133..547fef4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -36,7 +36,6 @@
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.D8CfPostProcessingDesugaringEventConsumer;
@@ -488,7 +487,7 @@
void convertMethods(
DexProgramClass clazz,
- D8CfInstructionDesugaringEventConsumer desugaringEventConsumer,
+ CfInstructionDesugaringEventConsumer desugaringEventConsumer,
D8MethodProcessor methodProcessor,
InterfaceProcessor interfaceProcessor) {
// When converting all methods on a class always convert <clinit> first.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index 8bd0077..42b36ff 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -29,6 +29,7 @@
import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer.RecordInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.twr.TwrCloseResourceDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaringEventConsumer;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCfInstructionDesugaringEventConsumer;
import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
import com.android.tools.r8.shaking.KeepMethodInfo.Joiner;
import com.google.common.collect.Sets;
@@ -63,30 +64,43 @@
ApiInvokeOutlinerDesugaringEventConsumer,
VarHandleDesugaringEventConsumer {
- public static D8CfInstructionDesugaringEventConsumer createForD8(
+ public static CfInstructionDesugaringEventConsumer createForD8(
+ AppView<?> appView,
+ ClassConverterResult.Builder classConverterResultBuilder,
D8MethodProcessor methodProcessor) {
- return new D8CfInstructionDesugaringEventConsumer(methodProcessor);
+ CfInstructionDesugaringEventConsumer eventConsumer =
+ new D8CfInstructionDesugaringEventConsumer(
+ appView, classConverterResultBuilder, methodProcessor);
+ return ArtProfileRewritingCfInstructionDesugaringEventConsumer.attachIfNeeded(eventConsumer);
}
- public static R8CfInstructionDesugaringEventConsumer createForR8(
+ public static CfInstructionDesugaringEventConsumer createForR8(
AppView<? extends AppInfoWithClassHierarchy> appView,
BiConsumer<LambdaClass, ProgramMethod> lambdaClassConsumer,
BiConsumer<ConstantDynamicClass, ProgramMethod> constantDynamicClassConsumer,
BiConsumer<ProgramMethod, ProgramMethod> twrCloseResourceMethodConsumer,
SyntheticAdditions additions,
BiConsumer<ProgramMethod, ProgramMethod> companionMethodConsumer) {
- return new R8CfInstructionDesugaringEventConsumer(
- appView,
- lambdaClassConsumer,
- constantDynamicClassConsumer,
- twrCloseResourceMethodConsumer,
- additions,
- companionMethodConsumer);
+ CfInstructionDesugaringEventConsumer eventConsumer =
+ new R8CfInstructionDesugaringEventConsumer(
+ appView,
+ lambdaClassConsumer,
+ constantDynamicClassConsumer,
+ twrCloseResourceMethodConsumer,
+ additions,
+ companionMethodConsumer);
+ return ArtProfileRewritingCfInstructionDesugaringEventConsumer.attachIfNeeded(eventConsumer);
}
+ public abstract List<ProgramMethod> finalizeDesugaring();
+
+ public abstract boolean verifyNothingToFinalize();
+
public static class D8CfInstructionDesugaringEventConsumer
extends CfInstructionDesugaringEventConsumer {
+ private final AppView<?> appView;
+ private final ClassConverterResult.Builder classConverterResultBuilder;
private final D8MethodProcessor methodProcessor;
private final Map<DexReference, InvokeSpecialBridgeInfo> pendingInvokeSpecialBridges =
@@ -94,7 +108,12 @@
private final List<LambdaClass> synthesizedLambdaClasses = new ArrayList<>();
private final List<ConstantDynamicClass> synthesizedConstantDynamicClasses = new ArrayList<>();
- private D8CfInstructionDesugaringEventConsumer(D8MethodProcessor methodProcessor) {
+ private D8CfInstructionDesugaringEventConsumer(
+ AppView<?> appView,
+ ClassConverterResult.Builder classConverterResultBuilder,
+ D8MethodProcessor methodProcessor) {
+ this.appView = appView;
+ this.classConverterResultBuilder = classConverterResultBuilder;
this.methodProcessor = methodProcessor;
}
@@ -231,17 +250,16 @@
methodProcessor.scheduleDesugaredMethodForProcessing(method);
}
- public List<ProgramMethod> finalizeDesugaring(
- AppView<?> appView, ClassConverterResult.Builder classConverterResultBuilder) {
+ @Override
+ public List<ProgramMethod> finalizeDesugaring() {
List<ProgramMethod> needsProcessing = new ArrayList<>();
- finalizeInvokeSpecialDesugaring(appView, needsProcessing::add);
+ finalizeInvokeSpecialDesugaring(needsProcessing::add);
finalizeLambdaDesugaring(classConverterResultBuilder, needsProcessing::add);
finalizeConstantDynamicDesugaring(needsProcessing::add);
return needsProcessing;
}
- private void finalizeInvokeSpecialDesugaring(
- AppView<?> appView, Consumer<ProgramMethod> needsProcessing) {
+ private void finalizeInvokeSpecialDesugaring(Consumer<ProgramMethod> needsProcessing) {
// Fixup the code of the new private methods have that been synthesized.
pendingInvokeSpecialBridges
.values()
@@ -288,6 +306,7 @@
synthesizedConstantDynamicClasses.clear();
}
+ @Override
public boolean verifyNothingToFinalize() {
assert pendingInvokeSpecialBridges.isEmpty();
assert synthesizedLambdaClasses.isEmpty();
@@ -473,10 +492,19 @@
twrCloseResourceMethodConsumer.accept(closeMethod, context);
}
- public void finalizeDesugaring() {
+ @Override
+ public List<ProgramMethod> finalizeDesugaring() {
finalizeInvokeSpecialDesugaring();
finalizeLambdaDesugaring();
// TODO(b/210485236): Finalize constant dynamic desugaring by rewriting signature if needed.
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean verifyNothingToFinalize() {
+ // Currently only used in D8.
+ assert false;
+ return true;
}
private void finalizeInvokeSpecialDesugaring() {
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
new file mode 100644
index 0000000..2386676
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCfInstructionDesugaringEventConsumer.java
@@ -0,0 +1,169 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.profile.art.rewriting;
+
+import com.android.tools.r8.graph.DexClasspathClass;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramField;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.LambdaClass;
+import com.android.tools.r8.ir.desugar.constantdynamic.ConstantDynamicClass;
+import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialBridgeInfo;
+import java.util.List;
+
+public class ArtProfileRewritingCfInstructionDesugaringEventConsumer
+ extends CfInstructionDesugaringEventConsumer {
+
+ private final CfInstructionDesugaringEventConsumer parent;
+
+ public ArtProfileRewritingCfInstructionDesugaringEventConsumer(
+ CfInstructionDesugaringEventConsumer parent) {
+ this.parent = parent;
+ }
+
+ public static CfInstructionDesugaringEventConsumer attachIfNeeded(
+ CfInstructionDesugaringEventConsumer eventConsumer) {
+ // TODO(b/265729283): Attach this wrapper when there is a baseline profile that needs rewriting.
+ return eventConsumer;
+ }
+
+ @Override
+ public void acceptAPIConversion(ProgramMethod method) {
+ parent.acceptAPIConversion(method);
+ }
+
+ @Override
+ public void acceptBackportedClass(DexProgramClass backportedClass, ProgramMethod context) {
+ parent.acceptBackportedClass(backportedClass, context);
+ }
+
+ @Override
+ public void acceptBackportedMethod(ProgramMethod backportedMethod, ProgramMethod context) {
+ parent.acceptBackportedMethod(backportedMethod, context);
+ }
+
+ @Override
+ public void acceptClasspathEmulatedInterface(DexClasspathClass clazz) {
+ parent.acceptClasspathEmulatedInterface(clazz);
+ }
+
+ @Override
+ public void acceptCollectionConversion(ProgramMethod arrayConversion) {
+ parent.acceptCollectionConversion(arrayConversion);
+ }
+
+ @Override
+ public void acceptCompanionClassClinit(ProgramMethod method) {
+ parent.acceptCompanionClassClinit(method);
+ }
+
+ @Override
+ public void acceptCompanionMethod(ProgramMethod method, ProgramMethod companionMethod) {
+ parent.acceptCompanionMethod(method, companionMethod);
+ }
+
+ @Override
+ public void acceptConstantDynamicClass(ConstantDynamicClass lambdaClass, ProgramMethod context) {
+ parent.acceptConstantDynamicClass(lambdaClass, context);
+ }
+
+ @Override
+ public void acceptCovariantRetargetMethod(ProgramMethod method) {
+ parent.acceptCovariantRetargetMethod(method);
+ }
+
+ @Override
+ public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
+ parent.acceptDesugaredLibraryRetargeterDispatchClasspathClass(clazz);
+ }
+
+ @Override
+ public void acceptEnumConversionClasspathClass(DexClasspathClass clazz) {
+ parent.acceptEnumConversionClasspathClass(clazz);
+ }
+
+ @Override
+ public void acceptGenericApiConversionStub(DexClasspathClass dexClasspathClass) {
+ parent.acceptGenericApiConversionStub(dexClasspathClass);
+ }
+
+ @Override
+ public void acceptInvokeSpecialBridgeInfo(InvokeSpecialBridgeInfo info) {
+ parent.acceptInvokeSpecialBridgeInfo(info);
+ }
+
+ @Override
+ public void acceptInvokeStaticInterfaceOutliningMethod(
+ ProgramMethod method, ProgramMethod context) {
+ parent.acceptInvokeStaticInterfaceOutliningMethod(method, context);
+ }
+
+ @Override
+ public void acceptLambdaClass(LambdaClass lambdaClass, ProgramMethod context) {
+ parent.acceptLambdaClass(lambdaClass, context);
+ }
+
+ @Override
+ public void acceptNestFieldGetBridge(ProgramField target, ProgramMethod bridge) {
+ parent.acceptNestFieldGetBridge(target, bridge);
+ }
+
+ @Override
+ public void acceptNestFieldPutBridge(ProgramField target, ProgramMethod bridge) {
+ parent.acceptNestFieldPutBridge(target, bridge);
+ }
+
+ @Override
+ public void acceptNestMethodBridge(ProgramMethod target, ProgramMethod bridge) {
+ parent.acceptNestMethodBridge(target, bridge);
+ }
+
+ @Override
+ public void acceptOutlinedMethod(ProgramMethod outlinedMethod, ProgramMethod context) {
+ parent.acceptOutlinedMethod(outlinedMethod, context);
+ }
+
+ @Override
+ public void acceptRecordClass(DexProgramClass recordClass) {
+ parent.acceptRecordClass(recordClass);
+ }
+
+ @Override
+ public void acceptRecordMethod(ProgramMethod method) {
+ parent.acceptRecordMethod(method);
+ }
+
+ @Override
+ public void acceptThrowMethod(ProgramMethod method, ProgramMethod context) {
+ parent.acceptThrowMethod(method, context);
+ }
+
+ @Override
+ public void acceptTwrCloseResourceMethod(ProgramMethod closeMethod, ProgramMethod context) {
+ parent.acceptTwrCloseResourceMethod(closeMethod, context);
+ }
+
+ @Override
+ public void acceptVarHandleDesugaringClass(DexProgramClass varHandleClass) {
+ parent.acceptVarHandleDesugaringClass(varHandleClass);
+ }
+
+ @Override
+ public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
+ parent.acceptWrapperClasspathClass(clazz);
+ }
+
+ @Override
+ public List<ProgramMethod> finalizeDesugaring() {
+ return parent.finalizeDesugaring();
+ }
+
+ @Override
+ public boolean verifyNothingToFinalize() {
+ assert parent.verifyNothingToFinalize();
+ return true;
+ }
+}
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 610cfa9..ea03644 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -111,7 +111,6 @@
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.R8CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.R8PostProcessingDesugaringEventConsumer;
@@ -4084,7 +4083,7 @@
});
}
- R8CfInstructionDesugaringEventConsumer eventConsumer =
+ CfInstructionDesugaringEventConsumer eventConsumer =
CfInstructionDesugaringEventConsumer.createForR8(
appView,
lambdaCallback,
@@ -4129,7 +4128,8 @@
additions.addMethodWithDesugaredCodeForTracing(companion);
}
- eventConsumer.finalizeDesugaring();
+ List<ProgramMethod> needsProcessing = eventConsumer.finalizeDesugaring();
+ assert needsProcessing.isEmpty();
pendingMethodMove.clear();
pendingCodeDesugaring.clear();