Refactor normalization of commutative binops.
This is a refactoring to allow allocating binops without normalization
which is needed for the one-pass building of lightweight IR.
Bug: b/225838009
Change-Id: Iebc9cccab0801145dc678e4bf2836e0fed18db6b
diff --git a/src/main/java/com/android/tools/r8/ir/code/Add.java b/src/main/java/com/android/tools/r8/ir/code/Add.java
index dc8cb05..98e4cf2 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Add.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Add.java
@@ -19,7 +19,17 @@
public class Add extends ArithmeticBinop {
- public Add(NumericType type, Value dest, Value left, Value right) {
+ public static Add create(NumericType type, Value dest, Value left, Value right) {
+ Add add = createNonNormalized(type, dest, left, right);
+ add.normalizeArgumentsForCommutativeBinop();
+ return add;
+ }
+
+ public static Add createNonNormalized(NumericType type, Value dest, Value left, Value right) {
+ return new Add(type, dest, left, right);
+ }
+
+ private Add(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/And.java b/src/main/java/com/android/tools/r8/ir/code/And.java
index f7aac6c..d7cd98c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/And.java
+++ b/src/main/java/com/android/tools/r8/ir/code/And.java
@@ -16,7 +16,17 @@
public class And extends LogicalBinop {
- public And(NumericType type, Value dest, Value left, Value right) {
+ public static And create(NumericType type, Value dest, Value left, Value right) {
+ And and = new And(type, dest, left, right);
+ and.normalizeArgumentsForCommutativeBinop();
+ return and;
+ }
+
+ public static And createNonNormalized(NumericType type, Value dest, Value left, Value right) {
+ return new And(type, dest, left, right);
+ }
+
+ private And(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
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 f2aa7cf..92f7380 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
@@ -17,7 +17,7 @@
public abstract class ArithmeticBinop extends Binop {
- public ArithmeticBinop(NumericType type, Value dest, Value left, Value right) {
+ ArithmeticBinop(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Binop.java b/src/main/java/com/android/tools/r8/ir/code/Binop.java
index 613ff5b..1629cda 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Binop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Binop.java
@@ -20,15 +20,19 @@
protected final NumericType type;
- public Binop(NumericType type, Value dest, Value left, Value right) {
+ Binop(NumericType type, Value dest, Value left, Value right) {
super(dest);
this.type = type;
- if (isCommutative() && (!right.isConstNumber() && left.isConstNumber())) {
- addInValue(right);
- addInValue(left);
- } else {
- addInValue(left);
- addInValue(right);
+ addInValue(left);
+ addInValue(right);
+ }
+
+ public void normalizeArgumentsForCommutativeBinop() {
+ assert isCommutative();
+ if (isCommutative() && !rightValue().isConstNumber() && leftValue().isConstNumber()) {
+ Value tmp = inValues.get(0);
+ inValues.set(0, inValues.get(1));
+ inValues.set(1, tmp);
}
}
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 c9a1b03..cfc2ee7 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
@@ -16,7 +16,7 @@
public abstract class LogicalBinop extends Binop {
- public LogicalBinop(NumericType type, Value dest, Value left, Value right) {
+ LogicalBinop(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Mul.java b/src/main/java/com/android/tools/r8/ir/code/Mul.java
index ccddf6a..41e4b35 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Mul.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Mul.java
@@ -19,7 +19,17 @@
public class Mul extends ArithmeticBinop {
- public Mul(NumericType type, Value dest, Value left, Value right) {
+ public static Mul create(NumericType type, Value dest, Value left, Value right) {
+ Mul mul = new Mul(type, dest, left, right);
+ mul.normalizeArgumentsForCommutativeBinop();
+ return mul;
+ }
+
+ public static Mul createNonNormalized(NumericType type, Value dest, Value left, Value right) {
+ return new Mul(type, dest, left, right);
+ }
+
+ private Mul(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Or.java b/src/main/java/com/android/tools/r8/ir/code/Or.java
index 3fd1a77..f0ce553 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Or.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Or.java
@@ -15,7 +15,17 @@
public class Or extends LogicalBinop {
- public Or(NumericType type, Value dest, Value left, Value right) {
+ public static Or create(NumericType type, Value dest, Value left, Value right) {
+ Or or = new Or(type, dest, left, right);
+ or.normalizeArgumentsForCommutativeBinop();
+ return or;
+ }
+
+ public static Or createNonNormalized(NumericType type, Value dest, Value left, Value right) {
+ return new Or(type, dest, left, right);
+ }
+
+ private Or(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Xor.java b/src/main/java/com/android/tools/r8/ir/code/Xor.java
index 657374a..db92998 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Xor.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Xor.java
@@ -15,7 +15,17 @@
public class Xor extends LogicalBinop {
- public Xor(NumericType type, Value dest, Value left, Value right) {
+ public static Xor create(NumericType type, Value dest, Value left, Value right) {
+ Xor xor = new Xor(type, dest, left, right);
+ xor.normalizeArgumentsForCommutativeBinop();
+ return xor;
+ }
+
+ public static Xor createNonNormalized(NumericType type, Value dest, Value left, Value right) {
+ return new Xor(type, dest, left, right);
+ }
+
+ private Xor(NumericType type, Value dest, Value left, Value right) {
super(type, dest, left, right);
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 3dfe55f..81f5c14 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -321,7 +321,7 @@
// Replace Not with Xor.
it.replaceCurrentInstruction(
- new Xor(current.asNot().type, current.outValue(), inValue, constValue));
+ Xor.create(current.asNot().type, current.outValue(), inValue, constValue));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 779beba..e28dba3 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -1086,7 +1086,7 @@
Value in1 = readNumericRegister(left, type);
Value in2 = readNumericRegister(right, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Add instruction = new Add(type, out, in1, in2);
+ Add instruction = Add.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1096,7 +1096,7 @@
Value in1 = readNumericRegister(value, type);
Value in2 = readIntLiteral(constant);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Add instruction = new Add(type, out, in1, in2);
+ Add instruction = Add.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1106,7 +1106,7 @@
Value in1 = readNumericRegister(left, type);
Value in2 = readNumericRegister(right, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- And instruction = new And(type, out, in1, in2);
+ And instruction = And.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1116,7 +1116,7 @@
Value in1 = readNumericRegister(value, type);
Value in2 = readIntLiteral(constant);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- And instruction = new And(type, out, in1, in2);
+ And instruction = And.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1323,7 +1323,7 @@
Value in1 = readNumericRegister(left, type);
Value in2 = readNumericRegister(right, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Mul instruction = new Mul(type, out, in1, in2);
+ Mul instruction = Mul.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1333,7 +1333,7 @@
Value in1 = readNumericRegister(value, type);
Value in2 = readIntLiteral(constant);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Mul instruction = new Mul(type, out, in1, in2);
+ Mul instruction = Mul.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -1774,7 +1774,7 @@
instruction = new Not(type, out, in);
} else {
Value minusOne = readLiteral(ValueTypeConstraint.fromNumericType(type), -1);
- instruction = new Xor(type, out, in, minusOne);
+ instruction = Xor.create(type, out, in, minusOne);
}
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
@@ -1991,7 +1991,7 @@
Value in1 = readNumericRegister(left, type);
Value in2 = readNumericRegister(right, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Or instruction = new Or(type, out, in1, in2);
+ Or instruction = Or.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -2001,7 +2001,7 @@
Value in1 = readNumericRegister(value, type);
Value in2 = readIntLiteral(constant);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- Or instruction = new Or(type, out, in1, in2);
+ Or instruction = Or.create(type, out, in1, in2);
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
}
@@ -2077,7 +2077,7 @@
&& in2.getConstInstruction().asConstNumber().isIntegerNegativeOne(type)) {
instruction = new Not(type, out, in1);
} else {
- instruction = new Xor(type, out, in1, in2);
+ instruction = Xor.create(type, out, in1, in2);
}
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
@@ -2093,7 +2093,7 @@
} else {
Value in2 = readIntLiteral(constant);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
- instruction = new Xor(type, out, in1, in2);
+ instruction = Xor.create(type, out, in1, in2);
}
assert !instruction.instructionTypeCanThrow();
addInstruction(instruction);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 9f985e9..692eeee 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -3567,8 +3567,8 @@
phiBlock.getInstructions().add(insertIndex++, cstToUse);
}
phi.replaceUsers(newOutValue);
- Instruction newInstruction = new Xor(NumericType.INT, newOutValue, testValue,
- cstToUse.outValue());
+ Instruction newInstruction =
+ Xor.create(NumericType.INT, newOutValue, testValue, cstToUse.outValue());
newInstruction.setBlock(phiBlock);
// The xor is replacing a phi so it does not have an actual position.
newInstruction.setPosition(phiPosition);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
index ef163ad..3b0caa2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
@@ -300,10 +300,10 @@
Instruction newInstruction = null;
switch (type) {
case ADD:
- newInstruction = new Add(numericType, outValue, inValues.get(0), inValues.get(1));
+ newInstruction = Add.create(numericType, outValue, inValues.get(0), inValues.get(1));
break;
case MUL:
- newInstruction = new Mul(numericType, outValue, inValues.get(0), inValues.get(1));
+ newInstruction = Mul.create(numericType, outValue, inValues.get(0), inValues.get(1));
break;
case SUB:
newInstruction = new Sub(numericType, outValue, inValues.get(0), inValues.get(1));
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 70c442b..4eea25d 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -344,7 +344,8 @@
@Override
public void onAdd(NumericType type, EV leftValueIndex, EV rightValueIndex) {
Value dest = getOutValueForNextInstruction(TypeElement.getInt());
- addInstruction(new Add(type, dest, getValue(leftValueIndex), getValue(rightValueIndex)));
+ addInstruction(
+ Add.createNonNormalized(type, dest, getValue(leftValueIndex), getValue(rightValueIndex)));
}
@Override
@@ -356,7 +357,8 @@
@Override
public void onMul(NumericType type, EV leftValueIndex, EV rightValueIndex) {
Value dest = getOutValueForNextInstruction(TypeElement.getInt());
- addInstruction(new Mul(type, dest, getValue(leftValueIndex), getValue(rightValueIndex)));
+ addInstruction(
+ Mul.createNonNormalized(type, dest, getValue(leftValueIndex), getValue(rightValueIndex)));
}
@Override
diff --git a/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java b/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
index a376a2e..66adde9 100644
--- a/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
+++ b/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
@@ -380,7 +380,7 @@
newReturnBlock.iterator().next().asReturn().returnValue().replaceUsers(newReturnValue);
Instruction constInstruction = new ConstNumber(newConstValue, 10);
Instruction addInstruction =
- new Add(NumericType.INT, newReturnValue, oldReturnValue, newConstValue);
+ Add.create(NumericType.INT, newReturnValue, oldReturnValue, newConstValue);
iterator.previous();
iterator.add(constInstruction);
iterator.add(addInstruction);
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/IdenticalAfterRegisterAllocationTest.java b/src/test/java/com/android/tools/r8/ir/regalloc/IdenticalAfterRegisterAllocationTest.java
index 5db89dc..983dfdb 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/IdenticalAfterRegisterAllocationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/IdenticalAfterRegisterAllocationTest.java
@@ -110,9 +110,9 @@
Value value2 = new Value(2, TypeElement.getInt(), null);
ConstNumber const2 = new ConstNumber(value2, 2);
Value value3 = new Value(2, TypeElement.getInt(), null);
- Add add0 = new Add(NumericType.INT, value3, value0, value1);
+ Add add0 = Add.create(NumericType.INT, value3, value0, value1);
add0.setPosition(Position.none());
- Add add1 = new Add(NumericType.INT, value3, value0, value2);
+ Add add1 = Add.create(NumericType.INT, value3, value0, value2);
add1.setPosition(Position.none());
value0.computeNeedsRegister();
assertTrue(value0.needsRegister());