Minor updates and misc. APIs for argument propagation
Change-Id: If3e9f7138dea0a1b3c5f5497203b156e3ff7e6a9
diff --git a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
index ac08e3f..fa003ea 100644
--- a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
@@ -63,6 +63,24 @@
});
}
+ public void forEachImmediateProgramSuperClass(
+ DexProgramClass clazz, Consumer<? super DexProgramClass> consumer) {
+ forEachImmediateProgramSuperClassMatching(clazz, alwaysTrue(), consumer);
+ }
+
+ public void forEachImmediateProgramSuperClassMatching(
+ DexProgramClass clazz,
+ Predicate<? super DexProgramClass> predicate,
+ Consumer<? super DexProgramClass> consumer) {
+ clazz.forEachImmediateSupertype(
+ supertype -> {
+ DexProgramClass superclass = asProgramClassOrNull(appView.definitionFor(supertype));
+ if (superclass != null && predicate.test(superclass)) {
+ consumer.accept(superclass);
+ }
+ });
+ }
+
public void forEachImmediateSubClass(
DexProgramClass clazz, Consumer<? super DexProgramClass> consumer) {
forEachImmediateSubClassMatching(clazz, alwaysTrue(), consumer);
diff --git a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
index 9f33913..f1e8ae1 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
@@ -98,6 +98,10 @@
return null;
}
+ public ProgramMethod getResolvedProgramMethod() {
+ return null;
+ }
+
@Override
public DexClassAndMethod getResolutionPair() {
return null;
@@ -192,6 +196,7 @@
return resolvedMethod;
}
+ @Override
public ProgramMethod getResolvedProgramMethod() {
return resolvedHolder.isProgramClass()
? new ProgramMethod(resolvedHolder.asProgramClass(), resolvedMethod)
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
index 083c27f..c171e7d 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeElement.java
@@ -140,6 +140,11 @@
}
@Override
+ public ClassTypeElement joinNullability(Nullability nullability) {
+ return getOrCreateVariant(nullability().join(nullability));
+ }
+
+ @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(nullability);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/Nullability.java b/src/main/java/com/android/tools/r8/ir/analysis/type/Nullability.java
index 26b9030..e45ac9a 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/Nullability.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/Nullability.java
@@ -29,6 +29,10 @@
private Nullability() {}
+ public boolean isBottom() {
+ return this == BOTTOM;
+ }
+
public boolean isDefinitelyNull() {
return this == DEFINITELY_NULL;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ReferenceTypeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ReferenceTypeElement.java
index c150cfd..5a82ac4 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ReferenceTypeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ReferenceTypeElement.java
@@ -78,6 +78,10 @@
return getOrCreateVariant(nullability.meet(Nullability.definitelyNotNull()));
}
+ public TypeElement asDefinitelyNull() {
+ return getOrCreateVariant(Nullability.definitelyNull());
+ }
+
public TypeElement asDefinitelyNotNull() {
return getOrCreateVariant(Nullability.definitelyNotNull());
}
@@ -86,6 +90,10 @@
return getOrCreateVariant(Nullability.maybeNull());
}
+ public ReferenceTypeElement joinNullability(Nullability nullability) {
+ return getOrCreateVariant(nullability().join(nullability));
+ }
+
@Override
public boolean isReferenceType() {
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Assume.java b/src/main/java/com/android/tools/r8/ir/code/Assume.java
index 3a51eec..f25c73b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Assume.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Assume.java
@@ -311,6 +311,8 @@
}
public boolean verifyCorrectnessOfValues(Value dest, Value src, AppView<?> appView) {
+ assert !dynamicUpperBoundType.isBottom();
+ assert !dynamicUpperBoundType.isTop();
assert dynamicUpperBoundType.lessThanOrEqualUpToNullability(src.getType(), appView);
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index ce8efd1..643fdcb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -1156,7 +1156,7 @@
DexType type = definition.asNewInstance().clazz;
DexClass clazz = appView.definitionFor(type);
if (clazz != null && !clazz.isInterface()) {
- return ClassTypeElement.create(type, definitelyNotNull(), appView);
+ return TypeElement.fromDexType(type, definitelyNotNull(), appView).asClassType();
}
return null;
}
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 c2572cf..8595ecd 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
@@ -409,11 +409,11 @@
reportNestDesugarDependencies();
clearNestAttributes();
- application = commitPendingSyntheticItems(appView, application);
+ application = commitPendingSyntheticItemsD8(appView, application);
postProcessingDesugaringForD8(methodProcessor, executor);
- application = commitPendingSyntheticItems(appView, application);
+ application = commitPendingSyntheticItemsD8(appView, application);
// Build a new application with jumbo string info,
Builder<?> builder = application.builder().setHighestSortingString(highestSortingString);
@@ -432,7 +432,7 @@
appView.appInfo().getMainDexInfo()));
}
- private DexApplication commitPendingSyntheticItems(
+ private DexApplication commitPendingSyntheticItemsD8(
AppView<AppInfo> appView, DexApplication application) {
if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
appView.setAppInfo(
@@ -444,6 +444,15 @@
return application;
}
+ private static void commitPendingSyntheticItemsR8(AppView<AppInfoWithLiveness> appView) {
+ if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
+ appView.setAppInfo(
+ appView
+ .appInfo()
+ .rebuildWithLiveness(appView.getSyntheticItems().commit(appView.appInfo().app())));
+ }
+ }
+
public void l8ClassSynthesis(
ExecutorService executorService,
CfL8ClassSynthesizerEventConsumer l8ClassSynthesizerEventConsumer)
@@ -729,6 +738,9 @@
// lenses with code rewriting are added.
appView.clearCodeRewritings();
+ // Commit synthetics from the primary optimization pass.
+ commitPendingSyntheticItemsR8(appView);
+
// Analyze the data collected by the argument propagator, use the analysis result to update
// the parameter optimization infos, and rewrite the application.
appView.withArgumentPropagator(
@@ -800,12 +812,8 @@
// Commit synthetics before creating a builder (otherwise the builder will not include the
// synthetics.)
- if (appView.getSyntheticItems().hasPendingSyntheticClasses()) {
- appView.setAppInfo(
- appView
- .appInfo()
- .rebuildWithLiveness(appView.getSyntheticItems().commit(appView.appInfo().app())));
- }
+ commitPendingSyntheticItemsR8(appView);
+
// Build a new application with jumbo string info.
Builder<?> builder = appView.appInfo().app().builder();
builder.setHighestSortingString(highestSortingString);
@@ -1541,7 +1549,7 @@
printMethod(code, "IR after idempotent function call canonicalization (SSA)", previous);
// Insert code to log arguments if requested.
- if (options.methodMatchesLogArgumentsFilter(method)) {
+ if (options.methodMatchesLogArgumentsFilter(method) && !method.isProcessed()) {
codeRewriter.logArgumentTypes(method, code);
assert code.isConsistentSSA();
}
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 13455ba..dbec312 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
@@ -80,10 +80,7 @@
WorkList<DexProgramClass> worklist = WorkList.newIdentityWorkList(clazz);
while (worklist.hasNext()) {
DexProgramClass current = worklist.next();
- immediateSubtypingInfo.forEachImmediateSuperClassMatching(
- current,
- (supertype, superclass) -> superclass != null && superclass.isProgramClass(),
- (supertype, superclass) -> worklist.addIfNotSeen(superclass.asProgramClass()));
+ immediateSubtypingInfo.forEachImmediateProgramSuperClass(current, worklist::addIfNotSeen);
worklist.addIfNotSeen(immediateSubtypingInfo.getSubclasses(current));
}
return worklist.getSeenSet();
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorUnoptimizableMethods.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorUnoptimizableMethods.java
index 9a478bd..36dae85 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorUnoptimizableMethods.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorUnoptimizableMethods.java
@@ -137,12 +137,11 @@
unoptimizableInterfaceMethods.computeIfAbsent(clazz, ignoreKey(Sets::newIdentityHashSet));
// Add the unoptimizable interface methods from the parent interfaces.
- immediateSubtypingInfo.forEachImmediateSuperClassMatching(
+ immediateSubtypingInfo.forEachImmediateProgramSuperClass(
clazz,
- (supertype, superclass) -> superclass != null && superclass.isProgramClass(),
- (supertype, superclass) ->
+ superclass ->
unoptimizableInterfaceMethodsForClass.addAll(
- unoptimizableInterfaceMethods.get(superclass.asProgramClass())));
+ unoptimizableInterfaceMethods.get(superclass)));
// Propagate the unoptimizable interface methods of this interface to all immediate
// (non-interface) subclasses.
@@ -221,12 +220,9 @@
unoptimizableMethods.computeIfAbsent(clazz, ignoreKey(DexMethodSignatureSet::create));
// Add the unoptimizable methods from the parent classes.
- immediateSubtypingInfo.forEachImmediateSuperClassMatching(
+ immediateSubtypingInfo.forEachImmediateProgramSuperClass(
clazz,
- (supertype, superclass) -> superclass != null && superclass.isProgramClass(),
- (supertype, superclass) ->
- unoptimizableMethodsForClass.addAll(
- unoptimizableMethods.get(superclass.asProgramClass())));
+ superclass -> unoptimizableMethodsForClass.addAll(unoptimizableMethods.get(superclass)));
// Disable argument propagation for the unoptimizable methods of this class.
clazz.forEachProgramVirtualMethod(
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
index 99a0bac..69cbb7b 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InterfaceMethodArgumentPropagator.java
@@ -82,12 +82,11 @@
DexProgramClass interfaceDefinition) {
// Join the state for all parent interfaces into a fresh state created for this interface.
MethodStateCollectionBySignature interfaceState = MethodStateCollectionBySignature.create();
- immediateSubtypingInfo.forEachImmediateSuperClassMatching(
+ immediateSubtypingInfo.forEachImmediateProgramSuperClass(
interfaceDefinition,
- (supertype, superclass) -> superclass != null && superclass.isProgramClass(),
- (supertype, superclass) -> {
+ superclass -> {
MethodStateCollectionBySignature implementedInterfaceState =
- methodStatesToPropagate.get(superclass.asProgramClass());
+ methodStatesToPropagate.get(superclass);
assert implementedInterfaceState != null;
interfaceState.addMethodStates(appView, implementedInterfaceState);
});
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
index 14c58f8..771a718 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/VirtualDispatchMethodArgumentPropagator.java
@@ -46,10 +46,8 @@
PropagationState(DexProgramClass clazz) {
// Join the argument information from each of the super types.
- immediateSubtypingInfo.forEachImmediateSuperClassMatching(
- clazz,
- (supertype, superclass) -> superclass != null && superclass.isProgramClass(),
- (supertype, superclass) -> addParentState(clazz, superclass.asProgramClass()));
+ immediateSubtypingInfo.forEachImmediateProgramSuperClass(
+ clazz, superclass -> addParentState(clazz, superclass));
}
// TODO(b/190154391): This currently copies the state of the superclass into its immediate