Prefer non-range invoke for single operand invokes when possible
Bug: b/378823200
Change-Id: I8e904990d7cbbd85617d4b4256400a13ff0bb371
Fixes: b/378819837
diff --git a/src/main/java/com/android/tools/r8/ir/code/Invoke.java b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
index d16fdc6..6aa12e5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Invoke.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
@@ -258,8 +258,13 @@
// Used to decide if this invoke should be emitted as invoke/range.
protected boolean needsRangedInvoke(DexBuilder builder) {
if (arguments().size() == 1) {
- // Prefer invoke-range since this does not impose any constraints on the operand register.
- return true;
+ // Prefer non-range invoke since ART's LSE does not always consider invoke/range
+ // (b/378823200).
+ int registerEnd =
+ builder.getRegisterAllocator().getRegisterForValue(getFirstArgument(), getNumber())
+ + getFirstArgument().requiredRegisters()
+ - 1;
+ return registerEnd > Constants.U4BIT_MAX;
}
if (requiredArgumentRegisters() > 5) {
// No way around using an invoke-range instruction.
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
index e1c7e00..f29440c 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/InvokeTypeConversionTest.java
@@ -13,8 +13,8 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.dex.code.DexInvokeDirectRange;
-import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
+import com.android.tools.r8.dex.code.DexInvokeDirect;
+import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.smali.SmaliBuilder;
@@ -121,7 +121,7 @@
assertNotNull(method);
DexCode code = method.getCode().asDexCode();
// The given invoke line is remained as-is.
- assertTrue(code.instructions[2] instanceof DexInvokeDirectRange);
+ assertTrue(code.instructions[2] instanceof DexInvokeDirect);
});
}
@@ -152,7 +152,7 @@
assertNotNull(method);
DexCode code = method.getCode().asDexCode();
// The given invoke line is changed to invoke-virtual
- assertTrue(code.instructions[2] instanceof DexInvokeVirtualRange);
+ assertTrue(code.instructions[2] instanceof DexInvokeVirtual);
});
}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
index d64aa20..9c7cf17 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
@@ -8,7 +8,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexInvokeStaticRange;
+import com.android.tools.r8.dex.code.DexInvokeStatic;
import com.android.tools.r8.dex.code.DexReturnVoid;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.smali.SmaliBuilder;
@@ -55,7 +55,7 @@
assertTrue(code.instructions[0] instanceof DexConstString);
DexConstString constString = (DexConstString) code.instructions[0];
assertNotEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof DexInvokeStaticRange);
+ assertTrue(code.instructions[1] instanceof DexInvokeStatic);
assertTrue(code.instructions[2] instanceof DexReturnVoid);
}
@@ -91,7 +91,7 @@
assertTrue(code.instructions[0] instanceof DexConstString);
DexConstString constString = (DexConstString) code.instructions[0];
assertEquals(BOO, constString.getString().toString());
- assertTrue(code.instructions[1] instanceof DexInvokeStaticRange);
+ assertTrue(code.instructions[1] instanceof DexInvokeStatic);
assertTrue(code.instructions[2] instanceof DexReturnVoid);
}
diff --git a/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java b/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
index eb24283..3449aa1 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/GetMembersTest.java
@@ -15,7 +15,7 @@
import com.android.tools.r8.dex.code.DexConst4;
import com.android.tools.r8.dex.code.DexConstClass;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexFilledNewArrayRange;
+import com.android.tools.r8.dex.code.DexFilledNewArray;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexMoveResultObject;
import com.android.tools.r8.dex.code.DexNewArray;
@@ -75,9 +75,9 @@
private void inspectGetMethodTest(MethodSubject method) {
// Accept either array construction style (differs based on minSdkVersion).
DexCode code = method.getMethod().getCode().asDexCode();
- if (code.instructions[1] instanceof DexFilledNewArrayRange) {
+ if (code.instructions[1] instanceof DexFilledNewArray) {
assertTrue(code.instructions[0] instanceof DexConstClass);
- assertTrue(code.instructions[1] instanceof DexFilledNewArrayRange);
+ assertTrue(code.instructions[1] instanceof DexFilledNewArray);
assertTrue(code.instructions[2] instanceof DexMoveResultObject);
assertTrue(code.instructions[3] instanceof DexConstClass);
assertTrue(code.instructions[4] instanceof DexConstString);
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index 42a037e..cc150aa 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -18,10 +18,9 @@
import com.android.tools.r8.dex.code.DexConst4;
import com.android.tools.r8.dex.code.DexConstClass;
import com.android.tools.r8.dex.code.DexConstString;
-import com.android.tools.r8.dex.code.DexFilledNewArrayRange;
-import com.android.tools.r8.dex.code.DexInvokeDirectRange;
+import com.android.tools.r8.dex.code.DexFilledNewArray;
+import com.android.tools.r8.dex.code.DexInvokeDirect;
import com.android.tools.r8.dex.code.DexInvokeStatic;
-import com.android.tools.r8.dex.code.DexInvokeStaticRange;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexIputObject;
import com.android.tools.r8.dex.code.DexMoveResultObject;
@@ -86,10 +85,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
- DexConstString.class,
- DexIputObject.class,
- DexReturnVoid.class));
+ DexInvokeDirect.class, DexConstString.class, DexIputObject.class, DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[1];
assertEquals(BOO, constString.getString().toString());
}
@@ -123,7 +119,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
@@ -164,7 +160,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
@@ -415,7 +411,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstString.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -459,11 +455,11 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
- DexInvokeStaticRange.class,
+ DexInvokeStatic.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
@@ -504,12 +500,12 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexSgetObject.class,
DexConstString.class,
DexInvokeVirtual.class,
DexConstString.class,
- DexInvokeStaticRange.class,
+ DexInvokeStatic.class,
DexReturnVoid.class));
DexConstString constString = (DexConstString) code.instructions[2];
assertEquals(BOO, constString.getString().toString());
@@ -559,7 +555,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -610,7 +606,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -666,13 +662,13 @@
DexCode code = method.getCode().asDexCode();
// Accept either array construction style (differs based on minSdkVersion).
- if (code.instructions[2].getClass() == DexFilledNewArrayRange.class) {
+ if (code.instructions[2].getClass() == DexFilledNewArray.class) {
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
- DexFilledNewArrayRange.class,
+ DexFilledNewArray.class,
DexMoveResultObject.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -681,7 +677,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConst4.class,
DexNewArray.class,
@@ -742,13 +738,13 @@
DexCode code = method.getCode().asDexCode();
// Accept either array construction style (differs based on minSdkVersion).
- if (code.instructions[2].getClass() == DexFilledNewArrayRange.class) {
+ if (code.instructions[2].getClass() == DexFilledNewArray.class) {
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
- DexFilledNewArrayRange.class,
+ DexFilledNewArray.class,
DexMoveResultObject.class,
DexConstString.class,
DexInvokeStatic.class,
@@ -757,7 +753,7 @@
checkInstructions(
code,
ImmutableList.of(
- DexInvokeDirectRange.class,
+ DexInvokeDirect.class,
DexConstClass.class,
DexConst4.class,
DexNewArray.class,
diff --git a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
index c7adad6..9642e4e 100644
--- a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
+++ b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
@@ -14,7 +14,7 @@
import com.android.tools.r8.dex.code.DexIfLez;
import com.android.tools.r8.dex.code.DexIfLtz;
import com.android.tools.r8.dex.code.DexIfNez;
-import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
+import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexReturn;
import com.android.tools.r8.dex.code.DexReturnObject;
import com.android.tools.r8.graph.DexCode;
@@ -399,7 +399,7 @@
" goto :label_7");
DexCode code = method.getCode().asDexCode();
assertEquals(3, code.instructions.length);
- assertTrue(code.instructions[0] instanceof DexInvokeVirtualRange);
+ assertTrue(code.instructions[0] instanceof DexInvokeVirtual);
assertTrue(code.instructions[1] instanceof DexConst4);
assertEquals(0, ((DexConst4) code.instructions[1]).B);
assertTrue(code.instructions[2] instanceof DexReturnObject);
diff --git a/src/test/java/com/android/tools/r8/smali/OutlineTest.java b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
index b3a09bf..25e8d89 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -575,7 +575,7 @@
DexInvokeStatic invoke = (DexInvokeStatic) mainCode.instructions[4];
assertTrue(isOutlineMethodName(invoke.getMethod()));
} else if (i == 3) {
- DexInvokeStaticRange invoke = (DexInvokeStaticRange) mainCode.instructions[1];
+ DexInvokeStatic invoke = (DexInvokeStatic) mainCode.instructions[1];
assertTrue(isOutlineMethodName(invoke.getMethod()));
} else {
assert i == 4 || i == 5;