Remove subtyping info from horizontal class merger policy
Change-Id: I55bd5246ecf8e576d7456e43f995976c2cc4dea4
diff --git a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
index f7be3cf..dd9d171 100644
--- a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
@@ -8,12 +8,14 @@
import static com.android.tools.r8.utils.MapUtils.ignoreKey;
import static com.google.common.base.Predicates.alwaysTrue;
+import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
@@ -127,6 +129,19 @@
return immediateSubtypes.getOrDefault(clazz, Collections.emptyList());
}
+ public Iterable<DexProgramClass> getSubinterfaces(DexProgramClass clazz) {
+ assert clazz.isInterface();
+ return Iterables.filter(getSubclasses(clazz), DexClass::isInterface);
+ }
+
+ public Iterable<DexProgramClass> getSuperinterfaces(
+ DexProgramClass clazz, DexDefinitionSupplier definitions) {
+ return Iterables.filter(
+ Iterables.transform(
+ clazz.getInterfaces(), i -> asProgramClassOrNull(definitions.definitionFor(i, clazz))),
+ Objects::nonNull);
+ }
+
public boolean hasSubclasses(DexProgramClass clazz) {
return !getSubclasses(clazz).isEmpty();
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/PolicyScheduler.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/PolicyScheduler.java
index cb7bda1..d1d6d92 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/PolicyScheduler.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/PolicyScheduler.java
@@ -271,7 +271,7 @@
new NoDefaultInterfaceMethodMerging(appView),
new NoDefaultInterfaceMethodCollisions(appView, immediateSubtypingInfo),
new LimitInterfaceGroups(appView),
- new OnlyDirectlyConnectedOrUnrelatedInterfaces(appView));
+ new OnlyDirectlyConnectedOrUnrelatedInterfaces(appView, immediateSubtypingInfo));
}
private static boolean verifyMultiClassPoliciesIrrelevantForMergingSyntheticsInD8(
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/OnlyDirectlyConnectedOrUnrelatedInterfaces.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/OnlyDirectlyConnectedOrUnrelatedInterfaces.java
index 1ed803e..839b331 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/OnlyDirectlyConnectedOrUnrelatedInterfaces.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/OnlyDirectlyConnectedOrUnrelatedInterfaces.java
@@ -4,16 +4,12 @@
package com.android.tools.r8.horizontalclassmerging.policies;
-import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
-
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.graph.ImmediateProgramSubtypingInfo;
import com.android.tools.r8.horizontalclassmerging.HorizontalMergeGroup;
-import com.android.tools.r8.horizontalclassmerging.MultiClassPolicyWithPreprocessing;
+import com.android.tools.r8.horizontalclassmerging.MultiClassPolicy;
import com.android.tools.r8.utils.SetUtils;
import com.android.tools.r8.utils.WorkList;
import com.google.common.collect.ImmutableList;
@@ -26,7 +22,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ExecutorService;
import java.util.function.Function;
/**
@@ -54,24 +49,25 @@
* interface J extends IK, ... {}
* </pre>
*/
-public class OnlyDirectlyConnectedOrUnrelatedInterfaces
- extends MultiClassPolicyWithPreprocessing<SubtypingInfo> {
+public class OnlyDirectlyConnectedOrUnrelatedInterfaces extends MultiClassPolicy {
private final AppView<? extends AppInfoWithClassHierarchy> appView;
+ private final ImmediateProgramSubtypingInfo immediateSubtypingInfo;
// The interface merge groups that this policy has committed to so far.
private final Map<DexProgramClass, HorizontalMergeGroup> committed = new IdentityHashMap<>();
public OnlyDirectlyConnectedOrUnrelatedInterfaces(
- AppView<? extends AppInfoWithClassHierarchy> appView) {
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ ImmediateProgramSubtypingInfo immediateSubtypingInfo) {
this.appView = appView;
+ this.immediateSubtypingInfo = immediateSubtypingInfo;
}
// TODO(b/270398965): Replace LinkedList.
@Override
@SuppressWarnings({"JdkObsolete", "MixedMutabilityReturnType"})
- public Collection<HorizontalMergeGroup> apply(
- HorizontalMergeGroup group, SubtypingInfo subtypingInfo) {
+ public Collection<HorizontalMergeGroup> apply(HorizontalMergeGroup group) {
if (!group.isInterfaceGroup()) {
return ImmutableList.of(group);
}
@@ -79,7 +75,7 @@
List<MergeGroupWithInfo> newGroupsWithInfo = new ArrayList<>();
for (DexProgramClass clazz : group) {
Set<DexProgramClass> superInterfaces = computeSuperInterfaces(clazz);
- Set<DexProgramClass> subInterfaces = computeSubInterfaces(clazz, subtypingInfo);
+ Set<DexProgramClass> subInterfaces = computeSubInterfaces(clazz);
MergeGroupWithInfo newGroup = null;
for (MergeGroupWithInfo candidateGroup : newGroupsWithInfo) {
@@ -116,18 +112,17 @@
}
private Set<DexProgramClass> computeSuperInterfaces(DexProgramClass clazz) {
- return computeTransitiveSubOrSuperInterfaces(clazz, DexClass::getInterfaces);
+ return computeStrictTransitiveInterfaces(
+ clazz, i -> immediateSubtypingInfo.getSuperinterfaces(i, appView));
}
- private Set<DexProgramClass> computeSubInterfaces(
- DexProgramClass clazz, SubtypingInfo subtypingInfo) {
- return computeTransitiveSubOrSuperInterfaces(
- clazz, definition -> subtypingInfo.allImmediateExtendsSubtypes(definition.getType()));
+ private Set<DexProgramClass> computeSubInterfaces(DexProgramClass clazz) {
+ return computeStrictTransitiveInterfaces(clazz, immediateSubtypingInfo::getSubinterfaces);
}
- private Set<DexProgramClass> computeTransitiveSubOrSuperInterfaces(
+ private Set<DexProgramClass> computeStrictTransitiveInterfaces(
DexProgramClass clazz,
- Function<DexProgramClass, Iterable<DexType>> immediateSubOrSuperInterfacesProvider) {
+ Function<DexProgramClass, Iterable<DexProgramClass>> immediateSubOrSuperInterfacesProvider) {
WorkList<DexProgramClass> workList = WorkList.newWorkList(new LinkedHashSet<>());
// Intentionally not marking `clazz` as seen, since we only want the strict sub/super types.
workList.addIgnoringSeenSet(clazz);
@@ -137,14 +132,7 @@
if (group != null) {
workList.addIfNotSeen(group);
}
- for (DexType immediateSubOrSuperInterfaceType :
- immediateSubOrSuperInterfacesProvider.apply(interfaceDefinition)) {
- DexProgramClass immediateSubOrSuperInterface =
- asProgramClassOrNull(appView.definitionFor(immediateSubOrSuperInterfaceType));
- if (immediateSubOrSuperInterface != null) {
- workList.addIfNotSeen(immediateSubOrSuperInterface);
- }
- }
+ workList.addIfNotSeen(immediateSubOrSuperInterfacesProvider.apply(interfaceDefinition));
});
assert !workList.isSeen(clazz);
return workList.getMutableSeenSet();
@@ -161,12 +149,6 @@
}
@Override
- public SubtypingInfo preprocess(
- Collection<HorizontalMergeGroup> groups, ExecutorService executorService) {
- return SubtypingInfo.create(appView);
- }
-
- @Override
public boolean shouldSkipPolicy() {
return !appView.options().horizontalClassMergerOptions().isInterfaceMergingEnabled();
}