[LIR] Add support for instanceof.
This also migrates ifstatements, instancevariable and interfaceinlining
example tests.
Bug: b/167145686
Change-Id: Iefbc2d5304cf449a2136e62dce9fac26a7a6627a
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
index 680ace0..9834a17 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
import java.util.Set;
public class InstanceOf extends Instruction {
@@ -135,4 +136,9 @@
void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
registry.registerInstanceOf(type);
}
+
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addInstanceOf(type, value());
+ }
}
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 6dcfe40..0583876 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -35,6 +35,7 @@
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.IfType;
import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.InstanceOf;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
@@ -588,6 +589,12 @@
}
@Override
+ public void onInstanceOf(DexType type, EV value) {
+ Value dest = getOutValueForNextInstruction(TypeElement.getInt());
+ addInstruction(new InstanceOf(dest, getValue(value), type));
+ }
+
+ @Override
public void onDebugPosition() {
addInstruction(new DebugPosition());
}
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 1239c11..54bdd09 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -401,6 +401,11 @@
LirOpcodes.CHECKCAST, Collections.singletonList(type), Collections.singletonList(value));
}
+ public LirBuilder<V, EV> addInstanceOf(DexType type, V value) {
+ return addInstructionTemplate(
+ LirOpcodes.INSTANCEOF, Collections.singletonList(type), Collections.singletonList(value));
+ }
+
public LirBuilder<V, EV> addStaticGet(DexField field) {
return addOneItemInstruction(LirOpcodes.GETSTATIC, field);
}
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 8d81728..fa36ce6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -372,6 +372,10 @@
onInstruction();
}
+ public void onInstanceOf(DexType type, EV value) {
+ onInstruction();
+ }
+
public void onDebugPosition() {
onInstruction();
}
@@ -938,6 +942,13 @@
onCheckCast(type, value);
return;
}
+ case LirOpcodes.INSTANCEOF:
+ {
+ DexType type = getNextDexTypeOperand(view);
+ EV value = getNextValueOperand(view);
+ onInstanceOf(type, value);
+ return;
+ }
case LirOpcodes.DEBUGPOS:
{
onDebugPosition();
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 58ac9b2..c3c06b1 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -304,6 +304,13 @@
}
@Override
+ public void onInstanceOf(DexType type, EV value) {
+ appendOutValue();
+ appendValueArguments(value);
+ builder.append(type);
+ }
+
+ @Override
public void onArrayGetPrimitive(MemberType type, EV array, EV index) {
appendOutValue();
appendValueArguments(array, index);
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index d63d66c..418dad3 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -26,9 +26,7 @@
public static Collection<String[]> data() {
String[] tests = {
"arithmetic.Arithmetic",
- "ifstatements.IfStatements",
"inlining.Inlining",
- "instancevariable.InstanceVariable",
"instanceofstring.InstanceofString",
"invoke.Invoke",
"invokeempty.InvokeEmpty",
@@ -65,7 +63,6 @@
"minification.Minification",
"enclosingmethod.Main",
"enclosingmethod_proguarded.Main",
- "interfaceinlining.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 577eb22..fe9bed4 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 testIfStatements() throws Exception {
- testDebugging("ifstatements", "IfStatements");
- }
-
- @Test
- public void testInstanceVariable() throws Exception {
- testDebugging("instancevariable", "InstanceVariable");
- }
-
- @Test
public void testInstanceofString() throws Exception {
testDebugging("instanceofstring", "InstanceofString");
}
@@ -252,11 +242,6 @@
}
@Test
- public void testInterfaceinlining() throws Exception {
- testDebugging("interfaceinlining", "Main");
- }
-
- @Test
public void testSwitchmaps() throws Exception {
// TODO(b/79671093): D8 has different line number info during stepping.
testDebuggingJvmOnly("switchmaps", "Switches");
diff --git a/src/test/examples/ifstatements/IfStatements.java b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
similarity index 96%
rename from src/test/examples/ifstatements/IfStatements.java
rename to src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
index 5d340ab..41183af 100644
--- a/src/test/examples/ifstatements/IfStatements.java
+++ b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
@@ -1,7 +1,7 @@
// Copyright (c) 2016, 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 ifstatements;
+package com.android.tools.r8.examples.ifstatements;
class IfStatements {
diff --git a/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java
new file mode 100644
index 0000000..9106b03
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java
@@ -0,0 +1,72 @@
+// 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.ifstatements;
+
+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 IfStatementsTestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public IfStatementsTestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return IfStatements.class;
+ }
+
+ @Override
+ public String getExpected() {
+ return StringUtils.lines(
+ "sisnotnull",
+ "sisnull",
+ "ifCond x != 0",
+ "ifCond x < 0",
+ "ifCond x <= 0",
+ "ifCond x == 0",
+ "ifCond x >= 0",
+ "ifCond x <= 0",
+ "ifCond x != 0",
+ "ifCond x >= 0",
+ "ifCond x > 0",
+ "ifIcmp x != y",
+ "ifIcmp x < y",
+ "ifIcmp x <= y",
+ "ifIcmp x == y",
+ "ifIcmp x >= y",
+ "ifIcmp x <= y",
+ "ifIcmp x != y",
+ "ifIcmp x >= y",
+ "ifIcmp x > y",
+ "ifAcmp a == b",
+ "ifAcmp a != b");
+ }
+
+ @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/instancevariable/InstanceVariable.java b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
similarity index 93%
rename from src/test/examples/instancevariable/InstanceVariable.java
rename to src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
index 88768f1..fdad644 100644
--- a/src/test/examples/instancevariable/InstanceVariable.java
+++ b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
@@ -1,7 +1,7 @@
// Copyright (c) 2016, 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 instancevariable;
+package com.android.tools.r8.examples.instancevariable;
class InstanceVariable {
public int foo = 42;
diff --git a/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java
new file mode 100644
index 0000000..95b20d4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java
@@ -0,0 +1,50 @@
+// 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.instancevariable;
+
+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 InstanceVariableTestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public InstanceVariableTestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return InstanceVariable.class;
+ }
+
+ @Override
+ public String getExpected() {
+ return StringUtils.lines("144=144");
+ }
+
+ @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/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java b/src/test/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java
new file mode 100644
index 0000000..05138f2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java
@@ -0,0 +1,56 @@
+// 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.interfaceinlining;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.examples.ExamplesTestBase;
+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 InterfaceInliningTestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public InterfaceInliningTestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return Main.class;
+ }
+
+ @Override
+ public List<Class<?>> getTestClasses() {
+ return ImmutableList.of(Main.class, Main.Data.class, Main.DataI.class);
+ }
+
+ @Override
+ public String getExpected() {
+ return "true";
+ }
+
+ @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/interfaceinlining/Main.java b/src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.java
similarity index 93%
rename from src/test/examples/interfaceinlining/Main.java
rename to src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.java
index 865fa14..2c23c4d 100644
--- a/src/test/examples/interfaceinlining/Main.java
+++ b/src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.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 interfaceinlining;
+package com.android.tools.r8.examples.interfaceinlining;
// This test ensures a check cast instruction is inserted IFF
// the expression "((DataI) other).field()" is inlined.