use of org.graalvm.compiler.nodes.spi.CanonicalizerTool in project graal by oracle.
the class ShortCircuitOrNode method canonical.
@Override
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:on
if (isXNegated()) {
if (isYNegated()) {
// !a || !a = !a
return LogicNegationNode.create(forX);
} else {
// !a || a = true
return LogicConstantNode.tautology();
}
} else {
if (isYNegated()) {
// a || !a = true
return LogicConstantNode.tautology();
} else {
// a || a = a
return forX;
}
}
}
if (forX instanceof LogicConstantNode) {
if (((LogicConstantNode) forX).getValue() ^ isXNegated()) {
return LogicConstantNode.tautology();
} else {
if (isYNegated()) {
return new LogicNegationNode(forY);
} else {
return forY;
}
}
}
if (forY instanceof LogicConstantNode) {
if (((LogicConstantNode) forY).getValue() ^ isYNegated()) {
return LogicConstantNode.tautology();
} else {
if (isXNegated()) {
return new LogicNegationNode(forX);
} else {
return forX;
}
}
}
if (forX instanceof ShortCircuitOrNode) {
ShortCircuitOrNode inner = (ShortCircuitOrNode) forX;
if (forY == inner.getX()) {
return optimizeShortCircuit(inner, this.xNegated, this.yNegated, true);
} else if (forY == inner.getY()) {
return optimizeShortCircuit(inner, this.xNegated, this.yNegated, false);
}
} else if (forY instanceof ShortCircuitOrNode) {
ShortCircuitOrNode inner = (ShortCircuitOrNode) forY;
if (inner.getX() == forX) {
return optimizeShortCircuit(inner, this.yNegated, this.xNegated, true);
} else if (inner.getY() == forX) {
return optimizeShortCircuit(inner, this.yNegated, this.xNegated, false);
}
}
// !X => Y constant
TriState impliedForY = forX.implies(!isXNegated(), forY);
if (impliedForY.isKnown()) {
boolean yResult = impliedForY.toBoolean() ^ isYNegated();
return yResult ? LogicConstantNode.tautology() : (isXNegated() ? LogicNegationNode.create(forX) : forX);
}
// u < 0 || X < u ==>> X |<| u
if (!isXNegated() && !isYNegated()) {
LogicNode sym = simplifyComparison(forX, forY);
if (sym != null) {
return sym;
}
}
// X |<| u || X < u ==>> X |<| u
if (forX instanceof IntegerBelowNode && forY instanceof IntegerLessThanNode && !isXNegated() && !isYNegated()) {
IntegerBelowNode xNode = (IntegerBelowNode) forX;
IntegerLessThanNode yNode = (IntegerLessThanNode) forY;
// X >= 0
ValueNode xxNode = xNode.getX();
// X >= 0
ValueNode yxNode = yNode.getX();
if (xxNode == yxNode && ((IntegerStamp) xxNode.stamp(view)).isPositive()) {
// u
ValueNode xyNode = xNode.getY();
// u
ValueNode yyNode = yNode.getY();
if (xyNode == yyNode) {
return forX;
}
}
}
// u < 0 || (X < u || tail) ==>> X |<| u || tail
if (forY instanceof ShortCircuitOrNode && !isXNegated() && !isYNegated()) {
ShortCircuitOrNode yNode = (ShortCircuitOrNode) forY;
if (!yNode.isXNegated()) {
LogicNode sym = simplifyComparison(forX, yNode.getX());
if (sym != null) {
BranchProbabilityData combinedProfile = BranchProbabilityData.combineShortCircuitOr(getShortCircuitProbability(), yNode.getShortCircuitProbability());
return new ShortCircuitOrNode(sym, isXNegated(), yNode.getY(), yNode.isYNegated(), combinedProfile);
}
}
}
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));
// 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;
}
Aggregations