# HG changeset patch # User Gilles Duboscq # Date 1340619535 -7200 # Node ID 1d3df3a16940636a94a26c7a1221569f3f6a388f # Parent 9bb0ba9e8ba67581de42a1a1416a207a33c69ce3 Canonicalize more Mul/Div to shifts diff -r 9bb0ba9e8ba6 -r 1d3df3a16940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Mon Jun 25 12:17:58 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Mon Jun 25 12:18:55 2012 +0200 @@ -58,8 +58,33 @@ long c = y().asConstant().asLong(); if (c == 1) { return x(); - } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().integerStamp().lowerBound() >= 0) { - return graph().unique(new UnsignedRightShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(c), graph()))); + } + if (c == -1) { + return graph().unique(new NegateNode(x())); + } + long abs = Math.abs(c); + if (CodeUtil.isPowerOf2(abs)) { + ValueNode dividend = x(); + IntegerStamp stampX = x().integerStamp(); + int log2 = CodeUtil.log2(abs); + // no rounding if dividend is negative or if its low bits are always 0 + if (stampX.lowerBound() < 0 || (stampX.mask() & (abs - 1)) != 0) { + int bits; + if (kind().isInt()) { + bits = 32; + } else { + assert kind().isLong(); + bits = 64; + } + RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph()))); + UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(kind(), sign, ConstantNode.forInt(bits - log2, graph()))); + dividend = IntegerArithmeticNode.add(dividend, round); + } + RightShiftNode shift = graph().unique(new RightShiftNode(kind(), dividend, ConstantNode.forInt(log2, graph()))); + if (c < 0) { + return graph().unique(new NegateNode(shift)); + } + return shift; } } return this; diff -r 9bb0ba9e8ba6 -r 1d3df3a16940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Mon Jun 25 12:17:58 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Mon Jun 25 12:18:55 2012 +0200 @@ -55,8 +55,14 @@ if (c == 0) { return ConstantNode.defaultForKind(kind(), graph()); } - if (c > 0 && CodeUtil.isPowerOf2(c)) { - return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(c), graph()))); + long abs = Math.abs(c); + if (abs > 0 && CodeUtil.isPowerOf2(abs)) { + LeftShiftNode shift = graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(abs), graph()))); + if (c < 0) { + return graph().unique(new NegateNode(shift)); + } else { + return shift; + } } // canonicalize expressions like "(a * 1) * 2" return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());