Reland "Insert Identity lens after IR processing"
Change-Id: I0b0421de0f31a727163eedb3c0a7bedd3ef059a6
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 3ce7b0a..1f24d35 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -156,6 +156,10 @@
allCodeProcessed = true;
}
+ public GraphLense clearCodeRewritings() {
+ return graphLense = graphLense.withCodeRewritingsApplied();
+ }
+
public AppServices appServices() {
return appServices;
}
diff --git a/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java b/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
index 18f8fe6..a05883a 100644
--- a/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/AppliedGraphLens.java
@@ -8,7 +8,6 @@
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import java.util.IdentityHashMap;
-import java.util.List;
import java.util.Map;
/**
@@ -29,7 +28,7 @@
new IdentityHashMap<>();
public AppliedGraphLens(
- AppView<? extends AppInfoWithSubtyping> appView, List<DexProgramClass> classes) {
+ AppView<? extends AppInfoWithSubtyping> appView, Iterable<DexProgramClass> classes) {
this.appView = appView;
for (DexProgramClass clazz : classes) {
@@ -135,4 +134,9 @@
public boolean isContextFreeForMethods() {
return true;
}
+
+ @Override
+ public boolean hasCodeRewritings() {
+ return false;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index f1d1a34..e01f0ee 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -223,10 +223,21 @@
return IdentityGraphLense.getInstance();
}
+ public boolean hasCodeRewritings() {
+ return true;
+ }
+
public final boolean isIdentityLense() {
return this == getIdentityLense();
}
+ public GraphLense withCodeRewritingsApplied() {
+ if (hasCodeRewritings()) {
+ return new ClearCodeRewritingGraphLens(this);
+ }
+ return this;
+ }
+
public <T extends DexDefinition> boolean assertDefinitionsNotModified(Iterable<T> definitions) {
for (DexDefinition definition : definitions) {
DexReference reference = definition.toReference();
@@ -455,6 +466,51 @@
public boolean isContextFreeForMethods() {
return true;
}
+
+ @Override
+ public boolean hasCodeRewritings() {
+ return false;
+ }
+ }
+
+ // This lens clears all code rewriting (lookup methods mimics identity lens behavior) but still
+ // relies on the previous lens for names (getRenamed/Original methods).
+ public static class ClearCodeRewritingGraphLens extends IdentityGraphLense {
+ private final GraphLense previous;
+
+ public ClearCodeRewritingGraphLens(GraphLense previous) {
+ this.previous = previous;
+ }
+
+ @Override
+ public DexType getOriginalType(DexType type) {
+ return previous.getOriginalType(type);
+ }
+
+ @Override
+ public DexField getOriginalFieldSignature(DexField field) {
+ return previous.getOriginalFieldSignature(field);
+ }
+
+ @Override
+ public DexMethod getOriginalMethodSignature(DexMethod method) {
+ return previous.getOriginalMethodSignature(method);
+ }
+
+ @Override
+ public DexField getRenamedFieldSignature(DexField originalField) {
+ return previous.getRenamedFieldSignature(originalField);
+ }
+
+ @Override
+ public DexMethod getRenamedMethodSignature(DexMethod originalMethod) {
+ return previous.getRenamedMethodSignature(originalMethod);
+ }
+
+ @Override
+ public DexType lookupType(DexType type) {
+ return previous.lookupType(type);
+ }
}
/**
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 dce9801..ed2dea0 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
@@ -671,6 +671,10 @@
// Assure that no more optimization feedback left after primary processing.
assert feedback.noUpdatesLeft();
appView.setAllCodeProcessed();
+ // All the code has been processed so the rewriting required by the lenses is done everywhere,
+ // we clear lens code rewriting so that the lens rewriter can be re-executed in phase 2 if new
+ // lenses with code rewriting are added.
+ graphLenseForIR = appView.clearCodeRewritings();
if (libraryMethodOverrideAnalysis != null) {
libraryMethodOverrideAnalysis.finish();
@@ -701,6 +705,11 @@
}
timing.end();
+ // All the code that should be impacted by the lenses inserted between phase 1 and phase 2
+ // have now been processed and rewritten, we clear code lens rewriting so that the class
+ // staticizer and phase 3 does not perform again the rewriting.
+ appView.clearCodeRewritings();
+
// TODO(b/112831361): Implement support for staticizeClasses in CF backend.
if (!options.isGeneratingClassFiles()) {
printPhase("Class staticizer post processing");
@@ -709,6 +718,10 @@
feedback.updateVisibleOptimizationInfo();
}
+ // The class staticizer lens shall not be applied through lens code rewriting or it breaks
+ // the lambda merger.
+ appView.clearCodeRewritings();
+
// Build a new application with jumbo string info.
Builder<?> builder = application.builder();
builder.setHighestSortingString(highestSortingString);
@@ -1112,18 +1125,18 @@
codeRewriter.simplifyDebugLocals(code);
}
+ // TODO(b/149364041): Remove !method.isProcessed().
+ if (lensCodeRewriter != null
+ && (!method.isProcessed() || appView.graphLense().hasCodeRewritings())) {
+ timing.begin("Lens rewrite");
+ lensCodeRewriter.rewrite(code, method);
+ timing.end();
+ }
+
if (method.isProcessed()) {
assert !appView.enableWholeProgramOptimizations()
|| !appView.appInfo().withLiveness().neverReprocess.contains(method.method);
} else {
- if (lensCodeRewriter != null) {
- timing.begin("Lens rewrite");
- lensCodeRewriter.rewrite(code, method);
- timing.end();
- } else {
- assert appView.graphLense().isIdentityLense();
- }
-
if (lambdaRewriter != null) {
timing.begin("Desugar lambdas");
lambdaRewriter.desugarLambdas(method, code);