< 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 >