Search in sources :

Example 1 with IntegerNormalizeCompareNode

use of org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode 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)

Aggregations

JavaKind (jdk.vm.ci.meta.JavaKind)1 Condition (org.graalvm.compiler.core.common.calc.Condition)1 FloatStamp (org.graalvm.compiler.core.common.type.FloatStamp)1 BranchProbabilityData (org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)1 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)1 ConditionalNode (org.graalvm.compiler.nodes.calc.ConditionalNode)1 FloatNormalizeCompareNode (org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode)1 IntegerNormalizeCompareNode (org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode)1