Search in sources :

Example 6 with BranchProbabilityData

use of org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData in project graal by oracle.

the class IfNode method canonicalizeConditionalCascade.

private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode trueValue, ValueNode falseValue) {
    if (trueValue.getStackKind() != falseValue.getStackKind()) {
        return null;
    }
    if (trueValue.getStackKind() != JavaKind.Int && trueValue.getStackKind() != JavaKind.Long) {
        return null;
    }
    if (isSafeConditionalInput(trueValue, trueSuccessor) && isSafeConditionalInput(falseValue, falseSuccessor)) {
        return graph().unique(new ConditionalNode(condition(), trueValue, falseValue));
    }
    ValueNode value = canonicalizeConditionalViaImplies(trueValue, falseValue);
    if (value != null) {
        return value;
    }
    if (graph().isBeforeStage(StageFlag.EXPAND_LOGIC)) {
        /*
             * !isAfterExpandLogic() => Cannot spawn NormalizeCompareNodes after lowering in the
             * ExpandLogicPhase.
             */
        ConditionalNode conditional = null;
        ValueNode constant = null;
        boolean negateCondition;
        if (trueValue instanceof ConditionalNode && falseValue.isConstant()) {
            conditional = (ConditionalNode) trueValue;
            constant = falseValue;
            negateCondition = true;
        } else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) {
            conditional = (ConditionalNode) falseValue;
            constant = trueValue;
            negateCondition = false;
        } else {
            return null;
        }
        boolean negateConditionalCondition = false;
        ValueNode otherValue = null;
        if (constant == conditional.trueValue()) {
            otherValue = conditional.falseValue();
            negateConditionalCondition = false;
        } else if (constant == conditional.falseValue()) {
            otherValue = conditional.trueValue();
            negateConditionalCondition = true;
        }
        if (otherValue != null && otherValue.isConstant()) {
            BranchProbabilityData shortCutProbability = trueSuccessorProfile();
            LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability);
            return graph().unique(new ConditionalNode(newCondition, constant, otherValue));
        }
        if (constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant() && condition() instanceof CompareNode && conditional.condition() instanceof CompareNode) {
            CompareNode condition1 = (CompareNode) condition();
            Condition cond1 = condition1.condition().asCondition();
            if (negateCondition) {
                cond1 = cond1.negate();
            }
            // cond1 is EQ, NE, LT, or GE
            CompareNode condition2 = (CompareNode) conditional.condition();
            Condition cond2 = condition2.condition().asCondition();
            ValueNode x = condition1.getX();
            ValueNode y = condition1.getY();
            ValueNode x2 = condition2.getX();
            ValueNode y2 = condition2.getY();
            // `x cond1 y ? c1 : (x2 cond2 y2 ? c2 : c3)`
            boolean sameVars = x == x2 && y == y2;
            if (!sameVars && x == y2 && y == x2) {
                sameVars = true;
                cond2 = cond2.mirror();
            }
            if (sameVars) {
                JavaKind stackKind = conditional.trueValue().stamp(NodeView.from(tool)).getStackKind();
                assert !stackKind.isNumericFloat();
                long c1 = constant.asJavaConstant().asLong();
                long c2 = conditional.trueValue().asJavaConstant().asLong();
                long c3 = conditional.falseValue().asJavaConstant().asLong();
                // canonicalize cond2
                cond2 = cond2.join(cond1.negate());
                if (cond2 == null) {
                    // mixing signed and unsigned cases, or useless combination of conditions
                    return null;
                }
                // derive cond3 from cond1 and cond2
                Condition cond3 = cond1.negate().join(cond2.negate());
                if (cond3 == null) {
                    // mixing signed and unsigned cases, or useless combination of conditions
                    return null;
                }
                boolean unsigned = cond1.isUnsigned() || cond2.isUnsigned();
                boolean floatingPoint = x.stamp(NodeView.from(tool)) instanceof FloatStamp;
                assert !floatingPoint || y.stamp(NodeView.from(tool)) instanceof FloatStamp;
                assert !(floatingPoint && unsigned);
                long expected1 = expectedConstantForNormalize(cond1);
                long expected2 = expectedConstantForNormalize(cond2);
                long expected3 = expectedConstantForNormalize(cond3);
                if (c1 == expected1 && c2 == expected2 && c3 == expected3) {
                // normal order
                } else if (c1 == 0 - expected1 && c2 == 0 - expected2 && c3 == 0 - expected3) {
                    // reverse order
                    ValueNode tmp = x;
                    x = y;
                    y = tmp;
                } else {
                    // cannot be expressed by NormalizeCompareNode
                    return null;
                }
                if (floatingPoint) {
                    boolean unorderedLess = false;
                    if (((FloatStamp) x.stamp).canBeNaN() || ((FloatStamp) y.stamp).canBeNaN()) {
                        // we may encounter NaNs, check the unordered value
                        // (following the original condition's "unorderedIsTrue" path)
                        long unorderedValue = condition1.unorderedIsTrue() ? c1 : condition2.unorderedIsTrue() ? c2 : c3;
                        if (unorderedValue == 0) {
                            // returning "0" for unordered is not possible
                            return null;
                        }
                        unorderedLess = unorderedValue == -1;
                    }
                    return graph().unique(new FloatNormalizeCompareNode(x, y, stackKind, unorderedLess));
                } else {
                    return graph().unique(new IntegerNormalizeCompareNode(x, y, stackKind, unsigned));
                }
            }
        }
    }
    return null;
}
Also used : Condition(org.graalvm.compiler.core.common.calc.Condition) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) FloatNormalizeCompareNode(org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) IntegerNormalizeCompareNode(org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp) FloatNormalizeCompareNode(org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode) IntegerNormalizeCompareNode(org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 7 with BranchProbabilityData

use of org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData in project graal by oracle.

the class ShortCircuitOrNode method optimizeShortCircuit.

private static LogicNode optimizeShortCircuit(ShortCircuitOrNode inner, boolean innerNegated, boolean matchNegated, boolean matchIsInnerX) {
    boolean innerMatchNegated;
    if (matchIsInnerX) {
        innerMatchNegated = inner.isXNegated();
    } else {
        innerMatchNegated = inner.isYNegated();
    }
    if (!innerNegated) {
        // b 1010
        if (innerMatchNegated == matchNegated) {
            // Only the inner or is relevant, the outer or never adds information.
            return inner;
        } else {
            // The result of the expression is always true.
            return LogicConstantNode.tautology();
        }
    } else {
        if (innerMatchNegated == matchNegated) {
            // (!(!a ||!b) ||!a) => 1011 (!a || b)
            // (!(!a || b) ||!a) => 0111 (!a ||!b)
            // (!( a ||!b) || a) => 1110 ( a || b)
            // (!( a || b) || a) => 1101 ( a ||!b)
            boolean newInnerXNegated = inner.isXNegated();
            boolean newInnerYNegated = inner.isYNegated();
            BranchProbabilityData newProbability = inner.getShortCircuitProbability();
            if (matchIsInnerX) {
                newInnerYNegated = !newInnerYNegated;
            } else {
                newInnerXNegated = !newInnerXNegated;
                newProbability = newProbability.negated();
            }
            // The expression can be transformed into a single or.
            return new ShortCircuitOrNode(inner.getX(), newInnerXNegated, inner.getY(), newInnerYNegated, newProbability);
        } else {
            // (!(!a ||!b) || a) => 1100 (a)
            // (!(!a || b) || a) => 1100 (a)
            // (!( a ||!b) ||!a) => 0011 (!a)
            // (!( a || b) ||!a) => 0011 (!a)
            LogicNode result = inner.getY();
            if (matchIsInnerX) {
                result = inner.getX();
            }
            // Only the second part of the outer or is relevant.
            if (matchNegated) {
                return LogicNegationNode.create(result);
            } else {
                return result;
            }
        }
    }
}
Also used : BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)

