changeset 16585:0d3a4532a28c

better stamps for RightShiftNode
author Lukas Stadler <lukas.stadler@oracle.com>
date Wed, 23 Jul 2014 14:16:35 +0200
parents ab84673bedc2
children 4a8f255c8c8d
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
diffstat 2 files changed, 35 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Jul 23 13:56:02 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Jul 23 14:16:35 2014 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = ">>")
 public final class RightShiftNode extends ShiftNode {
@@ -38,6 +39,11 @@
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.rightShift(getX().stamp(), getY().stamp()));
+    }
+
+    @Override
     public Constant evalConst(Constant... inputs) {
         assert inputs.length == 2;
         if (getKind() == Kind.Int) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Jul 23 13:56:02 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Jul 23 14:16:35 2014 +0200
@@ -252,6 +252,29 @@
         return stampForMask(stamp1.getBits(), newDownMask, newUpMask);
     }
 
+    public static Stamp rightShift(Stamp value, Stamp shift) {
+        if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
+            return rightShift((IntegerStamp) value, (IntegerStamp) shift);
+        }
+        return value.illegal();
+    }
+
+    public static Stamp rightShift(IntegerStamp value, IntegerStamp shift) {
+        int bits = value.getBits();
+        if (shift.lowerBound() == shift.upperBound()) {
+            int extraBits = 64 - bits;
+            long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
+            long shiftCount = shift.lowerBound() & shiftMask;
+            long defaultMask = IntegerStamp.defaultMask(bits);
+            // shifting back and forth performs sign extension
+            long downMask = (value.downMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
+            long upMask = (value.upMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
+            return new IntegerStamp(bits, value.lowerBound() >> shiftCount, value.upperBound() >> shiftCount, downMask, upMask);
+        }
+        long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
+        return stampForMask(bits, 0, mask);
+    }
+
     public static Stamp unsignedRightShift(Stamp value, Stamp shift) {
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return unsignedRightShift((IntegerStamp) value, (IntegerStamp) shift);
@@ -264,19 +287,12 @@
         if (shift.lowerBound() == shift.upperBound()) {
             long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
             long shiftCount = shift.lowerBound() & shiftMask;
-            if (shiftCount != 0) {
-                long lowerBound;
-                long upperBound;
-                long downMask = value.downMask() >>> shiftCount;
-                long upMask = value.upMask() >>> shiftCount;
-                if (value.lowerBound() < 0) {
-                    lowerBound = downMask;
-                    upperBound = upMask;
-                } else {
-                    lowerBound = value.lowerBound() >>> shiftCount;
-                    upperBound = value.upperBound() >>> shiftCount;
-                }
-                return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
+            long downMask = value.downMask() >>> shiftCount;
+            long upMask = value.upMask() >>> shiftCount;
+            if (value.lowerBound() < 0) {
+                return new IntegerStamp(bits, downMask, upMask, downMask, upMask);
+            } else {
+                return new IntegerStamp(bits, value.lowerBound() >>> shiftCount, value.upperBound() >>> shiftCount, downMask, upMask);
             }
         }
         long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());