Minor cleanup related to lambda merger
Change-Id: Ia3288155b047e6ded6a5186af7b835c6fef22910
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 1f7f7b5..be44297 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
@@ -252,7 +252,6 @@
options.enableDesugaring
? new BackportedMethodRewriter(appView, this)
: null;
- this.lambdaMerger = options.enableLambdaMerging ? new LambdaMerger(appView) : null;
this.covariantReturnTypeAnnotationTransformer =
options.processCovariantReturnTypeAnnotations
? new CovariantReturnTypeAnnotationTransformer(this, appView.dexItemFactory())
@@ -284,6 +283,8 @@
: null;
this.lensCodeRewriter = new LensCodeRewriter(appViewWithLiveness, lambdaRewriter);
this.inliner = new Inliner(appViewWithLiveness, mainDexClasses, lensCodeRewriter);
+ this.lambdaMerger =
+ options.enableLambdaMerging ? new LambdaMerger(appViewWithLiveness) : null;
this.outliner = new Outliner(appViewWithLiveness, this);
this.memberValuePropagation =
options.enableValuePropagation ? new MemberValuePropagation(appViewWithLiveness) : null;
@@ -307,6 +308,7 @@
this.fieldBitAccessAnalysis = null;
this.libraryMethodOverrideAnalysis = null;
this.inliner = null;
+ this.lambdaMerger = null;
this.outliner = null;
this.memberValuePropagation = null;
this.lensCodeRewriter = null;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/CodeProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/CodeProcessor.java
index 8d33db8..e7da094 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/CodeProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/CodeProcessor.java
@@ -26,7 +26,9 @@
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
+import com.android.tools.r8.ir.optimize.lambda.LambdaMerger.ApplyStrategy;
import com.android.tools.r8.kotlin.Kotlin;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.ListIterator;
import java.util.function.Function;
@@ -59,88 +61,75 @@
boolean isValidNewInstance(CodeProcessor context, NewInstance invoke);
- void patch(CodeProcessor context, NewInstance newInstance);
+ void patch(ApplyStrategy context, NewInstance newInstance);
- void patch(CodeProcessor context, InvokeMethod invoke);
+ void patch(ApplyStrategy context, InvokeMethod invoke);
- void patch(CodeProcessor context, InstancePut instancePut);
+ void patch(ApplyStrategy context, InstanceGet instanceGet);
- void patch(CodeProcessor context, InstanceGet instanceGet);
-
- void patch(CodeProcessor context, StaticPut staticPut);
-
- void patch(CodeProcessor context, StaticGet staticGet);
+ void patch(ApplyStrategy context, StaticGet staticGet);
}
// No-op strategy.
- static final Strategy NoOp = new Strategy() {
- @Override
- public LambdaGroup group() {
- return null;
- }
+ static final Strategy NoOp =
+ new Strategy() {
+ @Override
+ public LambdaGroup group() {
+ return null;
+ }
- @Override
- public boolean isValidInstanceFieldWrite(CodeProcessor context, DexField field) {
- return false;
- }
+ @Override
+ public boolean isValidInstanceFieldWrite(CodeProcessor context, DexField field) {
+ return false;
+ }
- @Override
- public boolean isValidInstanceFieldRead(CodeProcessor context, DexField field) {
- return false;
- }
+ @Override
+ public boolean isValidInstanceFieldRead(CodeProcessor context, DexField field) {
+ return false;
+ }
- @Override
- public boolean isValidStaticFieldWrite(CodeProcessor context, DexField field) {
- return false;
- }
+ @Override
+ public boolean isValidStaticFieldWrite(CodeProcessor context, DexField field) {
+ return false;
+ }
- @Override
- public boolean isValidStaticFieldRead(CodeProcessor context, DexField field) {
- return false;
- }
+ @Override
+ public boolean isValidStaticFieldRead(CodeProcessor context, DexField field) {
+ return false;
+ }
- @Override
- public boolean isValidInvoke(CodeProcessor context, InvokeMethod invoke) {
- return false;
- }
+ @Override
+ public boolean isValidInvoke(CodeProcessor context, InvokeMethod invoke) {
+ return false;
+ }
- @Override
- public boolean isValidNewInstance(CodeProcessor context, NewInstance invoke) {
- return false;
- }
+ @Override
+ public boolean isValidNewInstance(CodeProcessor context, NewInstance invoke) {
+ return false;
+ }
- @Override
- public void patch(CodeProcessor context, NewInstance newInstance) {
- throw new Unreachable();
- }
+ @Override
+ public void patch(ApplyStrategy context, NewInstance newInstance) {
+ throw new Unreachable();
+ }
- @Override
- public void patch(CodeProcessor context, InvokeMethod invoke) {
- throw new Unreachable();
- }
+ @Override
+ public void patch(ApplyStrategy context, InvokeMethod invoke) {
+ throw new Unreachable();
+ }
- @Override
- public void patch(CodeProcessor context, InstancePut instancePut) {
- throw new Unreachable();
- }
+ @Override
+ public void patch(ApplyStrategy context, InstanceGet instanceGet) {
+ throw new Unreachable();
+ }
- @Override
- public void patch(CodeProcessor context, InstanceGet instanceGet) {
- throw new Unreachable();
- }
+ @Override
+ public void patch(ApplyStrategy context, StaticGet staticGet) {
+ throw new Unreachable();
+ }
+ };
- @Override
- public void patch(CodeProcessor context, StaticPut staticPut) {
- throw new Unreachable();
- }
-
- @Override
- public void patch(CodeProcessor context, StaticGet staticGet) {
- throw new Unreachable();
- }
- };
-
- public final AppView<?> appView;
+ public final AppView<AppInfoWithLiveness> appView;
public final DexItemFactory factory;
public final Kotlin kotlin;
@@ -159,7 +148,7 @@
private InstructionListIterator instructions;
CodeProcessor(
- AppView<?> appView,
+ AppView<AppInfoWithLiveness> appView,
Function<DexType, Strategy> strategyProvider,
LambdaTypeVisitor lambdaChecker,
DexEncodedMethod method,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
index 87fc257..cd07285 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexApplication.Builder;
@@ -99,7 +98,7 @@
// should not be happening very frequently and we ignore possible overhead.
private final Set<DexEncodedMethod> methodsToReprocess = Sets.newIdentityHashSet();
- private final AppView<?> appView;
+ private final AppView<AppInfoWithLiveness> appView;
private final DexItemFactory factory;
private final Kotlin kotlin;
private final DiagnosticsHandler reporter;
@@ -111,7 +110,7 @@
// Lambda visitor throwing Unreachable on each lambdas it sees.
private final LambdaTypeVisitor lambdaChecker;
- public LambdaMerger(AppView<?> appView) {
+ public LambdaMerger(AppView<AppInfoWithLiveness> appView) {
this.appView = appView;
this.factory = appView.dexItemFactory();
this.kotlin = factory.kotlin;
@@ -212,14 +211,11 @@
analyzeReferencesInProgramClasses(app, executorService);
// Analyse more complex aspects of lambda classes including method code.
- assert appView.appInfo().hasSubtyping();
- AppInfoWithSubtyping appInfoWithSubtyping = appView.appInfo().withSubtyping();
- analyzeLambdaClassesStructure(appInfoWithSubtyping, executorService);
+ analyzeLambdaClassesStructure(executorService);
// Remove invalidated lambdas, compact groups to ensure
// sequential lambda ids, create group lambda classes.
- Map<LambdaGroup, DexProgramClass> lambdaGroupsClasses =
- finalizeLambdaGroups(appInfoWithSubtyping);
+ Map<LambdaGroup, DexProgramClass> lambdaGroupsClasses = finalizeLambdaGroups();
// Switch to APPLY strategy.
this.strategyFactory = ApplyStrategy::new;
@@ -258,12 +254,11 @@
ThreadUtils.awaitFutures(futures);
}
- private void analyzeLambdaClassesStructure(
- AppInfoWithSubtyping appInfo, ExecutorService service) throws ExecutionException {
+ private void analyzeLambdaClassesStructure(ExecutorService service) throws ExecutionException {
List<Future<?>> futures = new ArrayList<>();
for (LambdaGroup group : groups.values()) {
ThrowingConsumer<DexClass, LambdaStructureError> validator =
- group.lambdaClassValidator(kotlin, appInfo);
+ group.lambdaClassValidator(kotlin, appView.appInfo());
group.forEachLambda(info ->
futures.add(service.submit(() -> {
try {
@@ -282,7 +277,7 @@
ThreadUtils.awaitFutures(futures);
}
- private Map<LambdaGroup, DexProgramClass> finalizeLambdaGroups(AppInfoWithSubtyping appInfo) {
+ private Map<LambdaGroup, DexProgramClass> finalizeLambdaGroups() {
for (DexType lambda : invalidatedLambdas) {
LambdaGroup group = lambdas.get(lambda);
assert group != null;
@@ -303,7 +298,7 @@
result.put(group, lambdaGroupClass);
// We have to register this new class as a subtype of object.
- appInfo.registerNewType(lambdaGroupClass.type, lambdaGroupClass.superType);
+ appView.appInfo().registerNewType(lambdaGroupClass.type, lambdaGroupClass.superType);
}
return result;
}
@@ -423,7 +418,7 @@
}
}
- private final class ApplyStrategy extends CodeProcessor {
+ public final class ApplyStrategy extends CodeProcessor {
private ApplyStrategy(DexEncodedMethod method, IRCode code) {
super(
LambdaMerger.this.appView,
@@ -445,7 +440,9 @@
@Override
void process(Strategy strategy, InstancePut instancePut) {
- strategy.patch(this, instancePut);
+ // Instance put should only appear in lambda class instance constructor,
+ // we should never get here since we never rewrite them.
+ throw new Unreachable();
}
@Override
@@ -455,7 +452,9 @@
@Override
void process(Strategy strategy, StaticPut staticPut) {
- strategy.patch(this, staticPut);
+ // Static put should only appear in lambda class static initializer,
+ // we should never get here since we never rewrite them.
+ throw new Unreachable();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupCodeStrategy.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupCodeStrategy.java
index 9552267..2e82172 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupCodeStrategy.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupCodeStrategy.java
@@ -7,7 +7,6 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
-import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -17,19 +16,18 @@
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.InstanceGet;
-import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
-import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.optimize.lambda.CaptureSignature;
import com.android.tools.r8.ir.optimize.lambda.CodeProcessor;
import com.android.tools.r8.ir.optimize.lambda.CodeProcessor.Strategy;
import com.android.tools.r8.ir.optimize.lambda.LambdaGroup;
+import com.android.tools.r8.ir.optimize.lambda.LambdaMerger.ApplyStrategy;
import java.util.ArrayList;
import java.util.List;
@@ -114,7 +112,7 @@
}
@Override
- public void patch(CodeProcessor context, NewInstance newInstance) {
+ public void patch(ApplyStrategy context, NewInstance newInstance) {
NewInstance patchedNewInstance =
new NewInstance(
group.getGroupClassType(),
@@ -125,7 +123,7 @@
}
@Override
- public void patch(CodeProcessor context, InvokeMethod invoke) {
+ public void patch(ApplyStrategy context, InvokeMethod invoke) {
assert group.containsLambda(invoke.getInvokedMethod().holder);
if (isValidInitializerCall(context, invoke)) {
patchInitializer(context, invoke.asInvokeDirect());
@@ -140,14 +138,7 @@
}
@Override
- public void patch(CodeProcessor context, InstancePut instancePut) {
- // Instance put should only appear in lambda class instance constructor,
- // we should never get here since we never rewrite them.
- throw new Unreachable();
- }
-
- @Override
- public void patch(CodeProcessor context, InstanceGet instanceGet) {
+ public void patch(ApplyStrategy context, InstanceGet instanceGet) {
DexField field = instanceGet.getField();
DexType fieldType = field.type;
@@ -182,14 +173,7 @@
}
@Override
- public void patch(CodeProcessor context, StaticPut staticPut) {
- // Static put should only appear in lambda class static initializer,
- // we should never get here since we never rewrite them.
- throw new Unreachable();
- }
-
- @Override
- public void patch(CodeProcessor context, StaticGet staticGet) {
+ public void patch(ApplyStrategy context, StaticGet staticGet) {
context
.instructions()
.replaceCurrentInstruction(