Simplify class inliner constraint before adding to optimization info
Fixes: 181746071
Change-Id: I3e18899e8c31174128b5cbeed620022dafa1abe3
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
index 677518c..a0ce6b0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
@@ -31,16 +31,13 @@
if (result == null) {
return ClassInlinerMethodConstraint.alwaysFalse();
}
-
- // TODO(b/181746071): This always returns a non-empty result, that should be transformed into
- // bottom or top.
- ParameterUsages usages = result.join();
+ ParameterUsages usages = result.join().externalize();
if (usages.isBottom()) {
return ClassInlinerMethodConstraint.alwaysTrue();
}
if (usages.isTop()) {
return ClassInlinerMethodConstraint.alwaysFalse();
}
- return new ConditionalClassInlinerMethodConstraint(usages.externalize());
+ return new ConditionalClassInlinerMethodConstraint(usages);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsagePerContext.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsagePerContext.java
index e57fc5c..9460e7e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsagePerContext.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsagePerContext.java
@@ -55,13 +55,34 @@
@Override
ParameterUsagePerContext externalize() {
- return rebuild((context, usage) -> usage.externalize());
+ boolean allBottom = true;
+ boolean allTop = true;
+ for (ParameterUsage usage : backing.values()) {
+ if (!usage.isBottom()) {
+ allBottom = false;
+ }
+ if (!usage.isTop()) {
+ allTop = false;
+ }
+ }
+ if (allBottom) {
+ return bottom();
+ }
+ if (allTop) {
+ return top();
+ }
+ // Remove mappings to top. These mappings represent unknown information, which there is no point
+ // in storing. After the removal of these mappings, the result should still be non-empty.
+ ParameterUsagePerContext rebuilt =
+ rebuild((context, usage) -> usage.isTop() ? null : usage.externalize());
+ assert !rebuilt.isBottom();
+ assert !rebuilt.isTop();
+ return rebuilt;
}
@Override
public ParameterUsage get(AnalysisContext context) {
- assert backing.containsKey(context);
- return backing.get(context);
+ return backing.getOrDefault(context, ParameterUsage.top());
}
@Override
@@ -72,20 +93,22 @@
AnalysisContext context = entry.getKey();
ParameterUsage usage = entry.getValue();
ParameterUsage newUsage = transformation.apply(context, usage);
- if (newUsage != usage) {
- if (builder == null) {
- builder = ImmutableMap.builder();
- for (Map.Entry<AnalysisContext, ParameterUsage> previousEntry : backing.entrySet()) {
- AnalysisContext previousContext = previousEntry.getKey();
- if (previousContext == context) {
- break;
+ if (newUsage != null) {
+ if (newUsage != usage) {
+ if (builder == null) {
+ builder = ImmutableMap.builder();
+ for (Map.Entry<AnalysisContext, ParameterUsage> previousEntry : backing.entrySet()) {
+ AnalysisContext previousContext = previousEntry.getKey();
+ if (previousContext == context) {
+ break;
+ }
+ builder.put(previousContext, previousEntry.getValue());
}
- builder.put(previousContext, previousEntry.getValue());
}
+ builder.put(context, newUsage);
+ } else if (builder != null) {
+ builder.put(context, newUsage);
}
- builder.put(context, newUsage);
- } else if (builder != null) {
- builder.put(context, newUsage);
}
}
return builder != null ? create(builder.build()) : this;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsages.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsages.java
index 2fb4a19..8878976 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsages.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/NonEmptyParameterUsages.java
@@ -83,8 +83,26 @@
}
@Override
- NonEmptyParameterUsages externalize() {
- return rebuildParameters((parameter, usagePerContext) -> usagePerContext.externalize());
+ ParameterUsages externalize() {
+ NonEmptyParameterUsages rebuilt =
+ rebuildParameters((parameter, usagePerContext) -> usagePerContext.externalize());
+ boolean allBottom = true;
+ boolean allTop = true;
+ for (ParameterUsagePerContext usagePerContext : rebuilt.backing.values()) {
+ if (!usagePerContext.isBottom()) {
+ allBottom = false;
+ }
+ if (!usagePerContext.isTop()) {
+ allTop = false;
+ }
+ }
+ if (allBottom) {
+ return bottom();
+ }
+ if (allTop) {
+ return top();
+ }
+ return rebuilt;
}
@Override
@@ -101,9 +119,7 @@
@Override
public ParameterUsagePerContext get(int parameter) {
- assert backing.containsKey(parameter);
- ParameterUsagePerContext value = backing.get(parameter);
- return value != null ? value : ParameterUsagePerContext.bottom();
+ return backing.getOrDefault(parameter, ParameterUsagePerContext.top());
}
NonEmptyParameterUsages abandonClassInliningInCurrentContexts(Value value) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ParameterUsages.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ParameterUsages.java
index 6b4cffb..0cb3a5e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ParameterUsages.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ParameterUsages.java
@@ -18,8 +18,9 @@
}
/**
- * This converts instances inside this {@link ParameterUsages} instance that are not suitable for
- * being stored in optimization info into instances that can be stored in the optimization info.
+ * Prepares this instance for being stored in the optimization info. This converts instances
+ * inside this {@link ParameterUsages} instance that are not suitable for being stored in
+ * optimization info into instances that can be stored in the optimization info.
*
* <p>For example, converts instances of {@link InternalNonEmptyParameterUsage} to {@link
* NonEmptyParameterUsage}. This is needed because {@link InternalNonEmptyParameterUsage} is not