Search in sources :

Example 1 with BranchProbabilityData

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

the class BytecodeParser method genIf.

protected void genIf(ValueNode x, Condition cond, ValueNode y) {
    assert x.getStackKind() == y.getStackKind();
    assert currentBlock.getSuccessorCount() == 2;
    BciBlock trueBlock = currentBlock.getSuccessor(0);
    BciBlock falseBlock = currentBlock.getSuccessor(1);
    if (trueBlock == falseBlock) {
        // The target block is the same independent of the condition.
        appendGoto(trueBlock);
        return;
    }
    ValueNode a = x;
    ValueNode b = y;
    BciBlock trueSuccessor = trueBlock;
    BciBlock falseSuccessor = falseBlock;
    CanonicalizedCondition canonicalizedCondition = cond.canonicalize();
    // Check whether the condition needs to mirror the operands.
    if (canonicalizedCondition.mustMirror()) {
        a = y;
        b = x;
    }
    if (canonicalizedCondition.mustNegate()) {
        trueSuccessor = falseBlock;
        falseSuccessor = trueBlock;
    }
    // Create the logic node for the condition.
    LogicNode condition = createLogicNode(canonicalizedCondition.getCanonicalCondition(), a, b);
    BranchProbabilityData profileData = null;
    if (condition instanceof IntegerEqualsNode) {
        profileData = extractInjectedProbability((IntegerEqualsNode) condition);
    }
    if (profileData == null) {
        profileData = getProfileData(canonicalizedCondition.mustNegate());
    }
    genIf(condition, trueSuccessor, falseSuccessor, profileData);
}
Also used : CanonicalizedCondition(org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock)

Example 2 with BranchProbabilityData

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

the class BytecodeParser method getProfileData.

protected BranchProbabilityData getProfileData(boolean negate) {
    if (profilingInfo == null) {
        return BranchProbabilityData.unknown();
    }
    assert assertAtIfBytecode();
    double probability = profilingInfo.getBranchTakenProbability(bci());
    if (probability < 0) {
        assert probability == -1 : "invalid probability";
        debug.log("missing probability in %s at bci %d", code, bci());
        return BranchProbabilityData.unknown();
    }
    probability = clampProbability(probability);
    ProfileSource source = profilingInfo.isMature() ? ProfileSource.PROFILED : ProfileSource.UNKNOWN;
    BranchProbabilityData profileData = BranchProbabilityData.create(probability, source);
    if (negate) {
        // the probability coming from profile is about the original condition
        profileData = profileData.negated();
    }
    return profileData;
}
Also used : ProfileSource(org.graalvm.compiler.nodes.ProfileData.ProfileSource) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData)

Example 3 with BranchProbabilityData

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

Example 4 with BranchProbabilityData

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

the class HostedGraphKit method createCheckThrowingBytecodeException.

public GuardingNode createCheckThrowingBytecodeException(LogicNode condition, boolean failOnTrue, BytecodeExceptionNode.BytecodeExceptionKind exceptionKind, ValueNode... arguments) {
    BranchProbabilityData trueProbability = failOnTrue ? BranchProbabilityNode.SLOW_PATH_PROFILE : BranchProbabilityNode.FAST_PATH_PROFILE;
    IfNode ifNode = startIf(condition, trueProbability);
    if (failOnTrue) {
        thenPart();
    } else {
        elsePart();
    }
    BytecodeExceptionNode exception = createBytecodeExceptionObjectNode(exceptionKind, true, arguments);
    append(new UnwindNode(exception));
    AbstractMergeNode merge = endIf();
    assert merge == null;
    return failOnTrue ? ifNode.falseSuccessor() : ifNode.trueSuccessor();
}
Also used : BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 5 with BranchProbabilityData

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

the class BytecodeParser method genIf.

protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, BranchProbabilityData originalProfileData) {
    BciBlock trueBlock = trueBlockInput;
    BciBlock falseBlock = falseBlockInput;
    LogicNode condition = conditionInput;
    BranchProbabilityData profileData = originalProfileData;
    // Remove a logic negation node.
    if (condition instanceof LogicNegationNode) {
        LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
        BciBlock tmpBlock = trueBlock;
        trueBlock = falseBlock;
        falseBlock = tmpBlock;
        // the probability coming from profile is about the original condition
        profileData = profileData.negated();
        condition = logicNegationNode.getValue();
    }
    if (condition instanceof LogicConstantNode) {
        genConstantTargetIf(trueBlock, falseBlock, condition);
    } else {
        if (condition.graph() == null) {
            condition = genUnique(condition);
        }
        BciBlock deoptBlock = null;
        BciBlock noDeoptBlock = null;
        if (isNeverExecutedCode(profileData.getDesignatedSuccessorProbability())) {
            deoptBlock = trueBlock;
            noDeoptBlock = falseBlock;
        } else if (isNeverExecutedCode(profileData.getNegatedProbability())) {
            deoptBlock = falseBlock;
            noDeoptBlock = trueBlock;
        }
        if (deoptBlock != null) {
            NodeSourcePosition currentPosition = graph.currentNodeSourcePosition();
            NodeSourcePosition survivingSuccessorPosition = null;
            if (graph.trackNodeSourcePosition()) {
                survivingSuccessorPosition = new NodeSourcePosition(currentPosition.getCaller(), currentPosition.getMethod(), noDeoptBlock.startBci);
            }
            boolean negated = deoptBlock == trueBlock;
            if (!isPotentialCountedLoopExit(condition, deoptBlock)) {
                append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, negated, survivingSuccessorPosition));
                appendGoto(noDeoptBlock);
            } else {
                this.controlFlowSplit = true;
                FixedNode noDeoptSuccessor = createTarget(noDeoptBlock, frameState, false, true);
                DeoptimizeNode deopt = graph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
                /*
                     * We do not want to `checkLoopExit` here: otherwise the deopt will go to the
                     * deoptBlock's BCI, skipping the branch in the interpreter, and the profile
                     * will never see that the branch is taken. This can lead to deopt loops or OSR
                     * failure.
                     */
                BranchProbabilityData calculatedProbability = BranchProbabilityData.injected(BranchProbabilityNode.ALWAYS_TAKEN_PROBABILITY, negated);
                FixedNode deoptSuccessor = BeginNode.begin(deopt);
                ValueNode ifNode = genIfNode(condition, negated ? deoptSuccessor : noDeoptSuccessor, negated ? noDeoptSuccessor : deoptSuccessor, calculatedProbability);
                postProcessIfNode(ifNode);
                append(ifNode);
            }
            return;
        }
        int oldBci = stream.currentBCI();
        int trueBlockInt = checkPositiveIntConstantPushed(trueBlock);
        if (trueBlockInt != -1) {
            int falseBlockInt = checkPositiveIntConstantPushed(falseBlock);
            if (falseBlockInt != -1) {
                if (tryGenConditionalForIf(trueBlock, falseBlock, condition, oldBci, trueBlockInt, falseBlockInt)) {
                    return;
                }
            }
        }
        this.controlFlowSplit = true;
        FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, false);
        FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, true);
        if (this.graphBuilderConfig.replaceLocalsWithConstants() && condition instanceof CompareNode) {
            CompareNode compareNode = (CompareNode) condition;
            if (compareNode.condition() == CanonicalCondition.EQ) {
                ValueNode constantNode = null;
                ValueNode nonConstantNode = null;
                if (compareNode.getX() instanceof ConstantNode) {
                    constantNode = compareNode.getX();
                    nonConstantNode = compareNode.getY();
                } else if (compareNode.getY() instanceof ConstantNode) {
                    constantNode = compareNode.getY();
                    nonConstantNode = compareNode.getX();
                }
                if (constantNode != null && nonConstantNode != null) {
                    this.getEntryState(trueBlock).replaceValue(nonConstantNode, constantNode);
                }
            }
        }
        ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, profileData);
        postProcessIfNode(ifNode);
        append(ifNode);
    }
}
Also used : LogicNegationNode(org.graalvm.compiler.nodes.LogicNegationNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) BranchProbabilityData(org.graalvm.compiler.nodes.ProfileData.BranchProbabilityData) FixedNode(org.graalvm.compiler.nodes.FixedNode) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) FloatNormalizeCompareNode(org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode) IntegerNormalizeCompareNode(org.graalvm.compiler.nodes.calc.IntegerNormalizeCompareNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) NodeSourcePosition(org.graalvm.compiler.graph.NodeSourcePosition)

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