High-level structure for removing constant parameters
Change-Id: Icdb1ba49934a0cb75544adf5d213c5f31c26cd3e
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
index 115f31d..41f29a1 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagator.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -127,8 +128,13 @@
throws ExecutionException {
assert !appView.getSyntheticItems().hasPendingSyntheticClasses();
timing.begin("Argument propagator");
- populateParameterOptimizationInfo(executorService, timing);
- optimizeMethodParameters();
+ ImmediateProgramSubtypingInfo immediateSubtypingInfo =
+ ImmediateProgramSubtypingInfo.create(appView);
+ List<Set<DexProgramClass>> stronglyConnectedProgramComponents =
+ computeStronglyConnectedProgramClasses(appView, immediateSubtypingInfo);
+ populateParameterOptimizationInfo(
+ immediateSubtypingInfo, stronglyConnectedProgramComponents, executorService, timing);
+ optimizeMethodParameters(immediateSubtypingInfo, stronglyConnectedProgramComponents);
enqueueMethodsForProcessing(postMethodProcessorBuilder);
timing.end();
}
@@ -137,7 +143,11 @@
* Called by {@link IRConverter} *after* the primary optimization pass to populate the parameter
* optimization info.
*/
- private void populateParameterOptimizationInfo(ExecutorService executorService, Timing timing)
+ private void populateParameterOptimizationInfo(
+ ImmediateProgramSubtypingInfo immediateSubtypingInfo,
+ List<Set<DexProgramClass>> stronglyConnectedProgramComponents,
+ ExecutorService executorService,
+ Timing timing)
throws ExecutionException {
// Unset the scanner since all code objects have been scanned at this point.
assert appView.isAllCodeProcessed();
@@ -147,23 +157,39 @@
timing.begin("Compute optimization info");
new ArgumentPropagatorOptimizationInfoPopulator(
- appView, codeScannerResult, reprocessingCriteriaCollection)
+ appView,
+ immediateSubtypingInfo,
+ codeScannerResult,
+ reprocessingCriteriaCollection,
+ stronglyConnectedProgramComponents)
.populateOptimizationInfo(executorService, timing);
reprocessingCriteriaCollection = null;
timing.end();
}
/** Called by {@link IRConverter} to optimize method definitions. */
- private void optimizeMethodParameters() {
- // TODO(b/190154391): Remove parameters with constant values.
- // TODO(b/190154391): Remove unused parameters by simulating they are constant.
- // TODO(b/190154391): Strengthen the static type of parameters.
- // TODO(b/190154391): If we learn that a method returns a constant, then consider changing its
- // return type to void.
- // TODO(b/69963623): If we optimize a method to be unconditionally throwing (because it has a
- // bottom parameter), then for each caller that becomes unconditionally throwing, we could
- // also enqueue the caller's callers for reprocessing. This would propagate the throwing
- // information to all call sites.
+ private void optimizeMethodParameters(
+ ImmediateProgramSubtypingInfo immediateSubtypingInfo,
+ List<Set<DexProgramClass>> stronglyConnectedProgramComponents,
+ ExecutorService executorService)
+ throws ExecutionException {
+ Collection<ArgumentPropagatorGraphLens.Builder> partialGraphLensBuilders =
+ ThreadUtils.processItemsWithResults(
+ stronglyConnectedProgramComponents,
+ classes ->
+ new ArgumentPropagatorProgramOptimizer(appView, immediateSubtypingInfo)
+ .optimize(classes),
+ executorService);
+
+ // Merge all the partial, disjoint graph lens builders into a single graph lens.
+ ArgumentPropagatorGraphLens.Builder graphLensBuilder =
+ ArgumentPropagatorGraphLens.builder(appView);
+ partialGraphLensBuilders.forEach(graphLensBuilder::mergeDisjoint);
+
+ ArgumentPropagatorGraphLens graphLens = graphLensBuilder.build();
+ if (graphLens != null) {
+ appView.setGraphLens(graphLens);
+ }
}
/**
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java
new file mode 100644
index 0000000..0110197
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorGraphLens.java
@@ -0,0 +1,108 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.optimize.argumentpropagation;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLens;
+import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
+import com.android.tools.r8.graph.RewrittenPrototypeDescription;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
+public class ArgumentPropagatorGraphLens extends NonIdentityGraphLens {
+
+ ArgumentPropagatorGraphLens(AppView<AppInfoWithLiveness> appView) {
+ super(appView);
+ }
+
+ public static Builder builder(AppView<AppInfoWithLiveness> appView) {
+ return new Builder(appView);
+ }
+
+ @Override
+ public DexType getOriginalType(DexType type) {
+ return getPrevious().getOriginalType(type);
+ }
+
+ @Override
+ public Iterable<DexType> getOriginalTypes(DexType type) {
+ return getPrevious().getOriginalTypes(type);
+ }
+
+ @Override
+ public DexField getOriginalFieldSignature(DexField field) {
+ return getPrevious().getOriginalFieldSignature(field);
+ }
+
+ @Override
+ public DexField getRenamedFieldSignature(DexField originalField) {
+ return getPrevious().getRenamedFieldSignature(originalField);
+ }
+
+ @Override
+ public DexMethod getOriginalMethodSignature(DexMethod method) {
+ return getPrevious().getOriginalMethodSignature(method);
+ }
+
+ @Override
+ public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
+ return applied != this
+ ? getPrevious().getRenamedMethodSignature(originalMethod, applied)
+ : originalMethod;
+ }
+
+ @Override
+ protected DexType internalDescribeLookupClassType(DexType previous) {
+ return previous;
+ }
+
+ @Override
+ protected FieldLookupResult internalDescribeLookupField(FieldLookupResult previous) {
+ return previous;
+ }
+
+ @Override
+ protected MethodLookupResult internalDescribeLookupMethod(
+ MethodLookupResult previous, DexMethod context) {
+ return previous;
+ }
+
+ @Override
+ protected DexMethod internalGetPreviousMethodSignature(DexMethod method) {
+ return method;
+ }
+
+ @Override
+ public boolean isContextFreeForMethods() {
+ return getPrevious().isContextFreeForMethods();
+ }
+
+ @Override
+ public RewrittenPrototypeDescription lookupPrototypeChangesForMethodDefinition(DexMethod method) {
+ return getPrevious().lookupPrototypeChangesForMethodDefinition(method);
+ }
+
+ public static class Builder {
+
+ private final AppView<AppInfoWithLiveness> appView;
+
+ Builder(AppView<AppInfoWithLiveness> appView) {
+ this.appView = appView;
+ }
+
+ public ArgumentPropagatorGraphLens.Builder mergeDisjoint(
+ ArgumentPropagatorGraphLens.Builder partialGraphLensBuilder) {
+ // TODO(b/190154391): Implement.
+ return this;
+ }
+
+ public ArgumentPropagatorGraphLens build() {
+ // TODO(b/190154391): Implement.
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
index 39d1dc2..53876ab 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.optimize.argumentpropagation;
-import static com.android.tools.r8.optimize.argumentpropagation.utils.StronglyConnectedProgramClasses.computeStronglyConnectedProgramClasses;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -47,21 +46,19 @@
private final ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection;
private final ImmediateProgramSubtypingInfo immediateSubtypingInfo;
- private final List<Set<DexProgramClass>> stronglyConnectedComponents;
+ private final List<Set<DexProgramClass>> stronglyConnectedProgramComponents;
ArgumentPropagatorOptimizationInfoPopulator(
AppView<AppInfoWithLiveness> appView,
+ ImmediateProgramSubtypingInfo immediateSubtypingInfo,
MethodStateCollectionByReference methodStates,
- ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection) {
+ ArgumentPropagatorReprocessingCriteriaCollection reprocessingCriteriaCollection,
+ List<Set<DexProgramClass>> stronglyConnectedProgramComponents) {
this.appView = appView;
+ this.immediateSubtypingInfo = immediateSubtypingInfo;
this.methodStates = methodStates;
this.reprocessingCriteriaCollection = reprocessingCriteriaCollection;
-
- ImmediateProgramSubtypingInfo immediateSubtypingInfo =
- ImmediateProgramSubtypingInfo.create(appView);
- this.immediateSubtypingInfo = immediateSubtypingInfo;
- this.stronglyConnectedComponents =
- computeStronglyConnectedProgramClasses(appView, immediateSubtypingInfo);
+ this.stronglyConnectedProgramComponents = stronglyConnectedProgramComponents;
}
/**
@@ -80,7 +77,9 @@
// that the method returns the constant.
timing.begin("Propagate argument information for virtual methods");
ThreadUtils.processItems(
- stronglyConnectedComponents, this::processStronglyConnectedComponent, executorService);
+ stronglyConnectedProgramComponents,
+ this::processStronglyConnectedComponent,
+ executorService);
timing.end();
// Solve the parameter flow constraints.
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
new file mode 100644
index 0000000..859830b
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorProgramOptimizer.java
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.optimize.argumentpropagation;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ImmediateProgramSubtypingInfo;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import java.util.Set;
+
+public class ArgumentPropagatorProgramOptimizer {
+
+ private final AppView<AppInfoWithLiveness> appView;
+ private final ImmediateProgramSubtypingInfo immediateSubtypingInfo;
+
+ public ArgumentPropagatorProgramOptimizer(
+ AppView<AppInfoWithLiveness> appView, ImmediateProgramSubtypingInfo immediateSubtypingInfo) {
+ this.appView = appView;
+ this.immediateSubtypingInfo = immediateSubtypingInfo;
+ }
+
+ // TODO(b/190154391): Remove parameters with constant values.
+ // TODO(b/190154391): Remove unused parameters by simulating they are constant.
+ // TODO(b/190154391): Strengthen the static type of parameters.
+ // TODO(b/190154391): If we learn that a method returns a constant, then consider changing its
+ // return type to void.
+ // TODO(b/69963623): If we optimize a method to be unconditionally throwing (because it has a
+ // bottom parameter), then for each caller that becomes unconditionally throwing, we could
+ // also enqueue the caller's callers for reprocessing. This would propagate the throwing
+ // information to all call sites.
+ public ArgumentPropagatorGraphLens.Builder optimize(
+ Set<DexProgramClass> stronglyConnectedProgramClasses) {
+ return ArgumentPropagatorGraphLens.builder(appView);
+ }
+}