Search in sources :

Example 16 with AbstractEndNode

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

the class ControlFlowGraph method identifyBlocks.

/**
 * Identify and connect blocks (including loop backward edges). Predecessors need to be in the
 * order expected when iterating phi inputs.
 */
private void identifyBlocks() {
    // Find all block headers.
    int numBlocks = 0;
    for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.TYPE)) {
        Block block = new Block(begin);
        identifyBlock(block);
        numBlocks++;
    }
    // Compute reverse post order.
    int count = 0;
    NodeMap<Block> nodeMap = this.nodeToBlock;
    Block[] stack = new Block[numBlocks];
    int tos = 0;
    Block startBlock = blockFor(graph.start());
    stack[0] = startBlock;
    startBlock.setPredecessors(Block.EMPTY_ARRAY);
    do {
        Block block = stack[tos];
        int id = block.getId();
        if (id == BLOCK_ID_INITIAL) {
            // First time we see this block: push all successors.
            FixedNode last = block.getEndNode();
            if (last instanceof EndNode) {
                EndNode endNode = (EndNode) last;
                Block suxBlock = nodeMap.get(endNode.merge());
                if (suxBlock.getId() == BLOCK_ID_INITIAL) {
                    stack[++tos] = suxBlock;
                }
                block.setSuccessors(new Block[] { suxBlock });
            } else if (last instanceof IfNode) {
                IfNode ifNode = (IfNode) last;
                Block trueSucc = nodeMap.get(ifNode.trueSuccessor());
                stack[++tos] = trueSucc;
                Block falseSucc = nodeMap.get(ifNode.falseSuccessor());
                stack[++tos] = falseSucc;
                block.setSuccessors(new Block[] { trueSucc, falseSucc });
                Block[] ifPred = new Block[] { block };
                trueSucc.setPredecessors(ifPred);
                falseSucc.setPredecessors(ifPred);
            } else if (last instanceof LoopEndNode) {
                LoopEndNode loopEndNode = (LoopEndNode) last;
                block.setSuccessors(new Block[] { nodeMap.get(loopEndNode.loopBegin()) });
            // Nothing to do push onto the stack.
            } else if (last instanceof ControlSinkNode) {
                block.setSuccessors(Block.EMPTY_ARRAY);
            } else {
                assert !(last instanceof AbstractEndNode) : "Algorithm only supports EndNode and LoopEndNode.";
                int startTos = tos;
                Block[] ifPred = new Block[] { block };
                for (Node suxNode : last.successors()) {
                    Block sux = nodeMap.get(suxNode);
                    stack[++tos] = sux;
                    sux.setPredecessors(ifPred);
                }
                int suxCount = tos - startTos;
                Block[] successors = new Block[suxCount];
                System.arraycopy(stack, startTos + 1, successors, 0, suxCount);
                block.setSuccessors(successors);
            }
            block.setId(BLOCK_ID_VISITED);
            AbstractBeginNode beginNode = block.getBeginNode();
            if (beginNode instanceof LoopBeginNode) {
                computeLoopPredecessors(nodeMap, block, (LoopBeginNode) beginNode);
            } else if (beginNode instanceof MergeNode) {
                MergeNode mergeNode = (MergeNode) beginNode;
                int forwardEndCount = mergeNode.forwardEndCount();
                Block[] predecessors = new Block[forwardEndCount];
                for (int i = 0; i < forwardEndCount; ++i) {
                    predecessors[i] = nodeMap.get(mergeNode.forwardEndAt(i));
                }
                block.setPredecessors(predecessors);
            }
        } else if (id == BLOCK_ID_VISITED) {
            // Second time we see this block: All successors have been processed, so add block
            // to result list. Can safely reuse the stack for this.
            --tos;
            count++;
            int index = numBlocks - count;
            stack[index] = block;
            block.setId(index);
        } else {
            throw GraalError.shouldNotReachHere();
        }
    } while (tos >= 0);
    // Compute reverse postorder and number blocks.
    assert count == numBlocks : "all blocks must be reachable";
    this.reversePostOrder = stack;
}
Also used : ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode)

Example 17 with AbstractEndNode

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

the class GraphUtil method killCFGInner.

