Improve performance of MoveLoadUpPeephole by not resetting position
Bug: 138922694
Change-Id: I830bd4a25c4bf862162a1ca00645aec56b7e3bb9
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index db2d7bb..8907df8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -142,7 +142,7 @@
boolean reachedFixpoint = false;
phiOptimizations.optimize(code);
while (!reachedFixpoint) {
- BasicBlockMuncher.optimize(code);
+ BasicBlockMuncher.optimize(code, appView.options());
reachedFixpoint = !phiOptimizations.optimize(code);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/peepholes/BasicBlockMuncher.java b/src/main/java/com/android/tools/r8/ir/optimize/peepholes/BasicBlockMuncher.java
index b2db648..8eaf454 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/peepholes/BasicBlockMuncher.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/peepholes/BasicBlockMuncher.java
@@ -4,10 +4,14 @@
package com.android.tools.r8.ir.optimize.peepholes;
+import static com.android.tools.r8.utils.InternalOptions.TestingOptions.NO_LIMIT;
+
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.LinearFlowInstructionListIterator;
+import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.ListIterator;
@@ -29,13 +33,15 @@
new StoreLoadToDupStorePeephole());
}
- public static void optimize(IRCode code) {
- runPeepholes(code, nonDestructivePeepholes());
- runPeepholes(code, destructivePeepholes());
+ public static void optimize(IRCode code, InternalOptions options) {
+ runPeepholes(code, nonDestructivePeepholes(), options);
+ runPeepholes(code, destructivePeepholes(), options);
}
- private static void runPeepholes(IRCode code, List<BasicBlockPeephole> peepholes) {
+ private static void runPeepholes(
+ IRCode code, List<BasicBlockPeephole> peepholes, InternalOptions options) {
ListIterator<BasicBlock> blocksIterator = code.listIterator(code.blocks.size());
+ int iterations = 0;
while (blocksIterator.hasPrevious()) {
BasicBlock currentBlock = blocksIterator.previous();
InstructionListIterator it =
@@ -60,6 +66,12 @@
}
}
if (it.hasPrevious()) {
+ if (options.testing.basicBlockMuncherIterationLimit != NO_LIMIT) {
+ if (iterations > options.testing.basicBlockMuncherIterationLimit) {
+ throw new CompilationError("Too many iterations in BasicBlockMuncher");
+ }
+ iterations++;
+ }
it.previous();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/peepholes/MoveLoadUpPeephole.java b/src/main/java/com/android/tools/r8/ir/optimize/peepholes/MoveLoadUpPeephole.java
index 1a98fef..c50791e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/peepholes/MoveLoadUpPeephole.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/peepholes/MoveLoadUpPeephole.java
@@ -85,8 +85,10 @@
// Find the place to insert a new load.
Instruction current = it.previous();
+ int moves = 1;
while (current != insertPosition) {
current = it.previous();
+ moves++;
}
// Insert directly above the other load.
@@ -94,8 +96,11 @@
newLoad.setPosition(insertPosition.getPosition());
it.add(newLoad);
- // Do not reset the instruction pointer because the iterator should reset.
- return true;
+ // This will run in a loop where we are only going backwards and there is no need to iterate
+ // the same instructions again since the StoreLoad peephole will not change the level of the
+ // stack.
+ PeepholeHelper.resetPrevious(it, moves + 1);
+ return false;
}
private static boolean isPotentionalIncInstruction(InstructionListIterator it) {
@@ -127,7 +132,7 @@
@Override
public boolean resetAfterMatch() {
- return true;
+ return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index b9dd6c6..60d6b06 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -973,6 +973,8 @@
public static class TestingOptions {
+ public static int NO_LIMIT = -1;
+
// Force writing the specified bytes as the DEX version content.
public byte[] forceDexVersionBytes = null;
@@ -1018,6 +1020,7 @@
public StringConsumer desugaredLibraryKeepRuleConsumer = null;
// TODO(b/129458850) When fixed, remove this and change all usages to "true".
public boolean enableStatefulLambdaCreateInstanceMethod = false;
+ public int basicBlockMuncherIterationLimit = NO_LIMIT;
// Flag to turn on/off JDK11+ nest-access control even when not required (Cf backend)
public boolean enableForceNestBasedAccessDesugaringForTest = false;
diff --git a/src/test/java/com/android/tools/r8/cf/BasicBlockMuncherQuadraticTest.java b/src/test/java/com/android/tools/r8/cf/BasicBlockMuncherQuadraticTest.java
index f47127f..7ab71ea 100644
--- a/src/test/java/com/android/tools/r8/cf/BasicBlockMuncherQuadraticTest.java
+++ b/src/test/java/com/android/tools/r8/cf/BasicBlockMuncherQuadraticTest.java
@@ -17,11 +17,8 @@
.addKeepMainRule(MethodHolder.class)
.addInnerClasses(BasicBlockMuncherQuadraticTest.class)
.noMinification()
+ .addOptionsModification(options -> options.testing.basicBlockMuncherIterationLimit = 50000)
.compile();
- long end = System.currentTimeMillis();
- if (end - start > 1000) {
- System.out.println("WARNING: compilation of this method took " + (end - start) + " ms.");
- }
}
public static class MethodHolder {