Also remove dead phis during trivial phi removal
This fixes a bug in the class inliner that manifests when the inliner creates a phi for the return value, which ends up not having any users.
Change-Id: Id9b0a7ec910b017c42eccae16fe7e18078e81690
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
index 72ac893..0bb8f21 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/constant/SparseConditionalConstantPropagation.java
@@ -117,7 +117,7 @@
block.deduplicatePhis();
}
- code.removeAllTrivialPhis();
+ code.removeAllDeadAndTrivialPhis();
}
private LatticeElement getLatticeElement(Value value) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 952bd5c..883d49f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -1126,27 +1126,32 @@
return true;
}
- public boolean removeAllTrivialPhis() {
- return removeAllTrivialPhis(null, null);
+ public boolean removeAllDeadAndTrivialPhis() {
+ return removeAllDeadAndTrivialPhis(null, null);
}
- public boolean removeAllTrivialPhis(IRBuilder builder) {
- return removeAllTrivialPhis(builder, null);
+ public boolean removeAllDeadAndTrivialPhis(IRBuilder builder) {
+ return removeAllDeadAndTrivialPhis(builder, null);
}
- public boolean removeAllTrivialPhis(Set<Value> affectedValues) {
- return removeAllTrivialPhis(null, affectedValues);
+ public boolean removeAllDeadAndTrivialPhis(Set<Value> affectedValues) {
+ return removeAllDeadAndTrivialPhis(null, affectedValues);
}
- public boolean removeAllTrivialPhis(IRBuilder builder, Set<Value> affectedValues) {
- boolean anyTrivialPhisRemoved = false;
+ public boolean removeAllDeadAndTrivialPhis(IRBuilder builder, Set<Value> affectedValues) {
+ boolean anyPhisRemoved = false;
for (BasicBlock block : blocks) {
List<Phi> phis = new ArrayList<>(block.getPhis());
for (Phi phi : phis) {
- anyTrivialPhisRemoved |= phi.removeTrivialPhi(builder, affectedValues);
+ if (phi.hasAnyUsers()) {
+ anyPhisRemoved |= phi.removeTrivialPhi(builder, affectedValues);
+ } else {
+ phi.removeDeadPhi();
+ anyPhisRemoved = true;
+ }
}
}
- return anyTrivialPhisRemoved;
+ return anyPhisRemoved;
}
public int reserveMarkingColor() {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 9598e95..e87f619 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -688,7 +688,7 @@
block.deduplicatePhis();
}
- ir.removeAllTrivialPhis(this);
+ ir.removeAllDeadAndTrivialPhis(this);
ir.removeUnreachableBlocks();
// Compute precise types for all values.
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
index 41d1363..20ab05c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/StringSwitchConverter.java
@@ -113,7 +113,7 @@
}
}
if (changed) {
- code.removeAllTrivialPhis();
+ code.removeAllDeadAndTrivialPhis();
code.removeUnreachableBlocks();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 60813ab..45befcf 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -208,7 +208,7 @@
// Therefore, Assume elimination may result in a trivial phi:
// z <- phi(x, x)
if (needToCheckTrivialPhis) {
- code.removeAllTrivialPhis(valuesThatRequireWidening);
+ code.removeAllDeadAndTrivialPhis(valuesThatRequireWidening);
}
if (!valuesThatRequireWidening.isEmpty()) {
@@ -1221,10 +1221,10 @@
assumeDynamicTypeRemover.removeMarkedInstructions(blocksToBeRemoved).finish();
if (!blocksToBeRemoved.isEmpty()) {
code.removeBlocks(blocksToBeRemoved);
- code.removeAllTrivialPhis(affectedValues);
+ code.removeAllDeadAndTrivialPhis(affectedValues);
assert code.getUnreachableBlocks().isEmpty();
} else if (mayHaveRemovedTrivialPhi || assumeDynamicTypeRemover.mayHaveIntroducedTrivialPhi()) {
- code.removeAllTrivialPhis(affectedValues);
+ code.removeAllDeadAndTrivialPhis(affectedValues);
}
if (!affectedValues.isEmpty()) {
new TypeAnalysis(appView).narrowing(affectedValues);
@@ -1299,7 +1299,7 @@
// Removing check-cast may result in a trivial phi:
// v3 <- phi(v1, v1)
if (needToRemoveTrivialPhis) {
- code.removeAllTrivialPhis(affectedValues);
+ code.removeAllDeadAndTrivialPhis(affectedValues);
if (!affectedValues.isEmpty()) {
typeAnalysis.narrowing(affectedValues);
}
@@ -2593,7 +2593,7 @@
}
if (changed) {
- code.removeAllTrivialPhis();
+ code.removeAllDeadAndTrivialPhis();
}
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
index 5160e6c..2dff525 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
@@ -257,7 +257,7 @@
shouldSimplifyIfs |= newConst.outValue().hasUserThatMatches(Instruction::isIf);
} while (iterator.hasNext());
- shouldSimplifyIfs |= code.removeAllTrivialPhis();
+ shouldSimplifyIfs |= code.removeAllDeadAndTrivialPhis();
if (shouldSimplifyIfs) {
codeRewriter.simplifyIf(code);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
index 9cbc694..ebf6e57 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
@@ -248,7 +248,7 @@
}
}
- code.removeAllTrivialPhis();
+ code.removeAllDeadAndTrivialPhis();
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index c9bf058..c9bc764 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -1058,7 +1058,7 @@
assumeDynamicTypeRemover.finish();
classInitializationAnalysis.finish();
code.removeBlocks(blocksToRemove);
- code.removeAllTrivialPhis();
+ code.removeAllDeadAndTrivialPhis();
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index 96f6bcb..8e0858a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -393,7 +393,7 @@
}
assumeDynamicTypeRemover.removeMarkedInstructions(blocksToBeRemoved).finish();
code.removeBlocks(blocksToBeRemoved);
- code.removeAllTrivialPhis(valuesToNarrow);
+ code.removeAllDeadAndTrivialPhis(valuesToNarrow);
code.removeUnreachableBlocks();
if (!valuesToNarrow.isEmpty()) {
new TypeAnalysis(appView).narrowing(valuesToNarrow);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index 6707fe1..9b443bc 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -270,7 +270,7 @@
// Restore normality.
Set<Value> affectedValues = Sets.newIdentityHashSet();
- code.removeAllTrivialPhis(affectedValues);
+ code.removeAllDeadAndTrivialPhis(affectedValues);
if (!affectedValues.isEmpty()) {
new TypeAnalysis(appView).narrowing(affectedValues);
}
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1419TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1419TreeShakeJarVerificationTest.java
index 48acfdb..dd47f7f 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1419TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1419TreeShakeJarVerificationTest.java
@@ -5,6 +5,7 @@
import static com.android.tools.r8.ToolHelper.isLocalDevelopment;
import static com.android.tools.r8.ToolHelper.shouldRunSlowTests;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -46,8 +47,12 @@
R8TestCompileResult compileResult =
testForR8(parameters.getBackend())
.addKeepRuleFiles(getKeepRuleFiles())
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
- .compile();
+ .compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(containsString("Ignoring option:"));
if (ToolHelper.isLocalDevelopment()) {
DexItemFactory dexItemFactory = new DexItemFactory();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/UnusedReturnValueTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/UnusedReturnValueTest.java
index c46ae1b..2a2bb9e 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/UnusedReturnValueTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/UnusedReturnValueTest.java
@@ -31,8 +31,6 @@
testForR8(parameters.getBackend())
.addInnerClasses(UnusedReturnValueTest.class)
.addKeepMainRule(TestClass.class)
- // TODO(christofferqa): Fix class inliner.
- .allowClassInlinerGracefulExit()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.compile()