Reapply "Rewrite if rule evaluator to enqueuer extension"
This reverts commit f1416468ece7aa2a22315f8521054194e3c19ba3.
Change-Id: I3499b412058762c2c3d5cf43ddbc28329eb9e562
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 bdad36f..a0b981b 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;
@@ -501,8 +500,6 @@
this.appInfo = appView.appInfo();
this.appView = appView.withClassHierarchy();
this.mode = mode;
- this.ifRuleEvaluatorFactory =
- new IfRuleEvaluatorFactory(appView.withClassHierarchy(), this, executorService);
this.profileCollectionAdditions = profileCollectionAdditions;
this.deferredTracing = EnqueuerDeferredTracing.create(appView, this, mode);
this.executorService = executorService;
@@ -536,6 +533,7 @@
ResourceAccessAnalysis.register(appView, this);
CovariantReturnTypeEnqueuerExtension.register(appView, this);
}
+ IfRuleEvaluatorFactory.register(appView, this, executorService);
targetedMethods = new LiveMethodsSet(graphReporter::registerMethod);
failedClassResolutionTargets = SetUtils.newIdentityHashSet(0);
@@ -832,6 +830,10 @@
return keepInfo.getClassInfo(clazz);
}
+ public SubtypingInfo getSubtypingInfo() {
+ return subtypingInfo;
+ }
+
public boolean hasMinimumKeepInfoThatMatches(
DexProgramClass clazz, Predicate<KeepClassInfo.Joiner> predicate) {
MinimumKeepInfoCollection minimumKeepInfoCollection =
@@ -4731,7 +4733,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;
@@ -4851,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 25334fd..1f316e2 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,14 +44,22 @@
Enqueuer enqueuer,
ExecutorService executorService) {
this.appView = appView;
- this.enqueuer = enqueuer;
- this.activeIfRules =
- createActiveIfRules(
- appView.hasRootSet() ? appView.rootSet().ifRules : Collections.emptySet());
+ 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.hasRootSet() ? appView.rootSet().ifRules : Collections.emptySet();
+ 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) {
@@ -99,10 +109,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 =
@@ -111,5 +130,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);
}
}