Use more lit8 dex instruction form
- During build of lit8/lit16 dex instructions what we want to
check is if a value need a register for the current instruction
or not. Check if the value need a register for all usages is too
restrictive, for instance, each time a constant through by a phi
instruction, lit8/lit16 instructions were not used but it is safe
to use them.
Bug: 68188667
Change-Id: I50bc781c3ecde0fa5556355dab263644509a9c39
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java b/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
index 14a2a98..56d8de2 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArithmeticBinop.java
@@ -113,7 +113,7 @@
default:
throw new Unreachable("Unexpected numeric type " + type.name());
}
- } else if (!rightValue().needsRegister()) {
+ } else if (!needsValueInRegister(rightValue())) {
assert !isSub(); // Constants in instructions for sub must be handled in subclass Sub.
assert fitsInDexInstruction(rightValue());
ConstNumber right = rightValue().getConstInstruction().asConstNumber();
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index e7b82d6..0a907c3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -291,13 +291,38 @@
public abstract int compareNonValueParts(Instruction other);
- private boolean identicalAfterRegisterAllocation(
- Value a, int aInstr, Value b, int bInstr, RegisterAllocator allocator) {
+ private boolean identicalInputAfterRegisterAllocation(
+ Value a, int aInstrNumber, Instruction bInstr, Value b, int bInstrNumber,
+ RegisterAllocator allocator) {
+ if (needsValueInRegister(a) != bInstr.needsValueInRegister(b)) {
+ return false;
+ }
+ if (needsValueInRegister(a)) {
+ if (allocator.getRegisterForValue(a, aInstrNumber) !=
+ allocator.getRegisterForValue(b, bInstrNumber)) {
+ return false;
+ }
+ } else {
+ ConstNumber aNum = a.getConstInstruction().asConstNumber();
+ ConstNumber bNum = b.getConstInstruction().asConstNumber();
+ if (!aNum.identicalNonValueNonPositionParts(bNum)) {
+ return false;
+ }
+ }
+ if (a.outType() != b.outType()) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean identicalOutputAfterRegisterAllocation(
+ Value a, int aInstrNumber, Value b, int bInstrNumber, RegisterAllocator allocator) {
if (a.needsRegister() != b.needsRegister()) {
return false;
}
if (a.needsRegister()) {
- if (allocator.getRegisterForValue(a, aInstr) != allocator.getRegisterForValue(b, bInstr)) {
+ if (allocator.getRegisterForValue(a, aInstrNumber) !=
+ allocator.getRegisterForValue(b, bInstrNumber)) {
return false;
}
} else {
@@ -327,7 +352,7 @@
if (other.outValue == null) {
return false;
}
- if (!identicalAfterRegisterAllocation(
+ if (!identicalOutputAfterRegisterAllocation(
outValue, getNumber(), other.outValue, other.getNumber(), allocator)) {
return false;
}
@@ -341,7 +366,8 @@
for (int j = 0; j < inValues.size(); j++) {
Value in0 = inValues.get(j);
Value in1 = other.inValues.get(j);
- if (!identicalAfterRegisterAllocation(in0, getNumber(), in1, other.getNumber(), allocator)) {
+ if (!identicalInputAfterRegisterAllocation(in0, getNumber(), other, in1, other.getNumber(),
+ allocator)) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java b/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
index 5b19aab..efd0fc9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/LogicalBinop.java
@@ -90,7 +90,7 @@
default:
throw new Unreachable("Unexpected type " + type);
}
- } else if (!rightValue().needsRegister()) {
+ } else if (!needsValueInRegister(rightValue())) {
assert fitsInDexInstruction(rightValue());
ConstNumber right = rightValue().getConstInstruction().asConstNumber();
if (right.is8Bit()) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Sub.java b/src/main/java/com/android/tools/r8/ir/code/Sub.java
index 4bf7e66..aca0df8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Sub.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Sub.java
@@ -128,11 +128,11 @@
// This is overridden to give the correct value when adding the negative constant.
@Override
int maxInOutValueRegisterSize() {
- if (!leftValue().needsRegister()) {
+ if (!needsValueInRegister(leftValue())) {
assert fitsInDexInstruction(leftValue());
ConstNumber left = leftValue().getConstInstruction().asConstNumber();
return left.is8Bit() ? Constants.U8BIT_MAX : Constants.U4BIT_MAX;
- } else if (!rightValue().needsRegister()) {
+ } else if (!needsValueInRegister(rightValue())) {
assert negativeFitsInDexInstruction(rightValue());
ConstNumber right = rightValue().getConstInstruction().asConstNumber();
return right.negativeIs8Bit() ? Constants.U8BIT_MAX : Constants.U4BIT_MAX;
@@ -167,7 +167,7 @@
}
com.android.tools.r8.code.Instruction instruction = null;
- if (!leftValue().needsRegister()) {
+ if (!needsValueInRegister(leftValue())) {
// Sub instructions with small left constant is emitted as rsub.
assert fitsInDexInstruction(leftValue());
ConstNumber left = leftValue().getConstInstruction().asConstNumber();
@@ -179,11 +179,11 @@
assert left.is16Bit();
instruction = new RsubInt(dest, right, left.getIntValue());
}
- } else if (!rightValue().needsRegister()) {
+ } else if (!needsValueInRegister(rightValue())) {
// Sub instructions with small right constant are emitted as add of the negative constant.
assert negativeFitsInDexInstruction(rightValue());
int dest = builder.allocatedRegister(outValue, getNumber());
- assert leftValue().needsRegister();
+ assert needsValueInRegister(leftValue());
int left = builder.allocatedRegister(leftValue(), getNumber());
ConstNumber right = rightValue().getConstInstruction().asConstNumber();
if (right.negativeIs8Bit()) {