# HG changeset patch # User Lukas Stadler # Date 1406117795 -7200 # Node ID 0d3a4532a28c8e9422a6130242d22a88ece6e904 # Parent ab84673bedc21c4d30f10f2135bb5610adf13db5 better stamps for RightShiftNode diff -r ab84673bedc2 -r 0d3a4532a28c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- 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) { diff -r ab84673bedc2 -r 0d3a4532a28c 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 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());