Move proto normalizer to backend

Fixes: b/225837659
Change-Id: Ice78c9e98a1deab616f3c9616d2300cbae442683
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index cf5b2c1..3e3c0ca 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -510,8 +510,6 @@
       // TODO(b/225838009): Horizontal merging currently assumes pre-phase CF conversion.
       LirConverter.enterLirSupportedPhase(appView, executorService);
 
-      new ProtoNormalizer(appViewWithLiveness).run(executorService, timing);
-
       // Clear traced methods roots to not hold on to the main dex live method set.
       appView.appInfo().getMainDexInfo().clearTracedMethodRoots();
 
@@ -761,6 +759,10 @@
                     ? finalRuntimeTypeCheckInfoBuilder.build(appView.graphLens())
                     : null);
         assert appView.dexItemFactory().verifyNoCachedTypeElements();
+
+        if (appView.hasLiveness()) {
+          new ProtoNormalizer(appViewWithLiveness).run(executorService, timing);
+        }
       }
 
       // Perform minification.
diff --git a/src/main/java/com/android/tools/r8/graph/CfCodeWithLens.java b/src/main/java/com/android/tools/r8/graph/CfCodeWithLens.java
index 9ccdfa6..4d2f9d9 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCodeWithLens.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCodeWithLens.java
@@ -27,6 +27,11 @@
   }
 
   @Override
+  public boolean hasExplicitCodeLens() {
+    return true;
+  }
+
+  @Override
   public GraphLens getCodeLens(AppView<?> appView) {
     assert codeLens != null;
     assert !codeLens.isIdentityLens();
diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java
index e665ee1..f00b07b 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -44,6 +44,10 @@
         + getClass().getCanonicalName());
   }
 
+  public boolean hasExplicitCodeLens() {
+    return false;
+  }
+
   public GraphLens getCodeLens(AppView<?> appView) {
     return appView.codeLens();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index 8232d93..6f89669 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -164,6 +164,11 @@
     return new DexCode(this) {
 
       @Override
+      public boolean hasExplicitCodeLens() {
+        return true;
+      }
+
+      @Override
       public GraphLens getCodeLens(AppView<?> appView) {
         return codeLens;
       }
diff --git a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
index 7c01711..8d18fc3 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
@@ -456,6 +456,10 @@
     return null;
   }
 
+  public boolean isProtoNormalizerLens() {
+    return false;
+  }
+
   public boolean isVerticalClassMergerLens() {
     return false;
   }
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index 8838470..1c8cdc9 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -202,6 +202,7 @@
               .setAppInfo(
                   appView.appInfoWithClassHierarchy().rebuildWithClassHierarchy(newApplication));
         }
