changeset 6313:7ac010ae8c97

Add inferStamp for a number of ConvertNode's operations
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 04 Sep 2012 17:10:42 +0200
parents f70b0935485b
children 3aaf213e730e 8886fdfde36c
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
diffstat 5 files changed, 88 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Tue Sep 04 17:09:46 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Tue Sep 04 17:10:42 2012 +0200
@@ -445,7 +445,6 @@
             case Byte:
                 return 8;
             case Char:
-                return 16;
             case Short:
                 return 16;
             case Jsr:
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Sep 04 17:09:46 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Sep 04 17:10:42 2012 +0200
@@ -42,10 +42,10 @@
     public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) {
         int header = arrayBaseOffset(baseKind);
         int elementSize = arrayIndexScale(baseKind);
-        long byteLength = length * elementSize;
+        long byteLength = (long) length * elementSize;
         long nonVectorBytes = byteLength % VECTOR_SIZE;
-        long srcOffset = srcPos * elementSize;
-        long destOffset = destPos * elementSize;
+        long srcOffset = (long) srcPos * elementSize;
+        long destOffset = (long) destPos * elementSize;
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) {
                 UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
@@ -131,9 +131,9 @@
         }
         Kind baseKind = Kind.Long;
         int header = arrayBaseOffset(baseKind);
-        long byteLength = length * arrayIndexScale(baseKind);
-        long srcOffset = srcPos * arrayIndexScale(baseKind);
-        long destOffset = destPos * arrayIndexScale(baseKind);
+        long byteLength = (long) length * arrayIndexScale(baseKind);
+        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
+        long destOffset = (long) destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -157,9 +157,9 @@
         }
         Kind baseKind = Kind.Double;
         int header = arrayBaseOffset(baseKind);
-        long byteLength = length * arrayIndexScale(baseKind);
-        long srcOffset = srcPos * arrayIndexScale(baseKind);
-        long destOffset = destPos * arrayIndexScale(baseKind);
+        long byteLength = (long) length * arrayIndexScale(baseKind);
+        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
+        long destOffset = (long) destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -185,12 +185,14 @@
         final int scale = arrayIndexScale(Kind.Object);
         int header = arrayBaseOffset(Kind.Object);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = (length - 1) * scale; i >= 0; i -= scale) {
+            long start = (long) (length - 1) * scale;
+            for (long i = start; i >= 0; i -= scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
             }
         } else {
-            for (long i = 0; i < length * scale; i += scale) {
+            long end = (long) length * scale;
+            for (long i = 0; i < end; i += scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Tue Sep 04 17:09:46 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Tue Sep 04 17:10:42 2012 +0200
@@ -114,6 +114,20 @@
     }
 
     @Override
+    public boolean inferStamp() {
+        Stamp newStamp;
+        switch (opcode) {
+            case I2L: newStamp = StampTool.intToLong(value().integerStamp()); break;
+            case L2I: newStamp = StampTool.longToInt(value().integerStamp()); break;
+            case I2B: newStamp = StampTool.intToByte(value().integerStamp()); break;
+            case I2C: newStamp = StampTool.intToChar(value().integerStamp()); break;
+            case I2S: newStamp = StampTool.intToShort(value().integerStamp()); break;
+            default: return false;
+        }
+        return updateStamp(newStamp);
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.setResult(this, gen.emitConvert(opcode, gen.operand(value())));
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Tue Sep 04 17:09:46 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Tue Sep 04 17:10:42 2012 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.type;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -184,10 +185,15 @@
     }
 
     public static long defaultMask(Kind kind) {
-        if (kind == Kind.Int) {
-            return 0xFFFFFFFFL;
-        } else {
-            return 0xFFFFFFFFFFFFFFFFL;
+        switch (kind) {
+            case Boolean: return 0x01L;
+            case Byte: return 0xffL;
+            case Char: return 0xffffL;
+            case Short: return 0xffffL;
+            case Jsr:
+            case Int: return 0xffffffffL;
+            case Long: return 0xffffffffffffffffL;
+            default: throw GraalInternalError.shouldNotReachHere();
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Sep 04 17:09:46 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Sep 04 17:10:42 2012 +0200
@@ -165,4 +165,55 @@
         }
         return StampFactory.forKind(kind);
     }
+
+    public static Stamp intToLong(IntegerStamp intStamp) {
+        long mask;
+        if (intStamp.isPositive()) {
+            mask = intStamp.mask();
+        } else {
+            mask = 0xffffffff00000000L | intStamp.mask();
+        }
+        return StampFactory.forInteger(Kind.Long, intStamp.lowerBound(), intStamp.upperBound(), mask);
+    }
+
+    private static Stamp narrowingKindConvertion(IntegerStamp fromStamp, Kind toKind) {
+        long mask = fromStamp.mask() & IntegerStamp.defaultMask(toKind);
+        long lowerBound = saturate(fromStamp.lowerBound(), toKind);
+        long upperBound = saturate(fromStamp.upperBound(), toKind);
+        if (fromStamp.lowerBound() < toKind.minValue()) {
+            upperBound = toKind.maxValue();
+        }
+        if (fromStamp.upperBound() > toKind.maxValue()) {
+            lowerBound = toKind.minValue();
+        }
+        return StampFactory.forInteger(toKind.stackKind(), lowerBound, upperBound, mask);
+    }
+
+    public static Stamp intToByte(IntegerStamp intStamp) {
+        return narrowingKindConvertion(intStamp, Kind.Byte);
+    }
+
+    public static Stamp intToShort(IntegerStamp intStamp) {
+        return narrowingKindConvertion(intStamp, Kind.Short);
+    }
+
+    public static Stamp intToChar(IntegerStamp intStamp) {
+        return narrowingKindConvertion(intStamp, Kind.Char);
+    }
+
+    public static Stamp longToInt(IntegerStamp longStamp) {
+        return narrowingKindConvertion(longStamp, Kind.Int);
+    }
+
+    public static long saturate(long v, Kind kind) {
+        long max = kind.maxValue();
+        if (v > max) {
+            return max;
+        }
+        long min = kind.minValue();
+        if (v < min) {
+            return min;
+        }
+        return v;
+    }
 }