Rewrite AppInfoWithLiveness before pruning it after class merging

Change-Id: Ib3887e51e22bf23d54772b6782da02be2c4144ab
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index a4f2a44..f43bfc9 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -563,17 +563,17 @@
           HorizontalClassMergerGraphLens lens =
               merger.run(appBuilder, mainDexTracingResult, runtimeTypeCheckInfo);
           if (lens != null) {
-            DirectMappedDexApplication app = appBuilder.build();
+            // Must rewrite AppInfoWithLiveness before pruning the merged classes, to ensure that
+            // allocations sites, fields accesses, etc. are correctly transferred to the target
+            // classes.
+            appView.rewriteWithLensAndApplication(lens, appBuilder.build());
+            merger.recordSyntheticFieldAccesses();
             appView.pruneItems(
                 PrunedItems.builder()
-                    .setPrunedApp(app)
+                    .setPrunedApp(appView.appInfo().app())
                     .addRemovedClasses(appView.horizontallyMergedClasses().getSources())
                     .addNoLongerSyntheticItems(appView.horizontallyMergedClasses().getTargets())
                     .build());
-            appView.rewriteWithLens(lens);
-
-            // Only required for class merging, clear instance to save memory.
-            runtimeTypeCheckInfo = null;
           }
           timing.end();
         } else {
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 6115e7e..b1f1c31 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -39,6 +39,7 @@
 import com.android.tools.r8.horizontalclassmerging.policies.SameParentClass;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.FieldAccessInfoCollectionModifier;
+import com.android.tools.r8.shaking.KeepInfoCollection;
 import com.android.tools.r8.shaking.MainDexTracingResult;
 import com.android.tools.r8.shaking.RuntimeTypeCheckInfo;
 import com.google.common.collect.ImmutableList;
@@ -49,13 +50,19 @@
 import java.util.List;
 
 public class HorizontalClassMerger {
+
   private final AppView<AppInfoWithLiveness> appView;
+  private FieldAccessInfoCollectionModifier fieldAccessChanges;
 
   public HorizontalClassMerger(AppView<AppInfoWithLiveness> appView) {
     this.appView = appView;
     assert appView.options().enableInlining;
   }
 
+  public void recordSyntheticFieldAccesses() {
+    fieldAccessChanges.modify(appView);
+  }
+
   // TODO(b/165577835): replace Collection<DexProgramClass> with MergeGroup
   public HorizontalClassMergerGraphLens run(
       DirectMappedDexApplication.Builder appBuilder,
@@ -94,11 +101,18 @@
         new SyntheticArgumentClass.Builder().build(appView, appBuilder, allMergeClasses);
     applyClassMergers(classMergers, syntheticArgumentClass);
 
-    // Generate the class lens.
+    // Generate the graph lens.
     HorizontallyMergedClasses mergedClasses = mergedClassesBuilder.build();
     appView.setHorizontallyMergedClasses(mergedClasses);
-    return createLens(
-        mergedClasses, lensBuilder, fieldAccessChangesBuilder, syntheticArgumentClass);
+    HorizontalClassMergerGraphLens lens =
+        createLens(mergedClasses, lensBuilder, fieldAccessChangesBuilder, syntheticArgumentClass);
+    fieldAccessChanges = fieldAccessChangesBuilder.build();
+
+    // Prune keep info.
+    KeepInfoCollection keepInfo = appView.appInfo().getKeepInfo();
+    keepInfo.mutate(mutator -> mutator.removeKeepInfoForPrunedItems(mergedClasses.getSources()));
+
+    return lens;
   }
 
   private List<Policy> getPolicies(
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
index 87a1e31..551d229 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
@@ -14,7 +14,6 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodSignature;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.TreeFixerBase;
@@ -28,10 +27,8 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import java.util.Collections;
-import java.util.IdentityHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -41,7 +38,6 @@
  * tracked in {@link TreeFixer#lensBuilder}.
  */
 class TreeFixer extends TreeFixerBase {
-  private final Map<DexProto, DexProto> protoFixupCache = new IdentityHashMap<>();
   private final HorizontallyMergedClasses mergedClasses;
   private final HorizontalClassMergerGraphLens.Builder lensBuilder;
   private final FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder;
@@ -130,7 +126,7 @@
       subtypingForrest.traverseNodeDepthFirst(root, HashBiMap.create(), this::fixupProgramClass);
     }
     HorizontalClassMergerGraphLens lens = lensBuilder.build(appView, mergedClasses);
-    fieldAccessChangesBuilder.build(this::fixupMethodReference).modify(appView);
+    fieldAccessChangesBuilder.fixup(this::fixupMethodReference);
     new AnnotationFixer(lens).run(appView.appInfo().classes());
     return lens;
   }
diff --git a/src/main/java/com/android/tools/r8/shaking/FieldAccessInfoCollectionModifier.java b/src/main/java/com/android/tools/r8/shaking/FieldAccessInfoCollectionModifier.java
index 4e9d977..591ef6d 100644
--- a/src/main/java/com/android/tools/r8/shaking/FieldAccessInfoCollectionModifier.java
+++ b/src/main/java/com/android/tools/r8/shaking/FieldAccessInfoCollectionModifier.java
@@ -34,7 +34,7 @@
       }
     }
 
-    void fixUp(Function<DexMethod, DexMethod> fixUpMethod) {
+    void fixup(Function<DexMethod, DexMethod> fixUpMethod) {
       fixUpMethods(writeContexts, fixUpMethod);
       fixUpMethods(readContexts, fixUpMethod);
     }
@@ -74,10 +74,13 @@
 
     public Builder() {}
 
-    public FieldAccessInfoCollectionModifier build(Function<DexMethod, DexMethod> fixupMethod) {
-      for (FieldReferences fieldReference : newFieldAccesses.values()) {
-        fieldReference.fixUp(fixupMethod);
+    public void fixup(Function<DexMethod, DexMethod> fixupMethod) {
+      for (FieldReferences fieldReferences : newFieldAccesses.values()) {
+        fieldReferences.fixup(fixupMethod);
       }
+    }
+
+    public FieldAccessInfoCollectionModifier build() {
       return new FieldAccessInfoCollectionModifier(newFieldAccesses);
     }