private static void killCFGInner(FixedNode node) {
    EconomicSet<Node> markedNodes = EconomicSet.create();
    EconomicMap<AbstractMergeNode, List<AbstractEndNode>> unmarkedMerges = EconomicMap.create();
    // Detach this node from CFG
    node.replaceAtPredecessor(null);
    markFixedNodes(node, markedNodes, unmarkedMerges);
    fixSurvivingAffectedMerges(markedNodes, unmarkedMerges);
    DebugContext debug = node.getDebug();
    debug.dump(DebugContext.DETAILED_LEVEL, node.graph(), "After fixing merges (killCFG %s)", node);
    // Mark non-fixed nodes
    markUsages(markedNodes);
    // Detach marked nodes from non-marked nodes
    for (Node marked : markedNodes) {
        for (Node input : marked.inputs()) {
            if (!markedNodes.contains(input)) {
                marked.replaceFirstInput(input, null);
                tryKillUnused(input);
            }
        }
    }
    debug.dump(DebugContext.VERY_DETAILED_LEVEL, node.graph(), "After disconnecting non-marked inputs (killCFG %s)", node);
    // Kill marked nodes
    for (Node marked : markedNodes) {
        if (marked.isAlive()) {
            marked.markDeleted();
        }
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) List(java.util.List) ArrayList(java.util.ArrayList) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DebugContext(org.graalvm.compiler.debug.DebugContext)

Example 18 with AbstractEndNode

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

the class EnsureVirtualizedNode method ensureVirtualFailure.

public static void ensureVirtualFailure(Node location, Stamp stamp) {
    String additionalReason = "";
    if (location instanceof FixedWithNextNode && !(location instanceof EnsureVirtualizedNode)) {
        FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) location;
        FixedNode next = fixedWithNextNode.next();
        if (next instanceof StoreFieldNode) {
            additionalReason = " (must not store virtual object into a field)";
        } else if (next instanceof Invoke) {
            additionalReason = " (must not pass virtual object into an invoke that cannot be inlined)";
        } else {
            additionalReason = " (must not let virtual object escape at node " + next + ")";
        }
    }
    Throwable exception = new VerificationError("Object of type %s should not be materialized%s:", StampTool.typeOrNull(stamp).getName(), additionalReason);
    Node pos;
    if (location instanceof FixedWithNextNode) {
        pos = ((FixedWithNextNode) location).next();
    } else if (location instanceof AbstractEndNode) {
        pos = ((AbstractEndNode) location).merge();
    } else {
        pos = location;
    }
    throw GraphUtil.approxSourceException(pos, exception);
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) VerificationError(org.graalvm.compiler.graph.VerificationError) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 19 with AbstractEndNode

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

the class ConvertDeoptimizeToGuardPhase method propagateFixed.

@SuppressWarnings("try")
private void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, LoweringProvider loweringProvider) {
    Node current = from;
    while (current != null) {
        if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
            FixedGuardNode otherGuard = (FixedGuardNode) current;
            if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
                moveAsDeoptAfter(otherGuard, deopt);
                return;
            }
        } else if (current instanceof AbstractBeginNode) {
            if (current instanceof AbstractMergeNode) {
                AbstractMergeNode mergeNode = (AbstractMergeNode) current;
                FixedNode next = mergeNode.next();
                while (mergeNode.isAlive()) {
                    AbstractEndNode end = mergeNode.forwardEnds().first();
                    propagateFixed(end, deopt, loweringProvider);
                }
                assert next.isAlive();
                propagateFixed(next, deopt, loweringProvider);
                return;
            } else if (current.predecessor() instanceof IfNode) {
                IfNode ifNode = (IfNode) current.predecessor();
                // Prioritize the source position of the IfNode
                try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
                    StructuredGraph graph = ifNode.graph();
                    LogicNode conditionNode = ifNode.condition();
                    boolean negateGuardCondition = current == ifNode.trueSuccessor();
                    FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition));
                    FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
                    AbstractBeginNode survivingSuccessor;
                    if (negateGuardCondition) {
                        survivingSuccessor = ifNode.falseSuccessor();
                    } else {
                        survivingSuccessor = ifNode.trueSuccessor();
                    }
                    graph.removeSplitPropagate(ifNode, survivingSuccessor);
                    Node newGuard = guard;
                    if (survivingSuccessor instanceof LoopExitNode) {
                        newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
                    }
                    survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
                    graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
                    FixedNode next = pred.next();
                    pred.setNext(guard);
                    guard.setNext(next);
                    SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
                    survivingSuccessor.simplify(simplifierTool);
                    return;
                }
            } else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
                assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
                moveAsDeoptAfter((AbstractBeginNode) current, deopt);
                return;
            }
        }
        current = current.predecessor();
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StartNode(org.graalvm.compiler.nodes.StartNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StartNode(org.graalvm.compiler.nodes.StartNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) StaticDeoptimizingNode(org.graalvm.compiler.nodes.StaticDeoptimizingNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) SimplifierTool(org.graalvm.compiler.graph.spi.SimplifierTool) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable)

Example 20 with AbstractEndNode

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

the class CFGPrinter method scheduleInputs.

private void scheduleInputs(Node node, Block nodeBlock) {
    if (node instanceof ValuePhiNode) {
        PhiNode phi = (PhiNode) node;
        Block phiBlock = latestScheduling.get(phi.merge());
        assert phiBlock != null;
        for (Block pred : phiBlock.getPredecessors()) {
            schedule(phi.valueAt((AbstractEndNode) pred.getEndNode()), pred);
        }
    } else {
        for (Node input : node.inputs()) {
            schedule(input, nodeBlock);
        }
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Aggregations

AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)23 FixedNode (org.graalvm.compiler.nodes.FixedNode)17 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)16 Node (org.graalvm.compiler.graph.Node)14 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)13 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)10 EndNode (org.graalvm.compiler.nodes.EndNode)9 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)7 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)6 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)6 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)6 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)6 ArrayList (java.util.ArrayList)5 IfNode (org.graalvm.compiler.nodes.IfNode)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)5 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)5