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