[LIR] Add support for safe check-cast variant.
Bug: b/225838009
Change-Id: I85370a4b69ab60c536c9e41626598fc3524944ed
diff --git a/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java b/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
index 1aee996..bfb48e6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.lightir.LirBuilder;
public class SafeCheckCast extends CheckCast {
@@ -28,6 +29,11 @@
}
@Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addSafeCheckCast(getType(), object());
+ }
+
+ @Override
DexCheckCast createCheckCast(int register) {
return new DexSafeCheckCast(register, getType());
}
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 985b5c2..45e136d 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -79,6 +79,7 @@
import com.android.tools.r8.ir.code.RecordFieldValues;
import com.android.tools.r8.ir.code.Rem;
import com.android.tools.r8.ir.code.Return;
+import com.android.tools.r8.ir.code.SafeCheckCast;
import com.android.tools.r8.ir.code.Shl;
import com.android.tools.r8.ir.code.Shr;
import com.android.tools.r8.ir.code.StaticGet;
@@ -741,6 +742,12 @@
}
@Override
+ public void onSafeCheckCast(DexType type, EV value) {
+ Value dest = getOutValueForNextInstruction(type.toTypeElement(appView));
+ addInstruction(new SafeCheckCast(dest, getValue(value), type));
+ }
+
+ @Override
public void onInstanceOf(DexType type, EV value) {
Value dest = getOutValueForNextInstruction(TypeElement.getInt());
addInstruction(new InstanceOf(dest, getValue(value), type));
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 0607661..09229fc 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -488,6 +488,13 @@
LirOpcodes.CHECKCAST, Collections.singletonList(type), Collections.singletonList(value));
}
+ public LirBuilder<V, EV> addSafeCheckCast(DexType type, V value) {
+ return addInstructionTemplate(
+ LirOpcodes.CHECKCAST_SAFE,
+ 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));
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 bd52773..8863892 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
@@ -208,6 +208,7 @@
int INITCLASS = 221;
int INVOKEPOLYMORPHIC = 222;
int RECORDFIELDVALUES = 223;
+ int CHECKCAST_SAFE = 224;
static String toString(int opcode) {
switch (opcode) {
@@ -540,6 +541,8 @@
return "INVOKEPOLYMORPHIC";
case RECORDFIELDVALUES:
return "RECORDFIELDVALUES";
+ case CHECKCAST_SAFE:
+ return "CHECKCAST_SAFE";
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 f4f6e64..73ad12b 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -472,6 +472,10 @@
onInstruction();
}
+ public void onSafeCheckCast(DexType type, EV value) {
+ onInstruction();
+ }
+
public void onInstanceOf(DexType type, EV value) {
onInstruction();
}
@@ -1109,6 +1113,13 @@
onCheckCast(type, value);
return;
}
+ case LirOpcodes.CHECKCAST_SAFE:
+ {
+ DexType type = getNextDexTypeOperand(view);
+ EV value = getNextValueOperand(view);
+ onSafeCheckCast(type, value);
+ return;
+ }
case LirOpcodes.INSTANCEOF:
{
DexType type = getNextDexTypeOperand(view);
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 b494ecb..5092894 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -350,6 +350,11 @@
}
@Override
+ public void onSafeCheckCast(DexType type, EV value) {
+ onCheckCast(type, value);
+ }
+
+ @Override
public void onInstanceOf(DexType type, EV value) {
appendOutValue();
appendValueArguments(value);