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