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();