< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
Print this page
@@ -289,21 +289,83 @@
return super.equals(other);
}
@Override
public JavaConstant asConstant() {
- if (nonNaN && Double.compare(lowerBound, upperBound) == 0) {
+ if (isConstant()) {
switch (getBits()) {
case 32:
return JavaConstant.forFloat((float) lowerBound);
case 64:
return JavaConstant.forDouble(lowerBound);
}
}
return null;
}
+ private boolean isConstant() {
+ /*
+ * There are many forms of NaNs and any operations on them can silently convert them into
+ * the canonical NaN.
+ */
+ return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
+ }
+
+ private static FloatStamp stampForConstant(Constant constant) {
+ FloatStamp result;
+ PrimitiveConstant value = (PrimitiveConstant) constant;
+ switch (value.getJavaKind()) {
+ case Float:
+ if (Float.isNaN(value.asFloat())) {
+ result = new FloatStamp(32, Double.NaN, Double.NaN, false);
+ } else {
+ result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+ }
+ break;
+ case Double:
+ if (Double.isNaN(value.asDouble())) {
+ result = new FloatStamp(64, Double.NaN, Double.NaN, false);
+ } else {
+ result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+ }
+ break;
+ default:
+ throw GraalError.shouldNotReachHere();
+ }
+ if (result.isConstant()) {
+ return result;
+ }
+ return null;
+ }
+
+ private static Stamp maybeFoldConstant(UnaryOp<?> op, FloatStamp stamp) {
+ if (stamp.isConstant()) {
+ JavaConstant constant = stamp.asConstant();
+ Constant folded = op.foldConstant(constant);
+ if (folded != null) {
+ return FloatStamp.stampForConstant(folded);
+ }
+ }
+ return null;
+ }
+
+ private static Stamp maybeFoldConstant(BinaryOp<?> op, FloatStamp stamp1, FloatStamp stamp2) {
+ if (stamp1.isConstant() && stamp2.isConstant()) {
+ JavaConstant constant1 = stamp1.asConstant();
+ JavaConstant constant2 = stamp2.asConstant();
+ Constant folded = op.foldConstant(constant1, constant2);
+ if (folded != null) {
+ FloatStamp stamp = stampForConstant(folded);
+ if (stamp != null && stamp.isConstant()) {
+ assert stamp.asConstant().equals(folded);
+ return stamp;
+ }
+ }
+ }
+ return null;
+ }
+
public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
new UnaryOp.Neg() {
@Override
@@ -320,12 +382,17 @@
}
@Override
public Stamp foldStamp(Stamp s) {
FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
}
+
},
new BinaryOp.Add(false, true) {
@Override
@@ -342,12 +409,17 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant value) {
@@ -379,12 +451,17 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant value) {
@@ -416,13 +493,18 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp a, Stamp b) {
- // TODO
- return a.unrestricted();
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
+ return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant value) {
PrimitiveConstant n = (PrimitiveConstant) value;
@@ -448,21 +530,28 @@
PrimitiveConstant a = (PrimitiveConstant) const1;
PrimitiveConstant b = (PrimitiveConstant) const2;
assert a.getJavaKind() == b.getJavaKind();
switch (a.getJavaKind()) {
case Float:
- return JavaConstant.forFloat(a.asFloat() / b.asFloat());
+ float floatDivisor = b.asFloat();
+ return (floatDivisor == 0) ? null : JavaConstant.forFloat(a.asFloat() / floatDivisor);
case Double:
- return JavaConstant.forDouble(a.asDouble() / b.asDouble());
+ double doubleDivisor = b.asDouble();
+ return (doubleDivisor == 0) ? null : JavaConstant.forDouble(a.asDouble() / doubleDivisor);
default:
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant value) {
@@ -494,12 +583,17 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
- // TODO
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
},
new UnaryOp.Not() {
@@ -519,10 +613,21 @@
}
}
@Override
public Stamp foldStamp(Stamp s) {
+ FloatStamp stamp = (FloatStamp) s;
+ JavaConstant constant = stamp.asConstant();
+ if (constant != null) {
+ Constant folded = foldConstant(constant);
+ if (folded != null) {
+ FloatStamp result = stampForConstant(folded);
+ if (result != null && result.isConstant()) {
+ return result;
+ }
+ }
+ }
return s.unrestricted();
}
},
new BinaryOp.And(true, true) {
@@ -545,11 +650,17 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant n) {
@@ -574,22 +685,30 @@
assert a.getJavaKind() == b.getJavaKind();
switch (a.getJavaKind()) {
case Float:
int fa = Float.floatToRawIntBits(a.asFloat());
int fb = Float.floatToRawIntBits(b.asFloat());
- return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb));
+ float floatOr = Float.intBitsToFloat(fa | fb);
+ assert (fa | fb) == Float.floatToRawIntBits((floatOr));
+ return JavaConstant.forFloat(floatOr);
case Double:
long da = Double.doubleToRawLongBits(a.asDouble());
long db = Double.doubleToRawLongBits(b.asDouble());
return JavaConstant.forDouble(Double.longBitsToDouble(da | db));
default:
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant n) {
@@ -625,11 +744,17 @@
throw GraalError.shouldNotReachHere();
}
}
@Override
- public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ public Stamp foldStamp(Stamp s1, Stamp s2) {
+ FloatStamp stamp1 = (FloatStamp) s1;
+ FloatStamp stamp2 = (FloatStamp) s2;
+ Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+ if (folded != null) {
+ return folded;
+ }
return stamp1.unrestricted();
}
@Override
public boolean isNeutral(Constant n) {
@@ -663,10 +788,14 @@
}
@Override
public Stamp foldStamp(Stamp s) {
FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
if (stamp.isNaN()) {
return stamp;
}
return new FloatStamp(stamp.getBits(), 0, Math.max(-stamp.lowerBound(), stamp.upperBound()), stamp.isNonNaN());
}
@@ -687,10 +816,15 @@
}
}
@Override
public Stamp foldStamp(Stamp s) {
+ FloatStamp stamp = (FloatStamp) s;
+ Stamp folded = maybeFoldConstant(this, stamp);
+ if (folded != null) {
+ return folded;
+ }
return s.unrestricted();
}
},
null, null, null,
< prev index next >