< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ShortCircuitOrNode.java

Print this page
rev 52509 : [mq]: graal2

*** 26,44 **** --- 26,51 ---- import static org.graalvm.compiler.nodeinfo.InputType.Condition; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; + import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.compiler.core.common.type.IntegerStamp; + import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.IterableNodeType; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.NodeInfo; + import org.graalvm.compiler.nodes.calc.CompareNode; import org.graalvm.compiler.nodes.calc.IntegerBelowNode; import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; + import org.graalvm.compiler.options.OptionValues; + import jdk.vm.ci.meta.Assumptions; + import jdk.vm.ci.meta.ConstantReflectionProvider; + import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.TriState; @NodeInfo(cycles = CYCLES_0, size = SIZE_0) public final class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable.Binary<LogicNode> { public static final NodeClass<ShortCircuitOrNode> TYPE = NodeClass.create(ShortCircuitOrNode.class);
*** 55,64 **** --- 62,75 ---- this.y = y; this.yNegated = yNegated; this.shortCircuitProbability = shortCircuitProbability; } + public static LogicNode create(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { + return new ShortCircuitOrNode(x, xNegated, y, yNegated, shortCircuitProbability); + } + @Override public LogicNode getX() { return x; }
*** 109,118 **** --- 120,130 ---- public LogicNode canonical(CanonicalizerTool tool, LogicNode forX, LogicNode forY) { ShortCircuitOrNode ret = canonicalizeNegation(forX, forY); if (ret != this) { return ret; } + NodeView view = NodeView.from(tool); if (forX == forY) { // @formatter:off // a || a = a // a || !a = true
*** 201,211 **** if (forX instanceof IntegerBelowNode && forY instanceof IntegerLessThanNode && !isXNegated() && !isYNegated()) { IntegerBelowNode xNode = (IntegerBelowNode) forX; IntegerLessThanNode yNode = (IntegerLessThanNode) forY; ValueNode xxNode = xNode.getX(); // X >= 0 ValueNode yxNode = yNode.getX(); // X >= 0 ! if (xxNode == yxNode && ((IntegerStamp) xxNode.stamp(NodeView.DEFAULT)).isPositive()) { ValueNode xyNode = xNode.getY(); // u ValueNode yyNode = yNode.getY(); // u if (xyNode == yyNode) { return forX; } --- 213,223 ---- if (forX instanceof IntegerBelowNode && forY instanceof IntegerLessThanNode && !isXNegated() && !isYNegated()) { IntegerBelowNode xNode = (IntegerBelowNode) forX; IntegerLessThanNode yNode = (IntegerLessThanNode) forY; ValueNode xxNode = xNode.getX(); // X >= 0 ValueNode yxNode = yNode.getX(); // X >= 0 ! if (xxNode == yxNode && ((IntegerStamp) xxNode.stamp(view)).isPositive()) { ValueNode xyNode = xNode.getY(); // u ValueNode yyNode = yNode.getY(); // u if (xyNode == yyNode) { return forX; }
*** 224,236 **** --- 236,331 ---- return new ShortCircuitOrNode(sym, isXNegated(), yNode.getY(), yNode.isYNegated(), p1 + (1 - p1) * p2); } } } + if (forX instanceof CompareNode && forY instanceof CompareNode) { + CompareNode xCompare = (CompareNode) forX; + CompareNode yCompare = (CompareNode) forY; + + if (xCompare.getX() == yCompare.getX() || xCompare.getX() == yCompare.getY()) { + + Stamp succeedingStampX = xCompare.getSucceedingStampForX(!xNegated, xCompare.getX().stamp(view), xCompare.getY().stamp(view)); + // Try to canonicalize the other comparison using the knowledge gained from assuming + // the first part of the short circuit or is false (which is the only relevant case + // for the second part of the short circuit or). + if (succeedingStampX != null && !succeedingStampX.isUnrestricted()) { + CanonicalizerTool proxyTool = new ProxyCanonicalizerTool(succeedingStampX, xCompare.getX(), tool, view); + ValueNode result = yCompare.canonical(proxyTool); + if (result != yCompare) { + return ShortCircuitOrNode.create(forX, xNegated, (LogicNode) result, yNegated, this.shortCircuitProbability); + } + } + } + } + return this; } + private static class ProxyCanonicalizerTool implements CanonicalizerTool, NodeView { + + private final Stamp stamp; + private final ValueNode node; + private final CanonicalizerTool tool; + private final NodeView view; + + ProxyCanonicalizerTool(Stamp stamp, ValueNode node, CanonicalizerTool tool, NodeView view) { + this.stamp = stamp; + this.node = node; + this.tool = tool; + this.view = view; + } + + @Override + public Stamp stamp(ValueNode n) { + if (n == node) { + return stamp; + } + return view.stamp(n); + } + + @Override + public Assumptions getAssumptions() { + return tool.getAssumptions(); + } + + @Override + public MetaAccessProvider getMetaAccess() { + return tool.getMetaAccess(); + } + + @Override + public ConstantReflectionProvider getConstantReflection() { + return tool.getConstantReflection(); + } + + @Override + public ConstantFieldProvider getConstantFieldProvider() { + return tool.getConstantFieldProvider(); + } + + @Override + public boolean canonicalizeReads() { + return tool.canonicalizeReads(); + } + + @Override + public boolean allUsagesAvailable() { + return tool.allUsagesAvailable(); + } + + @Override + public Integer smallestCompareWidth() { + return tool.smallestCompareWidth(); + } + + @Override + public OptionValues getOptions() { + return tool.getOptions(); + } + } + private static LogicNode simplifyComparison(LogicNode forX, LogicNode forY) { LogicNode sym = simplifyComparisonOrdered(forX, forY); if (sym == null) { return simplifyComparisonOrdered(forY, forX); }
< prev index next >