Version 1.0.2.
Merge: Limit the amount of dominator tree computations.
CL: https://r8-review.googlesource.com/c/r8/+/14901
Merge: Fix unlinking of unreachable blocks.
CL: https://r8-review.googlesource.com/c/r8/+/14880
R=sgjesse@google.com
Change-Id: Idb5bcd5a4ea748f1bd23a5cdddf45f8afd56506d
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 5344a61..74b730d 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "v1.0.1";
+ public static final String LABEL = "v1.0.2";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index 1e076dd..d6fcd3c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -30,7 +30,6 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -553,34 +552,28 @@
assert successors.contains(successor);
assert successor.predecessors.contains(this);
List<BasicBlock> removedBlocks = new ArrayList<>();
- TreeSet<Pair> worklist = new TreeSet<>();
- worklist.add(new Pair(this, successor));
- while (!worklist.isEmpty()) {
- Pair pair = worklist.pollFirst();
- BasicBlock pred = pair.first;
- BasicBlock succ = pair.second;
- assert pred.successors.contains(succ);
- assert succ.predecessors.contains(pred);
- int size = pred.successors.size();
- pred.removeSuccessor(succ);
- assert size == pred.successors.size() + 1;
- size = succ.predecessors.size();
- succ.removePredecessor(pred);
- assert size == succ.predecessors.size() + 1;
- // A predecessor has been removed. If all remaining predecessors are dominated by this block
- // schedule it for removal, as it is no longer reachable.
- if (allPredecessorsDominated(succ, dominator)) {
- removedBlocks.add(succ);
- for (BasicBlock block : succ.successors) {
- worklist.add(new Pair(succ, block));
+ for (BasicBlock dominated : dominator.dominatedBlocks(successor)) {
+ removedBlocks.add(dominated);
+ for (BasicBlock block : dominated.successors) {
+ block.removePredecessor(dominated);
+ }
+ dominated.successors.clear();
+ for (BasicBlock block : dominated.predecessors) {
+ block.removeSuccessor(dominated);
+ }
+ dominated.predecessors.clear();
+ for (Phi phi : dominated.getPhis()) {
+ for (Value operand : phi.getOperands()) {
+ operand.removePhiUser(phi);
}
- for (Instruction instruction : succ.getInstructions()) {
- for (Value value : instruction.inValues) {
- value.removeUser(instruction);
- }
- for (Value value : instruction.getDebugValues()) {
- value.removeDebugUser(instruction);
- }
+ }
+ dominated.getPhis().clear();
+ for (Instruction instruction : dominated.getInstructions()) {
+ for (Value value : instruction.inValues) {
+ value.removeUser(instruction);
+ }
+ for (Value value : instruction.getDebugValues()) {
+ value.removeDebugUser(instruction);
}
}
}
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 eeb843c..0b3b021 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
@@ -1700,8 +1700,6 @@
}
public void simplifyIf(IRCode code) {
- Supplier<DominatorTree> dominatorTreeMemoization = Suppliers
- .memoize(() -> new DominatorTree(code));
int color = code.reserveMarkingColor();
for (BasicBlock block : code.blocks) {
if (block.isMarked(color)) {
@@ -1711,7 +1709,7 @@
// First rewrite zero comparison.
rewriteIfWithConstZero(block);
- if (simplifyKnownBooleanCondition(code, dominatorTreeMemoization, block, color)) {
+ if (simplifyKnownBooleanCondition(code, block, color)) {
continue;
}
@@ -1757,7 +1755,7 @@
BasicBlock target = theIf.targetFromCondition(cond);
BasicBlock deadTarget =
target == theIf.getTrueTarget() ? theIf.fallthroughBlock() : theIf.getTrueTarget();
- rewriteIfToGoto(dominatorTreeMemoization, block, theIf, target, deadTarget, color);
+ rewriteIfToGoto(code, block, theIf, target, deadTarget, color);
}
}
code.removeMarkedBlocks(color);
@@ -1796,8 +1794,7 @@
* which can be replaced by a fallthrough and the phi value can be replaced
* by an xor instruction which is smaller.
*/
- private boolean simplifyKnownBooleanCondition(IRCode code,
- Supplier<DominatorTree> dominatorTreeMemoization, BasicBlock block, int color) {
+ private boolean simplifyKnownBooleanCondition(IRCode code, BasicBlock block, int color) {
If theIf = block.exit().asIf();
Value testValue = theIf.inValues().get(0);
if (theIf.isZeroTest() && testValue.knownToBeBoolean()) {
@@ -1859,7 +1856,7 @@
// If all phis were removed, there is no need for the diamond shape anymore
// and it can be rewritten to a goto to one of the branches.
if (deadPhis == targetBlock.getPhis().size()) {
- rewriteIfToGoto(dominatorTreeMemoization, block, theIf, trueBlock, falseBlock, color);
+ rewriteIfToGoto(code, block, theIf, trueBlock, falseBlock, color);
return true;
}
}
@@ -1901,9 +1898,10 @@
return false;
}
- private void rewriteIfToGoto(Supplier<DominatorTree> dominatorTreeMemoization, BasicBlock block,
+ private void rewriteIfToGoto(IRCode code, BasicBlock block,
If theIf, BasicBlock target, BasicBlock deadTarget, int color) {
- List<BasicBlock> removedBlocks = block.unlink(deadTarget, dominatorTreeMemoization.get());
+ DominatorTree dominatorTree = new DominatorTree(code);
+ List<BasicBlock> removedBlocks = block.unlink(deadTarget, dominatorTree);
for (BasicBlock removedBlock : removedBlocks) {
if (!removedBlock.isMarked(color)) {
removedBlock.mark(color);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
index 88f9e63..5144704 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
@@ -12,19 +12,15 @@
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.utils.InternalOptions;
-import com.google.common.base.Suppliers;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
-import java.util.function.Supplier;
public class DeadCodeRemover {
public static void removeDeadCode(
IRCode code, CodeRewriter codeRewriter, InternalOptions options) {
Queue<BasicBlock> worklist = new LinkedList<>();
- Supplier<DominatorTree> dominatorTreeMemoization = Suppliers
- .memoize(() -> new DominatorTree(code));
int color = code.reserveMarkingColor();
worklist.addAll(code.blocks);
for (BasicBlock block = worklist.poll(); block != null; block = worklist.poll()) {
@@ -34,7 +30,7 @@
}
removeDeadInstructions(worklist, code, block, options, color);
removeDeadPhis(worklist, block, options, color);
- removeUnneededCatchHandlers(worklist, block, dominatorTreeMemoization, color);
+ removeUnneededCatchHandlers(worklist, block, code, color);
}
code.removeMarkedBlocks(color);
code.returnMarkingColor(color);
@@ -113,11 +109,12 @@
}
private static void removeUnneededCatchHandlers(Queue<BasicBlock> worklist, BasicBlock block,
- Supplier<DominatorTree> dominatorTreeMemoization, int color) {
+ IRCode code, int color) {
if (block.hasCatchHandlers() && !block.canThrow()) {
CatchHandlers<BasicBlock> handlers = block.getCatchHandlers();
for (BasicBlock target : handlers.getUniqueTargets()) {
- for (BasicBlock unlinked : block.unlink(target, dominatorTreeMemoization.get())) {
+ DominatorTree dominatorTree = new DominatorTree(code);
+ for (BasicBlock unlinked : block.unlink(target, dominatorTree)) {
if (!unlinked.isMarked(color)) {
Iterator<Instruction> iterator = unlinked.iterator();
while (iterator.hasNext()) {
diff --git a/src/test/java/com/android/tools/r8/jasmin/Regress72269635.java b/src/test/java/com/android/tools/r8/jasmin/Regress72269635.java
new file mode 100644
index 0000000..e92b8a9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/jasmin/Regress72269635.java
@@ -0,0 +1,63 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.jasmin;
+
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.jasmin.JasminBuilder.ClassFileVersion;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.utils.AndroidApp;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+public class Regress72269635 extends JasminTestBase {
+
+ @Test
+ public void testDeadBlocksRemoved() throws Exception {
+ JasminBuilder builder = new JasminBuilder(ClassFileVersion.JDK_1_4);
+ JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
+
+ clazz.addStaticMethod("test", ImmutableList.of("IIII"), "J",
+ ".limit stack 3",
+ ".limit locals 5",
+ "L0:",
+ " iconst_2",
+ " ifge L0",
+ "L48:",
+ " iload 3",
+ " ifle L48",
+ " goto L209",
+ " aconst_null",
+ " athrow",
+ "L209:",
+ " aconst_null",
+ " iconst_2",
+ " newarray float",
+ " if_acmpne L250",
+ "L240:",
+ " iload 3",
+ " pop",
+ "L250:",
+ " iload 3",
+ " ifgt L240",
+ " iload 3",
+ " istore 0",
+ " goto L357",
+ "L318:",
+ " iinc 0 1",
+ "L351:",
+ " iinc 0 1",
+ " goto L351",
+ "L357:",
+ " iinc 0 1",
+ "L415:",
+ " iinc 0 1",
+ " goto L415"
+ );
+
+ // Just compiling this code used to throw exceptions because not all dead blocks
+ // were removed.
+ AndroidApp originalApplication = builder.build();
+ ToolHelper.runD8(originalApplication);
+ }
+}