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);
}
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;
}
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;
}
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();
}
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);
}
}
Aggregations