Insert Identity lens after IR processing
- Allows to execute twice the lensCodeRewriter
Bug: 147860220
Change-Id: Id08602ed524d81b5f17fce5ebda2664012720901
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 9f7b4cf..32b996a 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -149,6 +149,10 @@
allCodeProcessed = true;
}
+ public GraphLense clearLensCodeRewriting() {
+ 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..6f8d92e 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,46 @@
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);
+ }
}
/**
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 6edeab0..08086ff 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
@@ -663,6 +663,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.clearLensCodeRewriting();
if (libraryMethodOverrideAnalysis != null) {
libraryMethodOverrideAnalysis.finish();
@@ -693,6 +697,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.clearLensCodeRewriting();
+
// TODO(b/112831361): Implement support for staticizeClasses in CF backend.
if (!options.isGeneratingClassFiles()) {
printPhase("Class staticizer post processing");
@@ -1104,18 +1113,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);