Example 8 with BranchProbabilityData

use of org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData in project graal by oracle.

the class BytecodeParser method extractInjectedProbability.

/**
 * Propagate injected branch probability if any. Returns {@code null} if no injected probability
 * is present in the condition's inputs.
 */
private BranchProbabilityData extractInjectedProbability(IntegerEqualsNode condition) {
    IntegerEqualsNode equalsNode = condition;
    BranchProbabilityNode probabilityNode = null;
    ValueNode other = null;
    if (equalsNode.getX() instanceof BranchProbabilityNode) {
        probabilityNode = (BranchProbabilityNode) equalsNode.getX();
        other = equalsNode.getY();
    } else if (equalsNode.getY() instanceof BranchProbabilityNode) {
        probabilityNode = (BranchProbabilityNode) equalsNode.getY();
        other = equalsNode.getX();
    }
    if (probabilityNode != null && probabilityNode.getProbability().isConstant() && other != null && other.isConstant()) {
        double probabilityValue = clampProbability(probabilityNode.getProbability().asJavaConstant().asDouble());
        BranchProbabilityData injectedProbability = BranchProbabilityData.injected(probabilityValue);
        return other.asJavaConstant().asInt() == 0 ? injectedProbability.negated() : injectedProbability;
    }
    return null;
}
Also used : IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)

Example 9 with BranchProbabilityData

use of org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData in project graal by oracle.

the class GraphBuilderContextUtil method emitBytecodeExceptionCheck.

default AbstractBeginNode emitBytecodeExceptionCheck(LogicNode condition, boolean passingOnTrue, BytecodeExceptionKind exceptionKind, ValueNode... arguments) {
    if (passingOnTrue ? condition.isTautology() : condition.isContradiction()) {
        return null;
    }
    AbstractBeginNode exceptionPath = genExplicitExceptionEdge(exceptionKind, arguments);
    AbstractBeginNode trueSuccessor = passingOnTrue ? null : exceptionPath;
    AbstractBeginNode falseSuccessor = passingOnTrue ? exceptionPath : null;
    boolean negate = !passingOnTrue;
    BranchProbabilityData probability = BranchProbabilityData.injected(BranchProbabilityNode.EXTREMELY_FAST_PATH_PROBABILITY, negate);
    IfNode ifNode = append(new IfNode(condition, trueSuccessor, falseSuccessor, probability));
    BeginNode passingSuccessor = append(new BeginNode());
    if (passingOnTrue) {
        ifNode.setTrueSuccessor(passingSuccessor);
    } else {
        ifNode.setFalseSuccessor(passingSuccessor);
    }
    return passingSuccessor;
}
Also used : BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

BranchProbabilityData (org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)9 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)3 BciBlock (org.graalvm.compiler.java.BciBlockMapping.BciBlock)2 IfNode (org.graalvm.compiler.nodes.IfNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 FloatNormalizeCompareNode (org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode)2 IntegerEqualsNode (org.graalvm.compiler.nodes.calc.IntegerEqualsNode)2 IntegerNormalizeCompareNode (org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode)2 RuntimeConstraint (jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 TriState (jdk.vm.ci.meta.TriState)1 Condition (org.graalvm.compiler.core.common.calc.Condition)1 CanonicalizedCondition (org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition)1 FloatStamp (org.graalvm.compiler.core.common.type.FloatStamp)1 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)1 Stamp (org.graalvm.compiler.core.common.type.Stamp)1 NodeSourcePosition (org.graalvm.compiler.graph.NodeSourcePosition)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)1