Introduce StringSwitch instructions in D8
Change-Id: I1bfc0b3b1b97f84c767b1be9fc6c96f765545beb
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index bd261a3..9d6a8b6 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -35,6 +35,7 @@
import com.android.tools.r8.ir.conversion.passes.FilledNewArrayRewriter;
import com.android.tools.r8.ir.conversion.passes.MoveResultRewriter;
import com.android.tools.r8.ir.conversion.passes.ParentConstructorHoistingCodeRewriter;
+import com.android.tools.r8.ir.conversion.passes.StringSwitchConverter;
import com.android.tools.r8.ir.conversion.passes.StringSwitchRemover;
import com.android.tools.r8.ir.conversion.passes.ThrowCatchOptimizer;
import com.android.tools.r8.ir.conversion.passes.TrivialPhiSimplifier;
@@ -584,6 +585,13 @@
return timing;
}
+ // In R8, StringSwitch instructions are introduced when entering the LIR phase. In D8, we don't
+ // use LIR, so we explicitly introduce StringSwitch instructions here.
+ if (!options.getTestingOptions().isSupportedLirPhase()) {
+ new StringSwitchConverter(appView)
+ .run(code, methodProcessor, methodProcessingContext, timing);
+ }
+
if (options.canHaveArtStringNewInitBug()) {
timing.begin("Check for new-init issue");
TrivialPhiSimplifier.ensureDirectStringNewToInit(appView, code);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/switches/ConvertRemovedStringSwitchTest.java b/src/test/java/com/android/tools/r8/ir/optimize/switches/ConvertRemovedStringSwitchTest.java
index 1239133..fc490c64 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/switches/ConvertRemovedStringSwitchTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/switches/ConvertRemovedStringSwitchTest.java
@@ -13,8 +13,14 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.conversion.passes.StringSwitchConverter;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
@@ -52,7 +58,7 @@
.assertSuccessWithOutputLines("A", "B", "C", "D", "E!");
}
- private void inspect(CodeInspector inspector) {
+ private void inspect(CodeInspector inspector) throws Exception {
ClassSubject classSubject = inspector.clazz(TestClass.class);
assertThat(classSubject, isPresent());
@@ -69,7 +75,12 @@
assertEquals(1, stringCounts.getInt("E!"));
// Verify that we can rebuild the StringSwitch instruction.
- IRCode code = mainMethodSubject.buildIR();
+ AppView<?> appView =
+ computeAppView(
+ AndroidApp.builder().build(),
+ new InternalOptions(inspector.getFactory(), new Reporter()));
+ IRCode code = mainMethodSubject.buildIR(appView);
+ new StringSwitchConverter(appView).run(code, Timing.empty());
assertTrue(code.streamInstructions().anyMatch(Instruction::isStringSwitch));
}
diff --git a/src/test/testbase/java/com/android/tools/r8/TestBase.java b/src/test/testbase/java/com/android/tools/r8/TestBase.java
index a0dbfa4..5512419 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestBase.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestBase.java
@@ -793,9 +793,14 @@
}
protected static AppView<AppInfo> computeAppView(AndroidApp app) throws Exception {
+ return computeAppView(app, new InternalOptions());
+ }
+
+ protected static AppView<AppInfo> computeAppView(AndroidApp app, InternalOptions options)
+ throws Exception {
AppInfo appInfo =
AppInfo.createInitialAppInfo(
- readApplicationForDexOutput(app, new InternalOptions()),
+ readApplicationForDexOutput(app, options),
GlobalSyntheticsStrategy.forNonSynthesizing());
return AppView.createForD8(appInfo);
}