Mercurial > hg > graal-compiler
changeset 5785:e5f0cf5b5627
more sophisticated float stamp
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Fri, 06 Jul 2012 16:25:59 +0200 |
parents | 182d5b57967e |
children | f69a406355b2 |
files | graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.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/StampFactory.java |
diffstat | 3 files changed, 107 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Fri Jul 06 16:21:46 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Fri Jul 06 16:25:59 2012 +0200 @@ -27,25 +27,116 @@ public class FloatStamp extends Stamp { + private final double lowerBound; + private final double upperBound; + private final boolean nonNaN; + protected FloatStamp(Kind kind) { + this(kind, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false); + assert kind == Kind.Float || kind == Kind.Double; + } + + protected FloatStamp(Kind kind, double lowerBound, double upperBound, boolean nonNaN) { super(kind); - assert kind == Kind.Float || kind == Kind.Double; + assert lowerBound <= upperBound; + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.nonNaN = nonNaN; + } + + /** + * The (inclusive) lower bound on the value described by this stamp. + */ + public double lowerBound() { + return lowerBound; + } + + /** + * The (inclusive) upper bound on the value described by this stamp. + */ + public double upperBound() { + return upperBound; + } + + public boolean isUnrestricted() { + return lowerBound == Double.NEGATIVE_INFINITY && upperBound == Double.POSITIVE_INFINITY && !nonNaN; + } + + public boolean contains(double value) { + if (Double.isNaN(value)) { + return !nonNaN; + } else { + return value >= lowerBound && value <= upperBound; + } } @Override public String toString() { - return "" + kind().typeChar; + StringBuilder str = new StringBuilder(); + str.append(kind().typeChar); + str.append(nonNaN ? "!" : ""); + if (lowerBound == upperBound) { + str.append(" [").append(lowerBound).append(']'); + } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) { + str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']'); + } + return str.toString(); + } + + @Override + public boolean alwaysDistinct(Stamp otherStamp) { + FloatStamp other = (FloatStamp) otherStamp; + return (nonNaN || other.nonNaN) && (lowerBound > other.upperBound || upperBound < other.lowerBound); + } + + @Override + public Stamp meet(Stamp otherStamp) { + FloatStamp other = (FloatStamp) otherStamp; + assert kind() == other.kind(); + double meetUpperBound = Math.max(upperBound, other.upperBound); + double meetLowerBound = Math.min(lowerBound, other.lowerBound); + boolean meetNonNaN = nonNaN && other.nonNaN; + if (meetLowerBound == lowerBound && meetUpperBound == upperBound && meetNonNaN == nonNaN) { + return this; + } else if (meetLowerBound == other.lowerBound && meetUpperBound == other.upperBound && meetNonNaN == other.nonNaN) { + return other; + } else { + return new FloatStamp(kind(), meetLowerBound, meetUpperBound, meetNonNaN); + } } @Override - public boolean alwaysDistinct(Stamp other) { - return false; + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(lowerBound); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + (nonNaN ? 1231 : 1237); + temp = Double.doubleToLongBits(upperBound); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; } @Override - public Stamp meet(Stamp other) { - assert kind() == other.kind(); - return this; + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + FloatStamp other = (FloatStamp) obj; + if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) { + return false; + } + if (Double.doubleToLongBits(upperBound) != Double.doubleToLongBits(other.upperBound)) { + return false; + } + if (nonNaN != other.nonNaN) { + return false; + } + return true; } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Jul 06 16:21:46 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Jul 06 16:25:59 2012 +0200 @@ -111,6 +111,8 @@ long meetMask = mask | other.mask; if (meetLowerBound == lowerBound && meetUpperBound == upperBound && meetMask == mask) { return this; + } else if (meetLowerBound == other.lowerBound && meetUpperBound == other.upperBound && meetMask == other.mask) { + return other; } else { return new IntegerStamp(kind(), meetLowerBound, meetUpperBound, meetMask); } @@ -122,6 +124,7 @@ int result = 1; result = prime * result + (int) (lowerBound ^ (lowerBound >>> 32)); result = prime * result + (int) (upperBound ^ (upperBound >>> 32)); + result = prime * result + (int) (mask ^ (mask >>> 32)); return result; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Jul 06 16:21:46 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Jul 06 16:25:59 2012 +0200 @@ -102,6 +102,10 @@ return new IntegerStamp(kind, lowerBound, upperBound, mask); } + public static Stamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) { + return new FloatStamp(kind, lowerBound, upperBound, nonNaN); + } + public static Stamp forConstant(Constant value) { assert value.kind != Kind.Object; if (value.kind == Kind.Object) { @@ -109,6 +113,8 @@ } else { if (value.kind == Kind.Int || value.kind == Kind.Long) { return forInteger(value.kind, value.asLong(), value.asLong(), value.asLong() & IntegerStamp.defaultMask(value.kind)); + } else if (value.kind == Kind.Float || value.kind == Kind.Double) { + return forFloat(value.kind, value.asDouble(), value.asDouble(), true); } return forKind(value.kind.stackKind()); }