use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class FixedNodeProbabilityCache method applyAsDouble.
/**
* <p>
* Given a {@link FixedNode} this method finds the most immediate {@link AbstractBeginNode}
* preceding it that either:
* <ul>
* <li>has no predecessor (ie, the begin-node is a merge, in particular a loop-begin, or the
* start-node)</li>
* <li>has a control-split predecessor</li>
* </ul>
* </p>
*
* <p>
* The thus found {@link AbstractBeginNode} is equi-probable with the {@link FixedNode} it was
* obtained from. When computed for the first time (afterwards a cache lookup returns it) that
* probability is computed as follows, again depending on the begin-node's predecessor:
* <ul>
* <li>No predecessor. In this case the begin-node is either:</li>
* <ul>
* <li>a merge-node, whose probability adds up those of its forward-ends</li>
* <li>a loop-begin, with probability as above multiplied by the loop-frequency</li>
* </ul>
* <li>Control-split predecessor: probability of the branch times that of the control-split</li>
* </ul>
* </p>
*
* <p>
* As an exception to all the above, a probability of 1 is assumed for a {@link FixedNode} that
* appears to be dead-code (ie, lacks a predecessor).
* </p>
*/
@Override
public double applyAsDouble(FixedNode node) {
assert node != null;
computeNodeProbabilityCounter.increment(node.getDebug());
FixedNode current = findBegin(node);
if (current == null) {
// this should only appear for dead code
return 1D;
}
assert current instanceof AbstractBeginNode;
Double cachedValue = cache.get(current);
if (cachedValue != null) {
return cachedValue;
}
double probability = 0.0;
if (current.predecessor() == null) {
if (current instanceof AbstractMergeNode) {
probability = handleMerge(current, probability);
} else {
assert current instanceof StartNode;
probability = 1D;
}
} else {
ControlSplitNode split = (ControlSplitNode) current.predecessor();
probability = multiplyProbabilities(split.probability((AbstractBeginNode) current), applyAsDouble(split));
}
assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability;
cache.put(current, probability);
return probability;
}
Aggregations