Remove sorting from remaining method sets in liveness info.
Bug: 132593519
Change-Id: I27625a7c0ec3c9f9483000162800d658ac4b7bb6
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLens.java b/src/main/java/com/android/tools/r8/graph/GraphLens.java
index 87cea9c..b306683 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLens.java
@@ -544,15 +544,6 @@
return builder.build();
}
- public ImmutableSortedSet<DexMethod> rewriteMethodsSorted(Set<DexMethod> methods) {
- ImmutableSortedSet.Builder<DexMethod> builder =
- new ImmutableSortedSet.Builder<>(PresortedComparable::slowCompare);
- for (DexMethod method : methods) {
- builder.add(getRenamedMethodSignature(method));
- }
- return builder.build();
- }
-
public <T> ImmutableMap<DexField, T> rewriteFieldKeys(Map<DexField, T> map) {
ImmutableMap.Builder<DexField, T> builder = ImmutableMap.builder();
map.forEach((field, value) -> builder.put(getRenamedFieldSignature(field), value));
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 8ba06e0..d3a2531 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1206,7 +1206,7 @@
assert !method.isProcessed() || !isDebugMode;
assert !method.isProcessed()
|| !appView.enableWholeProgramOptimizations()
- || !appView.appInfo().withLiveness().neverReprocess.contains(method.method);
+ || !appView.appInfo().withLiveness().isNeverReprocessMethod(method.method);
if (lambdaMerger != null) {
timing.begin("Merge lambdas");
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
index 48aaf3a..3d86936 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -28,6 +29,7 @@
import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -122,20 +124,17 @@
PostMethodProcessor build(
AppView<AppInfoWithLiveness> appView, ExecutorService executorService, Timing timing)
throws ExecutionException {
- if (!appView.appInfo().reprocess.isEmpty()) {
+ Set<DexMethod> reprocessMethods = appView.appInfo().getReprocessMethods();
+ if (!reprocessMethods.isEmpty()) {
ProgramMethodSet set = ProgramMethodSet.create();
- appView
- .appInfo()
- .reprocess
- .forEach(
- reference -> {
- DexProgramClass clazz =
- asProgramClassOrNull(appView.definitionForHolder(reference));
- DexEncodedMethod definition = reference.lookupOnClass(clazz);
- if (definition != null) {
- set.createAndAdd(clazz, definition);
- }
- });
+ reprocessMethods.forEach(
+ reference -> {
+ DexProgramClass clazz = asProgramClassOrNull(appView.definitionForHolder(reference));
+ DexEncodedMethod definition = reference.lookupOnClass(clazz);
+ if (definition != null) {
+ set.createAndAdd(clazz, definition);
+ }
+ });
put(set);
}
if (methodsToReprocess.isEmpty()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index 96e5e9c..c11c8bf 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -305,7 +305,7 @@
private RewrittenPrototypeDescription getPrototypeChanges(
DexEncodedMethod encodedMethod, Strategy strategy) {
if (ArgumentRemovalUtils.isPinned(encodedMethod, appView)
- || appView.appInfo().keepConstantArguments.contains(encodedMethod.method)) {
+ || appView.appInfo().isKeepConstantArgumentsMethod(encodedMethod.method)) {
return RewrittenPrototypeDescription.none();
}
return RewrittenPrototypeDescription.createForUninstantiatedTypes(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
index 509daa1..6270034 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
@@ -284,7 +284,7 @@
private ArgumentInfoCollection collectUnusedArguments(
DexEncodedMethod method, MemberPool<DexMethod> methodPool) {
if (ArgumentRemovalUtils.isPinned(method, appView)
- || appView.appInfo().keepUnusedArguments.contains(method.method)) {
+ || appView.appInfo().isKeepUnusedArgumentsMethod(method.method)) {
return null;
}
// Only process classfile code objects.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
index b3e72bf..81c6a35 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
@@ -19,7 +19,7 @@
public static WhyAreYouNotInliningReporter createFor(
ProgramMethod callee, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
- if (appView.appInfo().whyAreYouNotInlining.contains(callee.getReference())) {
+ if (appView.appInfo().isWhyAreYouNotInliningMethod(callee.getReference())) {
return new WhyAreYouNotInliningReporterImpl(
callee, context, appView.options().testing.whyAreYouNotInliningConsumer);
}
@@ -28,7 +28,7 @@
public static void handleInvokeWithUnknownTarget(
InvokeMethod invoke, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
- if (appView.appInfo().whyAreYouNotInlining.isEmpty()) {
+ if (appView.appInfo().hasNoWhyAreYouNotInliningMethods()) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 4d5a549..ee7668c 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -32,7 +32,6 @@
import com.android.tools.r8.graph.FieldAccessInfoCollection;
import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
import com.android.tools.r8.graph.FieldResolutionResult;
-import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
import com.android.tools.r8.graph.InstantiatedSubTypeInfo;
import com.android.tools.r8.graph.LookupResult.LookupResultSuccess;
@@ -40,7 +39,6 @@
import com.android.tools.r8.graph.MethodAccessInfoCollection;
import com.android.tools.r8.graph.ObjectAllocationInfoCollection;
import com.android.tools.r8.graph.ObjectAllocationInfoCollectionImpl;
-import com.android.tools.r8.graph.PresortedComparable;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
@@ -70,9 +68,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -148,15 +143,15 @@
/** All methods that *must* never be inlined due to a configuration directive (testing only). */
private final Set<DexMethod> neverInline;
/** Items for which to print inlining decisions for (testing only). */
- public final Set<DexMethod> whyAreYouNotInlining;
+ private final Set<DexMethod> whyAreYouNotInlining;
/** All methods that may not have any parameters with a constant value removed. */
- public final Set<DexMethod> keepConstantArguments;
+ private final Set<DexMethod> keepConstantArguments;
/** All methods that may not have any unused arguments removed. */
- public final Set<DexMethod> keepUnusedArguments;
+ private final Set<DexMethod> keepUnusedArguments;
/** All methods that must be reprocessed (testing only). */
- public final Set<DexMethod> reprocess;
+ private final Set<DexMethod> reprocess;
/** All methods that must not be reprocessed (testing only). */
- public final Set<DexMethod> neverReprocess;
+ private final Set<DexMethod> neverReprocess;
/** All types that should be inlined if possible due to a configuration directive. */
public final PredicateSet<DexType> alwaysClassInline;
/** All types that *must* never be inlined due to a configuration directive (testing only). */
@@ -283,92 +278,6 @@
this.initClassReferences = initClassReferences;
}
- public AppInfoWithLiveness(
- AppInfoWithClassHierarchy appInfoWithClassHierarchy,
- Set<DexType> deadProtoTypes,
- Set<DexType> missingTypes,
- Set<DexType> liveTypes,
- Set<DexType> instantiatedAppServices,
- Set<DexMethod> targetedMethods,
- Set<DexMethod> failedResolutionTargets,
- Set<DexMethod> bootstrapMethods,
- Set<DexMethod> methodsTargetedByInvokeDynamic,
- SortedSet<DexMethod> virtualMethodsTargetedByInvokeDirect,
- SortedSet<DexMethod> liveMethods,
- FieldAccessInfoCollectionImpl fieldAccessInfoCollection,
- MethodAccessInfoCollection methodAccessInfoCollection,
- ObjectAllocationInfoCollectionImpl objectAllocationInfoCollection,
- Map<DexCallSite, ProgramMethodSet> callSites,
- KeepInfoCollection keepInfo,
- Map<DexReference, ProguardMemberRule> mayHaveSideEffects,
- Map<DexMember<?, ?>, ProguardMemberRule> noSideEffects,
- Map<DexMember<?, ?>, ProguardMemberRule> assumedValues,
- Set<DexMethod> alwaysInline,
- Set<DexMethod> forceInline,
- Set<DexMethod> neverInline,
- Set<DexMethod> whyAreYouNotInlining,
- Set<DexMethod> keepConstantArguments,
- Set<DexMethod> keepUnusedArguments,
- Set<DexMethod> reprocess,
- Set<DexMethod> neverReprocess,
- PredicateSet<DexType> alwaysClassInline,
- Set<DexType> neverClassInline,
- Set<DexType> noUnusedInterfaceRemoval,
- Set<DexType> noVerticalClassMerging,
- Set<DexType> noHorizontalClassMerging,
- Set<DexType> noStaticClassMerging,
- Set<DexReference> neverPropagateValue,
- Object2BooleanMap<DexReference> identifierNameStrings,
- Set<DexType> prunedTypes,
- Map<DexField, Int2ReferenceMap<DexField>> switchMaps,
- EnumValueInfoMapCollection enumValueInfoMaps,
- Set<DexType> lockCandidates,
- Map<DexType, Visibility> initClassReferences) {
- super(
- appInfoWithClassHierarchy.getSyntheticItems().commit(appInfoWithClassHierarchy.app()),
- appInfoWithClassHierarchy.getClassToFeatureSplitMap(),
- appInfoWithClassHierarchy.getMainDexClasses());
- this.deadProtoTypes = deadProtoTypes;
- this.missingTypes = missingTypes;
- this.liveTypes = liveTypes;
- this.instantiatedAppServices = instantiatedAppServices;
- this.targetedMethods = targetedMethods;
- this.failedResolutionTargets = failedResolutionTargets;
- this.bootstrapMethods = bootstrapMethods;
- this.methodsTargetedByInvokeDynamic = methodsTargetedByInvokeDynamic;
- this.virtualMethodsTargetedByInvokeDirect = virtualMethodsTargetedByInvokeDirect;
- this.liveMethods = liveMethods;
- this.fieldAccessInfoCollection = fieldAccessInfoCollection;
- this.methodAccessInfoCollection = methodAccessInfoCollection;
- this.objectAllocationInfoCollection = objectAllocationInfoCollection;
- this.keepInfo = keepInfo;
- this.mayHaveSideEffects = mayHaveSideEffects;
- this.noSideEffects = noSideEffects;
- this.assumedValues = assumedValues;
- this.callSites = callSites;
- this.alwaysInline = alwaysInline;
- this.forceInline = forceInline;
- this.neverInline = neverInline;
- this.whyAreYouNotInlining = whyAreYouNotInlining;
- this.keepConstantArguments = keepConstantArguments;
- this.keepUnusedArguments = keepUnusedArguments;
- this.reprocess = reprocess;
- this.neverReprocess = neverReprocess;
- this.alwaysClassInline = alwaysClassInline;
- this.neverClassInline = neverClassInline;
- this.noUnusedInterfaceRemoval = noUnusedInterfaceRemoval;
- this.noVerticalClassMerging = noVerticalClassMerging;
- this.noHorizontalClassMerging = noHorizontalClassMerging;
- this.noStaticClassMerging = noStaticClassMerging;
- this.neverPropagateValue = neverPropagateValue;
- this.identifierNameStrings = identifierNameStrings;
- this.prunedTypes = prunedTypes;
- this.switchMaps = switchMaps;
- this.enumValueInfoMaps = enumValueInfoMaps;
- this.lockCandidates = lockCandidates;
- this.initClassReferences = initClassReferences;
- }
-
private AppInfoWithLiveness(
AppInfoWithLiveness previous, CommittedItems committedItems, Set<DexType> removedTypes) {
this(
@@ -675,6 +584,30 @@
return neverInline.contains(method);
}
+ public boolean isWhyAreYouNotInliningMethod(DexMethod method) {
+ return whyAreYouNotInlining.contains(method);
+ }
+
+ public boolean hasNoWhyAreYouNotInliningMethods() {
+ return whyAreYouNotInlining.isEmpty();
+ }
+
+ public boolean isKeepConstantArgumentsMethod(DexMethod method) {
+ return keepConstantArguments.contains(method);
+ }
+
+ public boolean isKeepUnusedArgumentsMethod(DexMethod method) {
+ return keepUnusedArguments.contains(method);
+ }
+
+ public boolean isNeverReprocessMethod(DexMethod method) {
+ return neverReprocess.contains(method);
+ }
+
+ public Set<DexMethod> getReprocessMethods() {
+ return reprocess;
+ }
+
public Collection<DexClass> computeReachableInterfaces() {
Set<DexClass> interfaces = Sets.newIdentityHashSet();
WorkList<DexType> worklist = WorkList.newIdentityWorkList();
@@ -936,18 +869,6 @@
return holder == null || holder.isLibraryClass() || holder.isClasspathClass();
}
- private static SortedMap<DexMethod, ProgramMethodSet> rewriteInvokesWithContexts(
- Map<DexMethod, ProgramMethodSet> invokes, GraphLens lens) {
- SortedMap<DexMethod, ProgramMethodSet> result = new TreeMap<>(PresortedComparable::slowCompare);
- invokes.forEach(
- (method, contexts) ->
- result
- .computeIfAbsent(
- lens.getRenamedMethodSignature(method), ignore -> ProgramMethodSet.create())
- .addAll(contexts));
- return Collections.unmodifiableSortedMap(result);
- }
-
public boolean isInstantiatedInterface(DexProgramClass clazz) {
assert checkIfObsolete();
return objectAllocationInfoCollection.isInterfaceWithUnknownSubtypeHierarchy(clazz);
@@ -1085,11 +1006,11 @@
lens.rewriteMethods(alwaysInline),
lens.rewriteMethods(forceInline),
lens.rewriteMethods(neverInline),
- lens.rewriteMethodsSorted(whyAreYouNotInlining),
- lens.rewriteMethodsSorted(keepConstantArguments),
- lens.rewriteMethodsSorted(keepUnusedArguments),
- lens.rewriteMethodsSorted(reprocess),
- lens.rewriteMethodsSorted(neverReprocess),
+ lens.rewriteMethods(whyAreYouNotInlining),
+ lens.rewriteMethods(keepConstantArguments),
+ lens.rewriteMethods(keepUnusedArguments),
+ lens.rewriteMethods(reprocess),
+ lens.rewriteMethods(neverReprocess),
alwaysClassInline.rewriteItems(lens::lookupType),
lens.rewriteTypes(neverClassInline),
lens.rewriteTypes(noUnusedInterfaceRemoval),