Mercurial > hg > graal-compiler
diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java @ 5689:1d3df3a16940
Canonicalize more Mul/Div to shifts
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Mon, 25 Jun 2012 12:18:55 +0200 |
parents | d71eb56d6bb0 |
children | 1ed726759f65 |
line wrap: on
line diff
--- 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;