Search in sources :

Example 1 with CanonicalizerTool

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;
}
Also used : IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) IntegerLessThanNode(org.graalvm.compiler.nodes.calc.IntegerLessThanNode) TriState(jdk.vm.ci.meta.TriState) CanonicalizerTool(org.graalvm.compiler.nodes.spi.CanonicalizerTool)

Aggregations

TriState (jdk.vm.ci.meta.TriState)1 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)1 Stamp (org.graalvm.compiler.core.common.type.Stamp)1 BranchProbabilityData (org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)1 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)1 IntegerBelowNode (org.graalvm.compiler.nodes.calc.IntegerBelowNode)1 IntegerLessThanNode (org.graalvm.compiler.nodes.calc.IntegerLessThanNode)1 CanonicalizerTool (org.graalvm.compiler.nodes.spi.CanonicalizerTool)1