Prune keep info for instance fields removed by merging
Change-Id: I838e6039c199b4d1633692d3d126033cb2f99b0e
diff --git a/src/main/java/com/android/tools/r8/graph/PrunedItems.java b/src/main/java/com/android/tools/r8/graph/PrunedItems.java
index 4f901fd..68c1dde 100644
--- a/src/main/java/com/android/tools/r8/graph/PrunedItems.java
+++ b/src/main/java/com/android/tools/r8/graph/PrunedItems.java
@@ -36,6 +36,10 @@
return new Builder();
}
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
public static PrunedItems empty(DexApplication application) {
return new Builder().setPrunedApp(application).build();
}
@@ -113,6 +117,17 @@
private final Set<DexField> removedFields = Sets.newIdentityHashSet();
private Set<DexMethod> removedMethods = Sets.newIdentityHashSet();
+ Builder() {}
+
+ Builder(PrunedItems prunedItems) {
+ additionalPinnedItems.addAll(prunedItems.getAdditionalPinnedItems());
+ noLongerSyntheticItems.addAll(prunedItems.getNoLongerSyntheticItems());
+ prunedApp = prunedItems.getPrunedApp();
+ removedClasses.addAll(prunedItems.getRemovedClasses());
+ removedFields.addAll(prunedItems.getRemovedFields());
+ removedMethods.addAll(prunedItems.getRemovedMethods());
+ }
+
public Builder setPrunedApp(DexApplication prunedApp) {
this.prunedApp = prunedApp;
return this;
@@ -129,6 +144,12 @@
return this;
}
+ public Builder addRemovedClass(DexType removedClass) {
+ this.noLongerSyntheticItems.add(removedClass);
+ this.removedClasses.add(removedClass);
+ return this;
+ }
+
public Builder addRemovedClasses(Set<DexType> removedClasses) {
this.noLongerSyntheticItems.addAll(removedClasses);
this.removedClasses.addAll(removedClasses);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index c76f43f..d7dc429 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMember;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger.Mode;
import com.android.tools.r8.horizontalclassmerging.code.ClassInitializerMerger;
import com.android.tools.r8.horizontalclassmerging.code.SyntheticInitializerConverter;
@@ -290,16 +291,21 @@
group.getTarget().setInterfaces(DexTypeList.create(interfaces));
}
- void mergeFields() {
+ void mergeFields(PrunedItems.Builder prunedItemsBuilder) {
if (group.hasClassIdField()) {
appendClassIdField();
}
- mergeInstanceFields();
+ mergeInstanceFields(prunedItemsBuilder);
mergeStaticFields();
}
- void mergeInstanceFields() {
- group.forEachSource(DexClass::clearInstanceFields);
+ void mergeInstanceFields(PrunedItems.Builder prunedItemsBuilder) {
+ group.forEachSource(
+ clazz -> {
+ clazz.forEachInstanceField(
+ field -> prunedItemsBuilder.addRemovedField(field.getReference()));
+ clazz.clearInstanceFields();
+ });
group.getTarget().setInstanceFields(classInstanceFieldsMerger.merge());
}
@@ -310,16 +316,18 @@
}
public void mergeGroup(
+ PrunedItems.Builder prunedItemsBuilder,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder) {
fixAccessFlags();
fixNestMemberAttributes();
mergeAnnotations();
mergeInterfaces();
- mergeFields();
+ mergeFields(prunedItemsBuilder);
mergeMethods(syntheticArgumentClass, syntheticInitializerConverterBuilder);
group.getTarget().clearClassSignature();
group.getTarget().forEachProgramMember(ProgramMember::clearGenericSignature);
+ group.forEachSource(clazz -> prunedItemsBuilder.addRemovedClass(clazz.getType()));
}
public static class Builder {
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 b14f07c..ad8d9df 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -103,7 +103,9 @@
: null;
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder =
SyntheticInitializerConverter.builder(appView, codeProvider);
- applyClassMergers(classMergers, syntheticArgumentClass, syntheticInitializerConverterBuilder);
+ PrunedItems prunedItems =
+ applyClassMergers(
+ classMergers, syntheticArgumentClass, syntheticInitializerConverterBuilder);
SyntheticInitializerConverter syntheticInitializerConverter =
syntheticInitializerConverterBuilder.build();
@@ -124,10 +126,7 @@
// Prune keep info.
KeepInfoCollection keepInfo = appView.getKeepInfo();
- keepInfo.mutate(
- mutator ->
- mutator.removeKeepInfoForMergedClasses(
- PrunedItems.builder().setRemovedClasses(mergedClasses.getSources()).build()));
+ keepInfo.mutate(mutator -> mutator.removeKeepInfoForMergedClasses(prunedItems));
// Must rewrite AppInfoWithLiveness before pruning the merged classes, to ensure that allocation
// sites, fields accesses, etc. are correctly transferred to the target classes.
@@ -142,12 +141,7 @@
}
appView.pruneItems(
- PrunedItems.builder()
- .setPrunedApp(appView.appInfo().app())
- .addRemovedClasses(mergedClasses.getSources())
- .addNoLongerSyntheticItems(mergedClasses.getSources())
- .build(),
- executorService);
+ prunedItems.toBuilder().setPrunedApp(appView.app()).build(), executorService);
}
private FieldAccessInfoCollectionModifier createFieldAccessInfoCollectionModifier(
@@ -220,13 +214,16 @@
}
/** Merges all class groups using {@link ClassMerger}. */
- private void applyClassMergers(
+ private PrunedItems applyClassMergers(
Collection<ClassMerger> classMergers,
SyntheticArgumentClass syntheticArgumentClass,
SyntheticInitializerConverter.Builder syntheticInitializerConverterBuilder) {
+ PrunedItems.Builder prunedItemsBuilder = PrunedItems.builder().setPrunedApp(appView.app());
for (ClassMerger merger : classMergers) {
- merger.mergeGroup(syntheticArgumentClass, syntheticInitializerConverterBuilder);
+ merger.mergeGroup(
+ prunedItemsBuilder, syntheticArgumentClass, syntheticInitializerConverterBuilder);
}
+ return prunedItemsBuilder.build();
}
/**
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index 570ed16..62529ed 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -249,6 +249,12 @@
if (prunedItems.hasRemovedClasses()) {
keepClassInfo.keySet().removeAll(prunedItems.getRemovedClasses());
}
+ if (prunedItems.hasRemovedFields()) {
+ keepFieldInfo.keySet().removeAll(prunedItems.getRemovedFields());
+ }
+ if (prunedItems.hasRemovedMembers()) {
+ keepMethodInfo.keySet().removeAll(prunedItems.getRemovedMethods());
+ }
}
public void removeKeepInfoForPrunedItems(PrunedItems prunedItems) {