+        appView.clearCodeRewritings(executorService, timing);
       }
     } else {
       assert mode.isFinal();
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
index 2ce9bac..6bd8269 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
@@ -305,6 +305,11 @@
     return new LirCode<>(lirBuilder.build()) {
 
       @Override
+      public boolean hasExplicitCodeLens() {
+        return true;
+      }
+
+      @Override
       public GraphLens getCodeLens(AppView<?> appView) {
         return lens;
       }
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
index fde81de..6b87383 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
@@ -61,6 +61,11 @@
   }
 
   @Override
+  public boolean hasExplicitCodeLens() {
+    return true;
+  }
+
+  @Override
   public GraphLens getCodeLens(AppView<?> appView) {
     return appView
         .graphLens()
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LirConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/LirConverter.java
index 5dcd034..f818817 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LirConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LirConverter.java
@@ -71,6 +71,12 @@
                 if (codeLens != appView.codeLens()) {
                   lirCode =
                       new LirCode<>(lirCode) {
+
+                        @Override
+                        public boolean hasExplicitCodeLens() {
+                          return true;
+                        }
+
                         @Override
                         public GraphLens getCodeLens(AppView<?> appView) {
                           return codeLens;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
index a336a3d..1ad49fd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
@@ -59,6 +59,7 @@
     optimizationInfo.unsetDynamicType();
     optimizationInfo.unsetInitializedClassesOnNormalExit();
     optimizationInfo.unsetInstanceInitializerInfoCollection();
+    optimizationInfo.unsetSimpleInliningConstraint();
     if (optimizationInfo.isEffectivelyDefault()) {
       method.unsetOptimizationInfo();
     }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java b/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
index 2d7dcee..e0112c3 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirLensCodeRewriter.java
@@ -132,6 +132,9 @@
 
   private boolean hasPotentialNonTrivialInvokeRewriting(
       DexMethod method, InvokeType type, MethodLookupResult result) {
+    if (graphLens.isProtoNormalizerLens()) {
+      return result.getPrototypeChanges().getArgumentInfoCollection().hasArgumentPermutation();
+    }
     VerticalClassMergerGraphLens verticalClassMergerLens = graphLens.asVerticalClassMergerLens();
     if (verticalClassMergerLens != null) {
       if (!result.getPrototypeChanges().isEmpty()) {
@@ -273,6 +276,13 @@
   }
 
   public LirCode<EV> rewrite() {
+    if (getCode().hasExplicitCodeLens()) {
+      // Only happens when the code is already rewritten, so simply clear the code lens and return.
+      assert getCode().getCodeLens(appView) == graphLens;
+      LirCode<EV> rewritten = new LirCode<>(getCode());
+      assert !rewritten.hasExplicitCodeLens();
+      return rewritten;
+    }
     if (hasNonTrivialMethodChanges()) {
       return rewriteWithLensCodeRewriter();
     }
@@ -288,10 +298,16 @@
     if (hasPrunedCatchHandlers(rewritten)) {
       rewritten = removeUnreachableBlocks(rewritten);
     }
+    assert !rewritten.hasExplicitCodeLens();
     return rewritten;
   }
 
   private boolean hasNonTrivialMethodChanges() {
+    if (graphLens.isProtoNormalizerLens()) {
+      RewrittenPrototypeDescription prototypeChanges =
+          graphLens.lookupPrototypeChangesForMethodDefinition(context.getReference(), codeLens);
+      return prototypeChanges.getArgumentInfoCollection().hasArgumentPermutation();
+    }
     VerticalClassMergerGraphLens verticalClassMergerLens = graphLens.asVerticalClassMergerLens();
     if (verticalClassMergerLens != null) {
       DexMethod previousReference =
diff --git a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
index a02ddf5..751c6d6 100644
--- a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
+import com.android.tools.r8.ir.conversion.LirConverter;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.KeepMethodInfo;
 import com.android.tools.r8.utils.DepthFirstSearchWorkListBase.StatefulDepthFirstSearchWorkList;
@@ -154,6 +155,8 @@
 
     if (!lensBuilder.isEmpty()) {
       appView.rewriteWithLens(lensBuilder.build(), executorService, timing);
+      LirConverter.rewriteLirWithLens(appView, timing, executorService);
+      appView.clearCodeRewritings(executorService, timing);
     }
     appView.notifyOptimizationFinishedForTesting();
     timing.end();
diff --git a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizerGraphLens.java b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizerGraphLens.java
index dd3f5bd..7d1314d 100644
--- a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizerGraphLens.java
@@ -41,6 +41,11 @@
   }
 
   @Override
+  public boolean isProtoNormalizerLens() {
+    return true;
+  }
+
+  @Override
   @SuppressWarnings("ReferenceEquality")
   public RewrittenPrototypeDescription lookupPrototypeChangesForMethodDefinition(
       DexMethod method, GraphLens codeLens) {
diff --git a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationDestinationOverrideLibraryTest.java b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationDestinationOverrideLibraryTest.java
index a62b27a..81e21c7 100644
--- a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationDestinationOverrideLibraryTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationDestinationOverrideLibraryTest.java
@@ -46,7 +46,6 @@
         .addLibraryClasses(LibraryClass.class)
         .setMinApi(parameters)
         .addKeepMainRule(Main.class)
-        .addDontObfuscate()
         .enableInliningAnnotations()
         .enableNoMethodStaticizingAnnotations()
         .compile()
diff --git a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithKeptMethodTest.java b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithKeptMethodTest.java
index cf5d688..09d8030 100644
--- a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithKeptMethodTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithKeptMethodTest.java
@@ -40,8 +40,6 @@
         .addKeepRules("-keep class " + Main.class.getTypeName() + " { void foo(...); }")
         .enableInliningAnnotations()
         .enableNoHorizontalClassMergingAnnotations()
-        // TODO(b/173398086): uniqueMethodWithName() does not work with proto changes.
-        .addDontObfuscate()
         .setMinApi(parameters)
         .compile()
         .inspect(
diff --git a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithLibraryOverrideTest.java b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithLibraryOverrideTest.java
index d39a33c..6cb0fd8 100644
--- a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithLibraryOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithLibraryOverrideTest.java
@@ -39,8 +39,6 @@
         .addDefaultRuntimeLibrary(parameters)
         .addKeepMainRule(Main.class)
         .enableInliningAnnotations()
-        // TODO(b/173398086): uniqueMethodWithName() does not work with proto changes.
-        .addDontObfuscate()
         .setMinApi(parameters)
         .compile()
         .inspect(
diff --git a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithParameterAnnotationsTest.java b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithParameterAnnotationsTest.java
index 49433d7..d97f188 100644
--- a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithParameterAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationWithParameterAnnotationsTest.java
@@ -43,11 +43,9 @@
         .addInnerClasses(getClass())
         .addKeepMainRule(Main.class)
         .addKeepClassAndMembersRules(Foo.class, Bar.class)
-        .addKeepRuntimeVisibleAnnotations()
+        .addKeepRuntimeVisibleParameterAnnotations()
         .enableInliningAnnotations()
         .enableNoHorizontalClassMergingAnnotations()
-        // TODO(b/173398086): uniqueMethodWithName() does not work with proto changes.
-        .addDontObfuscate()
         .setMinApi(parameters)
         .compile()
         .inspect(