Add utils to build and extend CodeOptimization.
Bug: 140766440
Change-Id: I3cddf8ac1d3542806b117cde8f728072bd676a2d
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CodeOptimization.java b/src/main/java/com/android/tools/r8/ir/conversion/CodeOptimization.java
index 5d73cd5..8a40db4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CodeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CodeOptimization.java
@@ -6,9 +6,14 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
+import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.Consumer;
/**
- * An abstraction of {@link IRCode}-level optimization.
+ * An abstraction of {@link IRCode}-level optimization, which may retrieve info from
+ * {@link AppView}; update {@link OptimizationFeedback}; or utilize {@link MethodProcessor}.
*/
public interface CodeOptimization {
@@ -17,9 +22,61 @@
// rewriting every affected optimization.
// Note that a code optimization can be a collection of other code optimizations.
// In that way, IRConverter will serve as the default full processing of all optimizations.
- void optimize(
- AppView<?> appView,
- IRCode code,
- OptimizationFeedback feedback,
- MethodProcessor methodProcessor);
+ void optimize(IRCode code, OptimizationFeedback feedback, MethodProcessor methodProcessor);
+
+ static CodeOptimization from(Consumer<IRCode> consumer) {
+ return (code, feedback, methodProcessor) -> {
+ consumer.accept(code);
+ };
+ }
+
+ static CodeOptimization sequence(CodeOptimization... codeOptimizations) {
+ return sequence(Arrays.asList(codeOptimizations));
+ }
+
+ static CodeOptimization sequence(Collection<CodeOptimization> codeOptimizations) {
+ return (code, feedback, methodProcessor) -> {
+ for (CodeOptimization codeOptimization : codeOptimizations) {
+ codeOptimization.optimize(code, feedback, methodProcessor);
+ }
+ };
+ }
+
+ /**
+ * Builder for {@link CodeOptimization}.
+ *
+ * Users can append either {@link CodeOptimization}, or simply {@link IRCode} consumer.
+ *
+ * Note that the order of everything that is appended through the builder matters.
+ */
+ public static class Builder {
+ private ImmutableList.Builder<CodeOptimization> processingQueue;
+
+ private Builder() {
+ processingQueue = ImmutableList.builder();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Builder addIRCodeConsumer(Consumer<IRCode> consumer) {
+ processingQueue.add(from(consumer));
+ return this;
+ }
+
+ public Builder addCodeOptimization(CodeOptimization optimization) {
+ processingQueue.add(optimization);
+ return this;
+ }
+
+ public CodeOptimization build() {
+ return (code, feedback, methodProcessor) -> {
+ processingQueue
+ .build()
+ .forEach(codeOptimization ->
+ codeOptimization.optimize(code, feedback, methodProcessor));
+ };
+ }
+ }
}
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 00d2f79..b3a6d66 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
@@ -1092,12 +1092,11 @@
feedback.markProcessed(method, ConstraintWithTarget.NEVER);
return;
}
- optimize(appView, code, feedback, methodProcessor);
+ optimize(code, feedback, methodProcessor);
}
// TODO(b/140766440): Convert all sub steps an implementer of CodeOptimization
private void optimize(
- AppView<?> appView,
IRCode code,
OptimizationFeedback feedback,
MethodProcessor methodProcessor) {
@@ -1218,7 +1217,7 @@
stringOptimizer.computeTrivialOperationsOnConstString(code);
stringOptimizer.removeTrivialConversions(code);
if (libraryMethodOptimizer != null) {
- libraryMethodOptimizer.optimize(appView, code, feedback, methodProcessor);
+ libraryMethodOptimizer.optimize(code, feedback, methodProcessor);
}
assert code.isConsistentSSA();
}
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 9ecc62d..7e0c9d5 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
@@ -153,7 +153,7 @@
}
// TODO(b/140768815): Reprocessing may trigger more methods to revisit. Update waves on-the-fly.
for (CodeOptimization codeOptimization : codeOptimizations) {
- codeOptimization.optimize(appView, code, feedback, this);
+ codeOptimization.optimize(code, feedback, this);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodOptimizer.java
index 0a92679..9c5a8d1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMethodOptimizer.java
@@ -24,10 +24,13 @@
public class LibraryMethodOptimizer implements CodeOptimization {
+ private final AppView<?> appView;
+
private final Map<DexType, LibraryMethodModelCollection> libraryMethodModelCollections =
new IdentityHashMap<>();
public LibraryMethodOptimizer(AppView<? extends AppInfoWithSubtyping> appView) {
+ this.appView = appView;
register(new BooleanMethodOptimizer(appView));
}
@@ -39,7 +42,6 @@
@Override
public void optimize(
- AppView<?> appView,
IRCode code,
OptimizationFeedback feedback,
MethodProcessor methodProcessor) {