Reapply "Rewrite if rule evaluator to enqueuer extension"
This reverts commit 15288d969d4efec531b2fb30440eddbf7da2469a.
Change-Id: I9ad0bf0d9bb3773c41709d944d1f60456a1012e8
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 46d4c02..dfe2d75 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -270,7 +270,6 @@
// Don't hold a direct pointer to app info (use appView).
private AppInfoWithClassHierarchy appInfo;
private final AppView<AppInfoWithClassHierarchy> appView;
- private final IfRuleEvaluatorFactory ifRuleEvaluatorFactory;
private final EnqueuerDeferredTracing deferredTracing;
private final ExecutorService executorService;
private SubtypingInfo subtypingInfo;
@@ -500,8 +499,6 @@
InternalOptions options = appView.options();
this.appInfo = appView.appInfo();
this.appView = appView.withClassHierarchy();
- this.ifRuleEvaluatorFactory =
- new IfRuleEvaluatorFactory(appView.withClassHierarchy(), this, executorService);
this.profileCollectionAdditions = profileCollectionAdditions;
this.deferredTracing = EnqueuerDeferredTracing.create(appView, this, mode);
this.executorService = executorService;
@@ -535,6 +532,7 @@
ResourceAccessAnalysis.register(appView, this);
CovariantReturnTypeEnqueuerExtension.register(appView, this);
}
+ IfRuleEvaluatorFactory.register(appView, this, executorService);
targetedMethods = new LiveMethodsSet(graphReporter::registerMethod);
failedClassResolutionTargets = SetUtils.newIdentityHashSet(0);
@@ -831,6 +829,10 @@
return keepInfo.getClassInfo(clazz);
}
+ public SubtypingInfo getSubtypingInfo() {
+ return subtypingInfo;
+ }
+
public boolean hasMinimumKeepInfoThatMatches(
DexProgramClass clazz, Predicate<KeepClassInfo.Joiner> predicate) {
MinimumKeepInfoCollection minimumKeepInfoCollection =
@@ -4730,7 +4732,6 @@
long numberOfLiveItemsAfterProcessing = getNumberOfLiveItems();
if (numberOfLiveItemsAfterProcessing > numberOfLiveItems) {
timing.time("Conditional rules", () -> applicableRules.evaluateConditionalRules(this));
- ifRuleEvaluatorFactory.run(subtypingInfo, timing);
assert getNumberOfLiveItems() == numberOfLiveItemsAfterProcessing;
if (!worklist.isEmpty()) {
continue;
@@ -4762,6 +4763,7 @@
// opportunity to add items to the worklist.
for (EnqueuerAnalysis analysis : analyses) {
analysis.notifyFixpoint(this, worklist, executorService, timing);
+ assert getNumberOfLiveItems() == numberOfLiveItemsAfterProcessing;
}
if (!worklist.isEmpty()) {
continue;
@@ -4850,7 +4852,7 @@
}
}
- private long getNumberOfLiveItems() {
+ public long getNumberOfLiveItems() {
long result = liveTypes.getItems().size();
result += liveMethods.items.size();
result += liveFields.fields.size();
diff --git a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluatorFactory.java b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluatorFactory.java
index 5857e14..dc438f3 100644
--- a/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluatorFactory.java
+++ b/src/main/java/com/android/tools/r8/shaking/IfRuleEvaluatorFactory.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.graph.analysis.EnqueuerAnalysis;
import com.android.tools.r8.shaking.RootSetUtils.ConsequentRootSet;
import com.android.tools.r8.shaking.RootSetUtils.ConsequentRootSetBuilder;
import com.android.tools.r8.threading.TaskCollection;
@@ -25,15 +26,16 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-public class IfRuleEvaluatorFactory {
+public class IfRuleEvaluatorFactory extends EnqueuerAnalysis {
private final AppView<? extends AppInfoWithClassHierarchy> appView;
- private final Enqueuer enqueuer;
/** Map of active if rules. This is important for speeding up aapt2 generated keep rules. */
private final Map<Wrapper<ProguardIfRule>, Set<ProguardIfRule>> activeIfRules;
private final Set<DexProgramClass> effectivelyFakeLiveClasses;
+ private final Set<DexProgramClass> newlyLiveClasses = Sets.newIdentityHashSet();
+ private long previousNumberOfLiveItems = 0;
private final TaskCollection<?> tasks;
@@ -42,12 +44,21 @@
Enqueuer enqueuer,
ExecutorService executorService) {
this.appView = appView;
- this.enqueuer = enqueuer;
this.activeIfRules = createActiveIfRules(appView.rootSet().ifRules);
this.effectivelyFakeLiveClasses = createEffectivelyFakeLiveClasses(appView, enqueuer);
this.tasks = new TaskCollection<>(appView.options(), executorService);
}
+ public static void register(
+ AppView<? extends AppInfoWithClassHierarchy> appView,
+ Enqueuer enqueuer,
+ ExecutorService executorService) {
+ Set<ProguardIfRule> ifRules = appView.rootSet().ifRules;
+ if (ifRules != null && !ifRules.isEmpty()) {
+ enqueuer.registerAnalysis(new IfRuleEvaluatorFactory(appView, enqueuer, executorService));
+ }
+ }
+
@SuppressWarnings("MixedMutabilityReturnType")
private static Map<Wrapper<ProguardIfRule>, Set<ProguardIfRule>> createActiveIfRules(
Set<ProguardIfRule> ifRules) {
@@ -97,10 +108,19 @@
return false;
}
- public void run(SubtypingInfo subtypingInfo, Timing timing) throws ExecutionException {
+ @Override
+ public void notifyFixpoint(
+ Enqueuer enqueuer, EnqueuerWorklist worklist, ExecutorService executorService, Timing timing)
+ throws ExecutionException {
+ // TODO(b/206086945): Leverage newlyLiveClasses.
if (activeIfRules.isEmpty()) {
return;
}
+ long numberOfLiveItems = enqueuer.getNumberOfLiveItems();
+ if (numberOfLiveItems == previousNumberOfLiveItems) {
+ return;
+ }
+ SubtypingInfo subtypingInfo = enqueuer.getSubtypingInfo();
ConsequentRootSetBuilder consequentRootSetBuilder =
ConsequentRootSet.builder(appView, enqueuer, subtypingInfo);
IfRuleEvaluator evaluator =
@@ -109,5 +129,14 @@
"Find consequent items for -if rules...",
() -> evaluator.run(activeIfRules, effectivelyFakeLiveClasses));
enqueuer.addConsequentRootSet(consequentRootSetBuilder.buildConsequentRootSet());
+ previousNumberOfLiveItems = numberOfLiveItems;
+ }
+
+ @Override
+ public void processNewlyLiveClass(DexProgramClass clazz, EnqueuerWorklist worklist) {
+ if (effectivelyFakeLiveClasses.contains(clazz)) {
+ return;
+ }
+ newlyLiveClasses.add(clazz);
}
}