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()) {