--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java Thu Oct 31 16:54:16 2019 -0700
@@ -27,7 +27,7 @@
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Or;
-import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
@@ -40,9 +40,7 @@
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
-import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.PrimitiveConstant;
@NodeInfo(shortName = "|")
public final class OrNode extends BinaryArithmeticNode<Or> implements BinaryCommutative<ValueNode>, NarrowableArithmeticNode {
@@ -53,6 +51,18 @@
super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
}
+ private OrNode(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ super(TYPE, forcedStamp, x, y);
+ }
+
+ /**
+ * Create a new XorNode with a forced stamp, without eager folding. This should only be used in
+ * snippet code, where native-image may assign wrong stamps during graph generation.
+ */
+ public static ValueNode createForSnippet(ValueNode x, ValueNode y, Stamp forcedStamp) {
+ return new OrNode(x, y, forcedStamp);
+ }
+
public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
@@ -60,7 +70,7 @@
if (tryConstantFold != null) {
return tryConstantFold;
}
- return canonical(null, op, stamp, x, y, view);
+ return canonical(null, op, x, y, view);
}
@Override
@@ -76,34 +86,42 @@
return ret;
}
- return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
+ return canonical(this, getOp(forX, forY), forX, forY, view);
}
- private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
+ private static ValueNode canonical(OrNode self, BinaryOp<Or> op, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return forX;
}
if (forX.isConstant() && !forY.isConstant()) {
return new OrNode(forY, forX);
}
+
+ Stamp rawXStamp = forX.stamp(view);
+ Stamp rawYStamp = forY.stamp(view);
+ if (rawXStamp instanceof IntegerStamp && rawYStamp instanceof IntegerStamp) {
+ IntegerStamp xStamp = (IntegerStamp) rawXStamp;
+ IntegerStamp yStamp = (IntegerStamp) rawYStamp;
+ if (((~xStamp.downMask()) & yStamp.upMask()) == 0) {
+ return forX;
+ } else if (((~yStamp.downMask()) & xStamp.upMask()) == 0) {
+ return forY;
+ }
+ }
+
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
- if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
- long rawY = ((PrimitiveConstant) c).asLong();
- long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
- if ((rawY & mask) == mask) {
- return ConstantNode.forIntegerStamp(stamp, mask);
- }
- }
return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
}
+
if (forX instanceof NotNode && forY instanceof NotNode) {
return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
}
+
return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
}