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;