< 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 >