Fix removal of used StringBuilder
Bug: 213369062
Change-Id: I4bf0fcd6bab119a61531f91d8ad4833669cd9b4b
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
index 33f4ba5..dca8e31 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
@@ -356,6 +356,10 @@
if (!candidateBuilders.contains(builder)) {
continue;
}
+ if (builder.hasPhiUsers()) {
+ candidateBuilders.remove(builder);
+ continue;
+ }
Map<Instruction, BuilderState> perInstrState = createBuilderState(builder);
perInstrState.put(instr, BuilderState.createRoot());
continue;
@@ -396,6 +400,10 @@
if (!candidateBuilders.contains(builder)) {
continue;
}
+ if (invoke.hasUsedOutValue()) {
+ candidateBuilders.remove(builder);
+ continue;
+ }
Value arg = invoke.inValues().get(1).getAliasedValue();
DexType argType = invoke.getInvokedMethod().proto.parameters.values[0];
String addition = extractConstantArgument(arg, argType);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisSmaliTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisSmaliTest.java
index 8552e48..cc582ea 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisSmaliTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisSmaliTest.java
@@ -158,29 +158,33 @@
public void testPhiWithDifferentNewInstance() {
buildAndCheckIR(
"phiWithDifferentNewInstance",
- checkOptimizerStates(appView, optimizer -> {
- assertEquals(2, optimizer.analysis.builderStates.size());
- for (Value builder : optimizer.analysis.builderStates.keySet()) {
- Map<Instruction, BuilderState> perBuilderState =
- optimizer.analysis.builderStates.get(builder);
- checkBuilderState(optimizer, perBuilderState, null, false);
- }
- assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
- }));
+ checkOptimizerStates(
+ appView,
+ optimizer -> {
+ assertEquals(0, optimizer.analysis.builderStates.size());
+ for (Value builder : optimizer.analysis.builderStates.keySet()) {
+ Map<Instruction, BuilderState> perBuilderState =
+ optimizer.analysis.builderStates.get(builder);
+ checkBuilderState(optimizer, perBuilderState, null, false);
+ }
+ assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
+ }));
}
@Test
public void testPhiAtInit() {
buildAndCheckIR(
"phiAtInit",
- checkOptimizerStates(appView, optimizer -> {
- assertEquals(2, optimizer.analysis.builderStates.size());
- for (Value builder : optimizer.analysis.builderStates.keySet()) {
- Map<Instruction, BuilderState> perBuilderState =
- optimizer.analysis.builderStates.get(builder);
- checkBuilderState(optimizer, perBuilderState, null, false);
- }
- assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
- }));
+ checkOptimizerStates(
+ appView,
+ optimizer -> {
+ assertEquals(0, optimizer.analysis.builderStates.size());
+ for (Value builder : optimizer.analysis.builderStates.keySet()) {
+ Map<Instruction, BuilderState> perBuilderState =
+ optimizer.analysis.builderStates.get(builder);
+ checkBuilderState(optimizer, perBuilderState, null, false);
+ }
+ assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
+ }));
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisTest.java
index e18c8ea..72b5887 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizerAnalysisTest.java
@@ -290,15 +290,17 @@
public void testPhiWithDifferentInits() {
buildAndCheckIR(
"phiWithDifferentInits",
- checkOptimizerStates(appView, optimizer -> {
- assertEquals(2, optimizer.analysis.builderStates.size());
- for (Value builder : optimizer.analysis.builderStates.keySet()) {
- Map<Instruction, BuilderState> perBuilderState =
- optimizer.analysis.builderStates.get(builder);
- checkBuilderState(optimizer, perBuilderState, null, false);
- }
- assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
- }));
+ checkOptimizerStates(
+ appView,
+ optimizer -> {
+ assertEquals(0, optimizer.analysis.builderStates.size());
+ for (Value builder : optimizer.analysis.builderStates.keySet()) {
+ Map<Instruction, BuilderState> perBuilderState =
+ optimizer.analysis.builderStates.get(builder);
+ checkBuilderState(optimizer, perBuilderState, null, false);
+ }
+ assertEquals(0, optimizer.analysis.simplifiedBuilders.size());
+ }));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderWithLoopTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderWithLoopTest.java
index 05899f9..8cc98c4 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderWithLoopTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringBuilderWithLoopTest.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.codeinspector.AssertUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -27,16 +26,13 @@
@Test
public void test() throws Exception {
- AssertUtils.assertFailsCompilationIf(
- parameters.isDexRuntime(),
- () ->
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .addKeepMainRule(Main.class)
- .addKeepClassAndMembersRules(Utils.class)
- .setMinApi(parameters.getApiLevel())
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines("1", "2"));
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addKeepClassAndMembersRules(Utils.class)
+ .setMinApi(parameters.getApiLevel())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("1", "2");
}
static class Main {