[LIR] Add support for new unboxed enum instance.
Also migrates legacy example tests stringbuilders, switches and switchmaps.
Bug: b/225838009
Bug: b/167145686
Change-Id: I0b2ce5d7fe80012716cd25036715fc284307399b
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
index 123b988..d47c812 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
@@ -22,6 +22,7 @@
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxer;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxerImpl;
+import com.android.tools.r8.lightir.LirBuilder;
/**
* Special instruction used by {@link EnumUnboxerImpl}.
@@ -166,4 +167,9 @@
void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
registry.registerNewUnboxedEnumInstance(clazz);
}
+
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addNewUnboxedEnumInstance(clazz, ordinal);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
index abccb80..b02f968 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -56,6 +56,7 @@
import com.android.tools.r8.ir.code.NewArrayEmpty;
import com.android.tools.r8.ir.code.NewArrayFilledData;
import com.android.tools.r8.ir.code.NewInstance;
+import com.android.tools.r8.ir.code.NewUnboxedEnumInstance;
import com.android.tools.r8.ir.code.NumberConversion;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.NumericType;
@@ -763,5 +764,12 @@
ArrayPut.createWithoutVerification(
type, getValue(array), getValue(index), getValue(value)));
}
+
+ @Override
+ public void onNewUnboxedEnumInstance(DexType clazz, int ordinal) {
+ TypeElement type = TypeElement.fromDexType(clazz, Nullability.definitelyNotNull(), appView);
+ Value dest = getOutValueForNextInstruction(type);
+ addInstruction(new NewUnboxedEnumInstance(clazz, ordinal, dest));
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index b0334c9..c19b47c 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -789,4 +789,13 @@
return addInstructionTemplate(
LirOpcodes.ITEMBASEDCONSTSTRING, ImmutableList.of(item, payload), Collections.emptyList());
}
+
+ public LirBuilder<V, EV> addNewUnboxedEnumInstance(DexType clazz, int ordinal) {
+ advanceInstructionState();
+ int operandSize = constantIndexSize(clazz) + ByteUtils.intEncodingSize(ordinal);
+ writer.writeInstruction(LirOpcodes.NEWUNBOXEDENUMINSTANCE, operandSize);
+ writeConstantIndex(clazz);
+ ByteUtils.writeEncodedInt(ordinal, writer::writeOperand);
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
index e4111ff..19179aa 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
@@ -197,6 +197,7 @@
int INVOKENEWARRAY = 214;
int NEWARRAYFILLEDDATA = 215;
int ITEMBASEDCONSTSTRING = 216;
+ int NEWUNBOXEDENUMINSTANCE = 217;
static String toString(int opcode) {
switch (opcode) {
@@ -515,6 +516,8 @@
return "NEWARRAYFILLEDDATA";
case ITEMBASEDCONSTSTRING:
return "ITEMBASEDCONSTSTRING";
+ case NEWUNBOXEDENUMINSTANCE:
+ return "NEWUNBOXEDENUMINSTANCE";
default:
throw new Unreachable("Unexpected LIR opcode: " + opcode);
diff --git a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
index 8277988..3354fba 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -410,6 +410,10 @@
public abstract void onMonitorExit(EV value);
+ public void onNewUnboxedEnumInstance(DexType type, int ordinal) {
+ onInstruction();
+ }
+
private DexItem getConstantItem(int index) {
return code.getConstantItem(index);
}
@@ -1059,6 +1063,13 @@
onDexItemBasedConstString(item, payload.nameComputationInfo);
return;
}
+ case LirOpcodes.NEWUNBOXEDENUMINSTANCE:
+ {
+ DexType type = getNextDexTypeOperand(view);
+ int ordinal = view.getNextIntegerOperand();
+ onNewUnboxedEnumInstance(type, ordinal);
+ return;
+ }
default:
throw new Unimplemented("No dispatch for opcode " + LirOpcodes.toString(opcode));
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
index 7aaf668..26a4694 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -379,4 +379,9 @@
public void onMonitorExit(EV value) {
appendValueArguments(value);
}
+
+ @Override
+ public void onNewUnboxedEnumInstance(DexType type, int ordinal) {
+ appendOutValue().append("type(").append(type).append(") ordinal(").append(ordinal).append(")");
+ }
}
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index a303b8c..c359fd9 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -27,8 +27,6 @@
String[] tests = {
"arithmetic.Arithmetic",
"inlining.Inlining",
- "stringbuilding.StringBuilding",
- "switches.Switches",
"sync.Sync",
"throwing.Throwing",
"trivial.Trivial",
@@ -51,7 +49,6 @@
"minification.Minification",
"enclosingmethod.Main",
"enclosingmethod_proguarded.Main",
- "switchmaps.Switches",
"uninitializedfinal.UninitializedFinalFieldLeak",
};
diff --git a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
index c870a8e..c1bf716 100644
--- a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
@@ -60,16 +60,6 @@
}
@Test
- public void testStringBuilding() throws Exception {
- testDebugging("stringbuilding", "StringBuilding");
- }
-
- @Test
- public void testSwitches() throws Exception {
- testDebugging("switches", "Switches");
- }
-
- @Test
public void testSync() throws Exception {
// TODO(b/79671093): Line number mismatch in D8.
testDebuggingJvmOnly("sync", "Sync");
@@ -179,12 +169,6 @@
testDebuggingJvmOutputOnly("enclosingmethod_proguarded", "Main");
}
- @Test
- public void testSwitchmaps() throws Exception {
- // TODO(b/79671093): D8 has different line number info during stepping.
- testDebuggingJvmOnly("switchmaps", "Switches");
- }
-
private void testDebugging(String pkg, String clazz) throws Exception {
init(pkg, clazz)
.add("Input", input())
diff --git a/src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java b/src/test/java/com/android/tools/r8/examples/staticfield/StaticFieldTestRunner.java
similarity index 92%
rename from src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java
rename to src/test/java/com/android/tools/r8/examples/staticfield/StaticFieldTestRunner.java
index 81ca334..3cb14eb 100644
--- a/src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java
+++ b/src/test/java/com/android/tools/r8/examples/staticfield/StaticFieldTestRunner.java
@@ -1,12 +1,11 @@
// Copyright (c) 2023, 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.examples.returns;
+package com.android.tools.r8.examples.staticfield;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.examples.ExamplesTestBase;
-import com.android.tools.r8.examples.staticfield.StaticField;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Assume;
import org.junit.Test;
diff --git a/src/test/examples/stringbuilding/StringBuilding.java b/src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuilding.java
similarity index 96%
rename from src/test/examples/stringbuilding/StringBuilding.java
rename to src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuilding.java
index 18152fb..0805f37 100644
--- a/src/test/examples/stringbuilding/StringBuilding.java
+++ b/src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuilding.java
@@ -5,7 +5,7 @@
// This code is not run directly. It needs to be compiled to dex code.
// 'stringbuilding.dex' is what is run.
-package stringbuilding;
+package com.android.tools.r8.examples.stringbuilding;
class StringBuilding {
diff --git a/src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java b/src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuildingTestRunner.java
similarity index 67%
copy from src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java
copy to src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuildingTestRunner.java
index 81ca334..db98076 100644
--- a/src/test/java/com/android/tools/r8/examples/returns/StaticFieldTestRunner.java
+++ b/src/test/java/com/android/tools/r8/examples/stringbuilding/StringBuildingTestRunner.java
@@ -1,38 +1,43 @@
// Copyright (c) 2023, 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.examples.returns;
+package com.android.tools.r8.examples.stringbuilding;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.examples.ExamplesTestBase;
-import com.android.tools.r8.examples.staticfield.StaticField;
import com.android.tools.r8.utils.StringUtils;
-import org.junit.Assume;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
-public class StaticFieldTestRunner extends ExamplesTestBase {
+public class StringBuildingTestRunner extends ExamplesTestBase {
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
}
- public StaticFieldTestRunner(TestParameters parameters) {
+ public StringBuildingTestRunner(TestParameters parameters) {
super(parameters);
}
@Override
public Class<?> getMainClass() {
- return StaticField.class;
+ return StringBuilding.class;
+ }
+
+ @Override
+ public List<Class<?>> getTestClasses() throws Exception {
+ return ImmutableList.of(getMainClass(), StringBuilding.X.class);
}
@Override
public String getExpected() {
- return StringUtils.lines("101010", "101010", "ABC", "ABC");
+ return StringUtils.joinLines("a2c-xyz-abc7xyz", "trueABCDE1234232.21.101an Xstringbuilder");
}
@Test
@@ -47,8 +52,6 @@
@Test
public void testDebug() throws Exception {
- // TODO(b/79671093): DEX has different line number info during stepping.
- Assume.assumeTrue(parameters.isCfRuntime());
runTestDebugComparator();
}
}
diff --git a/src/test/examples/switches/Switches.java b/src/test/java/com/android/tools/r8/examples/switches/Switches.java
similarity index 97%
rename from src/test/examples/switches/Switches.java
rename to src/test/java/com/android/tools/r8/examples/switches/Switches.java
index 588e541..a51e94b 100644
--- a/src/test/examples/switches/Switches.java
+++ b/src/test/java/com/android/tools/r8/examples/switches/Switches.java
@@ -5,7 +5,7 @@
// This code is not run directly. It needs to be compiled to dex code.
// 'switches.dex' is what is run.
-package switches;
+package com.android.tools.r8.examples.switches;
class Switches {
diff --git a/src/test/java/com/android/tools/r8/examples/switches/SwitchesTestRunner.java b/src/test/java/com/android/tools/r8/examples/switches/SwitchesTestRunner.java
new file mode 100644
index 0000000..5bcd322
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/switches/SwitchesTestRunner.java
@@ -0,0 +1,68 @@
+// Copyright (c) 2023, 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.examples.switches;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.examples.ExamplesTestBase;
+import com.android.tools.r8.utils.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class SwitchesTestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public SwitchesTestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return Switches.class;
+ }
+
+ @Override
+ public String getExpected() {
+ return StringUtils.lines(
+ "packedSwitch cases: 0 1 2 after switch 0",
+ "packedSwitch cases: 1 2 after switch 1",
+ "packedSwitch cases: 1 2 after switch 2",
+ "packedSwitch cases: after switch -1",
+ "0 ",
+ "100 ",
+ "after switch 0",
+ "100 ",
+ "after switch 100",
+ "200 ",
+ "after switch 200",
+ "after switch -1",
+ " 420",
+ " 1.02",
+ "0-21 after switch 1",
+ "0-21 after switch 10",
+ "after switch 40",
+ "60 after switch 60");
+ }
+
+ @Test
+ public void testDesugaring() throws Exception {
+ runTestDesugaring();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ runTestR8();
+ }
+
+ @Test
+ public void testDebug() throws Exception {
+ runTestDebugComparator();
+ }
+}
diff --git a/src/test/examples/switchmaps/Colors.java b/src/test/java/com/android/tools/r8/examples/switchmaps/Colors.java
similarity index 89%
rename from src/test/examples/switchmaps/Colors.java
rename to src/test/java/com/android/tools/r8/examples/switchmaps/Colors.java
index b2c8dc1..15b4ad6 100644
--- a/src/test/examples/switchmaps/Colors.java
+++ b/src/test/java/com/android/tools/r8/examples/switchmaps/Colors.java
@@ -1,7 +1,7 @@
// Copyright (c) 2017, 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 switchmaps;
+package com.android.tools.r8.examples.switchmaps;
public enum Colors {
RED("rar"), BLUE("blew"), GREEN("soylent"), GRAY("fifty");
diff --git a/src/test/examples/switchmaps/Days.java b/src/test/java/com/android/tools/r8/examples/switchmaps/Days.java
similarity index 85%
rename from src/test/examples/switchmaps/Days.java
rename to src/test/java/com/android/tools/r8/examples/switchmaps/Days.java
index b484bb5..710edfa 100644
--- a/src/test/examples/switchmaps/Days.java
+++ b/src/test/java/com/android/tools/r8/examples/switchmaps/Days.java
@@ -1,7 +1,7 @@
// Copyright (c) 2017, 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 switchmaps;
+package com.android.tools.r8.examples.switchmaps;
public enum Days {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
diff --git a/src/test/java/com/android/tools/r8/examples/switchmaps/SwitchMapsTestRunner.java b/src/test/java/com/android/tools/r8/examples/switchmaps/SwitchMapsTestRunner.java
new file mode 100644
index 0000000..1fb0770
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/switchmaps/SwitchMapsTestRunner.java
@@ -0,0 +1,89 @@
+// Copyright (c) 2023, 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.examples.switchmaps;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.examples.ExamplesTestBase;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class SwitchMapsTestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public SwitchMapsTestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return Switches.class;
+ }
+
+ @Override
+ public List<Class<?>> getTestClasses() throws Exception {
+ return ImmutableList.of(
+ getMainClass(),
+ Class.forName(getMainClass().getTypeName() + "$1"),
+ Days.class,
+ Colors.class);
+ }
+
+ @Override
+ public String getExpected() {
+ return StringUtils.lines(
+ "other",
+ "1, 3 or 4",
+ "2 or 5",
+ "other",
+ "2 or 5",
+ "3 or 5",
+ "1, 3 or 4",
+ "2 or 5",
+ "other",
+ "1, 3 or 4",
+ "2 or 5",
+ "3 or 5",
+ "2 or 5",
+ "other",
+ "6",
+ "7",
+ "7",
+ "rar",
+ "colorful",
+ "blew",
+ "colorful",
+ "soylent",
+ "sooo green",
+ "fifty",
+ "not really");
+ }
+
+ @Test
+ public void testDesugaring() throws Exception {
+ runTestDesugaring();
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ runTestR8();
+ }
+
+ @Test
+ public void testDebug() throws Exception {
+ // TODO(b/79671093): DEX has different line number info during stepping.
+ Assume.assumeTrue(parameters.isCfRuntime());
+ runTestDebugComparator();
+ }
+}
diff --git a/src/test/examples/switchmaps/Switches.java b/src/test/java/com/android/tools/r8/examples/switchmaps/Switches.java
similarity index 96%
rename from src/test/examples/switchmaps/Switches.java
rename to src/test/java/com/android/tools/r8/examples/switchmaps/Switches.java
index bf16856..4b5cb54 100644
--- a/src/test/examples/switchmaps/Switches.java
+++ b/src/test/java/com/android/tools/r8/examples/switchmaps/Switches.java
@@ -1,7 +1,7 @@
// Copyright (c) 2017, 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 switchmaps;
+package com.android.tools.r8.examples.switchmaps;
public class Switches {