< 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,93 ****
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;
}
}
// Convert the expression ((a - a % b) / b) into (a / b).
if (forX instanceof SubNode) {
--- 61,73 ----
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();
! 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,120 ****
--- 91,128 ----
}
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 >