--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Wed Apr 05 22:48:35 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java Thu Apr 06 14:31:32 2017 -0700
@@ -28,13 +28,13 @@
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.LogicConstantNode;
import org.graalvm.compiler.nodes.LogicNegationNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.util.GraphUtil;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.TriState;
/**
@@ -65,51 +65,9 @@
if (synonym != null) {
return synonym;
}
- if (forY.stamp() instanceof IntegerStamp) {
- IntegerStamp yStamp = (IntegerStamp) forY.stamp();
- if (forX.isConstant() && forX.asJavaConstant().asLong() == getOp().minValue(yStamp.getBits())) {
- // MIN < y is the same as y != MIN
- return LogicNegationNode.create(CompareNode.createCompareNode(Condition.EQ, forY, forX, tool.getConstantReflection()));
- }
- if (forY instanceof AddNode) {
- AddNode addNode = (AddNode) forY;
- ValueNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
- if (canonical != null) {
- return canonical;
- }
- }
- if (forX instanceof AddNode) {
- AddNode addNode = (AddNode) forX;
- ValueNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
- if (canonical != null) {
- return canonical;
- }
- }
- }
return this;
}
- private ValueNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean negated, boolean strict) {
- // x < x + a
- Stamp succeedingXStamp;
- if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
- succeedingXStamp = getOp().getSucceedingStampForXLowerXPlusA(negated, strict, (IntegerStamp) addNode.getY().stamp());
- } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
- succeedingXStamp = getOp().getSucceedingStampForXLowerXPlusA(negated, strict, (IntegerStamp) addNode.getX().stamp());
- } else {
- return null;
- }
- succeedingXStamp = forX.stamp().join(succeedingXStamp);
- if (succeedingXStamp.isEmpty()) {
- return LogicConstantNode.contradiction();
- }
- /*
- * since getSucceedingStampForXLowerXPlusA is only best effort,
- * succeedingXStamp.equals(xStamp) does not imply tautology
- */
- return null;
- }
-
@Override
public Stamp getSucceedingStampForX(boolean negated, Stamp xStampGeneric, Stamp yStampGeneric) {
return getSucceedingStampForX(negated, !negated, xStampGeneric, yStampGeneric, getX(), getY());
@@ -196,10 +154,10 @@
protected abstract Condition getCondition();
- protected abstract IntegerLowerThanNode create(ValueNode x, ValueNode y);
+ protected abstract IntegerLowerThanNode createNode(ValueNode x, ValueNode y);
- public LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
- LogicNode result = CompareNode.tryConstantFold(getCondition(), x, y, constantReflection, false);
+ public LogicNode create(ValueNode x, ValueNode y) {
+ LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false);
if (result != null) {
return result;
} else {
@@ -207,7 +165,7 @@
if (result != null) {
return result;
}
- return create(x, y);
+ return createNode(x, y);
}
}
@@ -221,6 +179,73 @@
} else if (fold.isFalse()) {
return LogicConstantNode.contradiction();
}
+ if (forY.stamp() instanceof IntegerStamp) {
+ IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+ int bits = yStamp.getBits();
+ if (forX.isJavaConstant() && !forY.isConstant()) {
+ // bring the constant on the right
+ long xValue = forX.asJavaConstant().asLong();
+ if (xValue != maxValue(bits)) {
+ // c < x <=> !(c >= x) <=> !(x <= c) <=> !(x < c + 1)
+ return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1)));
+ }
+ }
+ if (forY.isJavaConstant()) {
+ long yValue = forY.asJavaConstant().asLong();
+ if (yValue == maxValue(bits)) {
+ // x < MAX <=> x != MAX
+ return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY));
+ }
+ if (yValue == minValue(bits) + 1) {
+ // x < MIN + 1 <=> x <= MIN <=> x == MIN
+ return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)));
+ }
+ } else if (forY instanceof AddNode) {
+ AddNode addNode = (AddNode) forY;
+ LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
+ if (canonical != null) {
+ return canonical;
+ }
+ }
+ if (forX instanceof AddNode) {
+ AddNode addNode = (AddNode) forX;
+ LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
+ if (canonical != null) {
+ return canonical;
+ }
+ }
+ }
+ return null;
+ }
+
+ private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict) {
+ // x < x + a
+ IntegerStamp succeedingXStamp;
+ boolean exact;
+ if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
+ IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp();
+ succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
+ exact = aStamp.lowerBound() == aStamp.upperBound();
+ } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
+ IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp();
+ succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
+ exact = aStamp.lowerBound() == aStamp.upperBound();
+ } else {
+ return null;
+ }
+ if (succeedingXStamp.join(forX.stamp()).isEmpty()) {
+ return LogicConstantNode.contradiction();
+ } else if (exact && !succeedingXStamp.isEmpty()) {
+ int bits = succeedingXStamp.getBits();
+ if (compare(lowerBound(succeedingXStamp), minValue(bits)) > 0) {
+ assert upperBound(succeedingXStamp) == maxValue(bits);
+ // x must be in [L..MAX] <=> x >= L <=> !(x < L)
+ return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp))));
+ } else if (compare(upperBound(succeedingXStamp), maxValue(bits)) < 0) {
+ // x must be in [MIN..H] <=> x <= H <=> !(H < x)
+ return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX));
+ }
+ }
return null;
}
@@ -268,7 +293,7 @@
return null;
}
- protected IntegerStamp getSucceedingStampForXLowerXPlusA(boolean negated, boolean strict, IntegerStamp a) {
+ protected IntegerStamp getSucceedingStampForXLowerXPlusA(boolean mirrored, boolean strict, IntegerStamp a) {
int bits = a.getBits();
long min = minValue(bits);
long max = maxValue(bits);
@@ -286,7 +311,7 @@
* This does not use upper/lowerBound from LowerOp because it's about the (signed)
* addition not the comparison.
*/
- if (negated) {
+ if (mirrored) {
if (a.contains(0)) {
// a may be zero
return a.unrestricted();