< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java
Print this page
@@ -61,33 +61,13 @@
return this; // this will trap, can not canonicalize
}
return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
} else if (forY.isConstant()) {
long c = forY.asJavaConstant().asLong();
- if (c == 1) {
- return forX;
- }
- if (c == -1) {
- return NegateNode.create(forX);
- }
- long abs = Math.abs(c);
- if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
- ValueNode dividend = forX;
- IntegerStamp stampX = (IntegerStamp) forX.stamp();
- int log2 = CodeUtil.log2(abs);
- // no rounding if dividend is positive or if its low bits are always 0
- if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
- int bits = PrimitiveStamp.getBits(stamp());
- RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
- UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
- dividend = BinaryArithmeticNode.add(dividend, round);
- }
- RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
- if (c < 0) {
- return NegateNode.create(shift);
- }
- return shift;
+ ValueNode v = canonical(forX, c);
+ if (v != null) {
+ return v;
}
}
// Convert the expression ((a - a % b) / b) into (a / b).
if (forX instanceof SubNode) {
@@ -111,10 +91,38 @@
}
return this;
}
+ public static ValueNode canonical(ValueNode forX, long c) {
+ if (c == 1) {
+ return forX;
+ }
+ if (c == -1) {
+ return NegateNode.create(forX);
+ }
+ long abs = Math.abs(c);
+ if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+ ValueNode dividend = forX;
+ IntegerStamp stampX = (IntegerStamp) forX.stamp();
+ int log2 = CodeUtil.log2(abs);
+ // no rounding if dividend is positive or if its low bits are always 0
+ if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
+ int bits = PrimitiveStamp.getBits(forX.stamp());
+ RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
+ UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
+ dividend = BinaryArithmeticNode.add(dividend, round);
+ }
+ RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
+ if (c < 0) {
+ return NegateNode.create(shift);
+ }
+ return shift;
+ }
+ return null;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this)));
}
}
< prev index next >