Search in sources :

Example 86 with FixedNode

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

the class LoweringPhase method checkPostNodeLowering.

/**
 * Checks that lowering of a given node did not introduce any new {@link Lowerable} nodes that
 * could be lowered in the current {@link LoweringPhase}. Such nodes must be recursively lowered
 * as part of lowering {@code node}.
 *
 * @param node a node that was just lowered
 * @param preLoweringMark the graph mark before {@code node} was lowered
 * @param unscheduledUsages set of {@code node}'s usages that were unscheduled before it was
 *            lowered
 * @throws AssertionError if the check fails
 */
private static boolean checkPostNodeLowering(Node node, LoweringToolImpl loweringTool, Mark preLoweringMark, Collection<Node> unscheduledUsages) {
    StructuredGraph graph = (StructuredGraph) node.graph();
    Mark postLoweringMark = graph.getMark();
    NodeIterable<Node> newNodesAfterLowering = graph.getNewNodes(preLoweringMark);
    if (node instanceof FloatingNode) {
        if (!unscheduledUsages.isEmpty()) {
            for (Node n : newNodesAfterLowering) {
                assert !(n instanceof FixedNode) : node.graph() + ": cannot lower floatable node " + node + " as it introduces fixed node(s) but has the following unscheduled usages: " + unscheduledUsages;
            }
        }
    }
    for (Node n : newNodesAfterLowering) {
        if (n instanceof Lowerable) {
            ((Lowerable) n).lower(loweringTool);
            Mark mark = graph.getMark();
            assert postLoweringMark.equals(mark) : graph + ": lowering of " + node + " produced lowerable " + n + " that should have been recursively lowered as it introduces these new nodes: " + graph.getNewNodes(postLoweringMark).snapshot();
        }
        if (graph.isAfterFloatingReadPhase() && n instanceof MemoryCheckpoint && !(node instanceof MemoryCheckpoint) && !(node instanceof ControlSinkNode)) {
            /*
                 * The lowering introduced a MemoryCheckpoint but the current node isn't a
                 * checkpoint. This is only OK if the locations involved don't affect the memory
                 * graph or if the new kill location doesn't connect into the existing graph.
                 */
            boolean isAny = false;
            if (n instanceof MemoryCheckpoint.Single) {
                isAny = ((MemoryCheckpoint.Single) n).getLocationIdentity().isAny();
            } else {
                for (LocationIdentity ident : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
                    if (ident.isAny()) {
                        isAny = true;
                    }
                }
            }
            if (isAny && n instanceof FixedWithNextNode) {
                /*
                     * Check if the next kill location leads directly to a ControlSinkNode in the
                     * new part of the graph. This is a fairly conservative test that could be made
                     * more general if required.
                     */
                FixedWithNextNode cur = (FixedWithNextNode) n;
                while (cur != null && graph.isNew(preLoweringMark, cur)) {
                    if (cur.next() instanceof ControlSinkNode) {
                        isAny = false;
                        break;
                    }
                    if (cur.next() instanceof FixedWithNextNode) {
                        cur = (FixedWithNextNode) cur.next();
                    } else {
                        break;
                    }
                }
            }
            assert !isAny : node + " " + n;
        }
    }
    return true;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GuardedNode(org.graalvm.compiler.nodes.extended.GuardedNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) Mark(org.graalvm.compiler.graph.Graph.Mark) FixedNode(org.graalvm.compiler.nodes.FixedNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LocationIdentity(org.graalvm.word.LocationIdentity) Lowerable(org.graalvm.compiler.nodes.spi.Lowerable)

Example 87 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode 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;
}
Also used : StartNode(org.graalvm.compiler.nodes.StartNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

FixedNode (org.graalvm.compiler.nodes.FixedNode)87 Node (org.graalvm.compiler.graph.Node)41 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)41 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)39 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)39 ValueNode (org.graalvm.compiler.nodes.ValueNode)34 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)33 EndNode (org.graalvm.compiler.nodes.EndNode)27 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)25 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)23 PhiNode (org.graalvm.compiler.nodes.PhiNode)22 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)21 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)21 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)20 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)17 MergeNode (org.graalvm.compiler.nodes.MergeNode)17 StartNode (org.graalvm.compiler.nodes.StartNode)17 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)16 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)13 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)13