changeset 15791:308cedd2aaa2

better stamps for IntegerRemNode
author Lukas Stadler <lukas.stadler@oracle.com>
date Tue, 20 May 2014 16:17:16 +0200
parents c74c34976c47
children 401edc9ef521
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
diffstat 2 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Tue May 20 15:28:53 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Tue May 20 16:17:16 2014 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "%")
 public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable {
@@ -37,6 +38,11 @@
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.rem(x().stamp(), y().stamp()));
+    }
+
+    @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long y = y().asConstant().asLong();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue May 20 15:28:53 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue May 20 16:17:16 2014 +0200
@@ -105,6 +105,37 @@
         return stamp1.unrestricted();
     }
 
+    public static Stamp rem(Stamp stamp1, Stamp stamp2) {
+        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
+            return rem((IntegerStamp) stamp1, (IntegerStamp) stamp2);
+        }
+        return StampFactory.illegal();
+    }
+
+    public static Stamp rem(IntegerStamp stamp1, IntegerStamp stamp2) {
+        assert stamp1.getBits() == stamp2.getBits();
+        long magnitude; // the maximum absolute value of the result
+        if (stamp2.lowerBound() == IntegerStamp.defaultMinValue(stamp2.getBits())) {
+            // Math.abs(...) - 1 does not work in this case
+            magnitude = IntegerStamp.defaultMaxValue(stamp2.getBits());
+        } else {
+            magnitude = Math.max(Math.abs(stamp2.lowerBound()), Math.abs(stamp2.upperBound())) - 1;
+        }
+        long lowerBound = Math.max(stamp1.lowerBound(), -magnitude);
+        if (stamp1.upperBound() > magnitude) {
+            // if the result can wrap around at the upper bound, it can reach any value between 0
+            // and magnitude
+            lowerBound = Math.min(lowerBound, 0);
+        }
+        long upperBound = Math.min(stamp1.upperBound(), magnitude);
+        if (stamp1.lowerBound() < -magnitude) {
+            // if the result can wrap around at the lower bound, it can reach any value between
+            // -magnitude and 0
+            upperBound = Math.max(upperBound, 0);
+        }
+        return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
+    }
+
     private static boolean addOverflowsPositively(long x, long y, int bits) {
         long result = x + y;
         if (bits == 64) {