Fix overcounting in outliner due to revisiting same instructions
Change-Id: I2073b0a7df9f79b20cf97cab1b3c55376063d154
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
index 7ef7216..4093846 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
@@ -795,6 +795,9 @@
while (index < currentCandidateInstructions.size()) {
processInstruction(currentCandidateInstructions.get(index));
}
+ if (actualInstructions > 0) {
+ candidate(start, index);
+ }
}
// Get int in-values for an instruction. For commutative binary operations using the current
@@ -1448,12 +1451,17 @@
boolean sawLinearFlowWithCatchHandlers = false;
while (instructionIterator.hasNext()) {
Instruction instruction = instructionIterator.next();
- // Disregard linear flow when there are catch handlers
- if (instruction.getBlock() != block
- && (block.hasCatchHandlers() || instruction.getBlock().hasCatchHandlers())) {
- lastSeenBlock = instruction.getBlock();
- sawLinearFlowWithCatchHandlers = true;
- break;
+ if (instruction.getBlock() != block) {
+ // Disregard linear flow when there are catch handlers
+ if (block.hasCatchHandlers() || instruction.getBlock().hasCatchHandlers()) {
+ lastSeenBlock = instruction.getBlock();
+ sawLinearFlowWithCatchHandlers = true;
+ break;
+ }
+ // Disregard revisiting already processed blocks.
+ if (seenBlocks.contains(instruction.getBlock())) {
+ break;
+ }
}
builder.add(instruction);
counter++;
@@ -1464,6 +1472,7 @@
}
lastSeenBlock = instruction.getBlock();
}
+ // Add all seen blocks including trivial goto blocks skipped by the linear iterator.
seenBlocks.addAll(instructionIterator.getSeenBlocks());
if (sawLinearFlowWithCatchHandlers) {
assert lastSeenBlock != block;