# HG changeset patch # User Gilles Duboscq # Date 1346771442 -7200 # Node ID 7ac010ae8c977b336faa25eb904933dbc3c7d329 # Parent f70b0935485ba6c0eef8d5d7e00f79f060aef1d1 Add inferStamp for a number of ConvertNode's operations diff -r f70b0935485b -r 7ac010ae8c97 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- 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: diff -r f70b0935485b -r 7ac010ae8c97 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- 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); } diff -r f70b0935485b -r 7ac010ae8c97 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- 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()))); } diff -r f70b0935485b -r 7ac010ae8c97 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java --- 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(); } } diff -r f70b0935485b -r 7ac010ae8c97 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- 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; + } }