Search in sources :

Example 26 with FrameState

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

the class GraphOrder method assertSchedulableGraph.

/**
 * This method schedules the graph and makes sure that, for every node, all inputs are available
 * at the position where it is scheduled. This is a very expensive assertion.
 */
public static boolean assertSchedulableGraph(final StructuredGraph graph) {
    assert graph.getGuardsStage() != GuardsStage.AFTER_FSA : "Cannot use the BlockIteratorClosure after FrameState Assignment, HIR Loop Data Structures are no longer valid.";
    try {
        final SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true);
        final EconomicMap<LoopBeginNode, NodeBitMap> loopEntryStates = EconomicMap.create(Equivalence.IDENTITY);
        schedulePhase.apply(graph, false);
        final ScheduleResult schedule = graph.getLastSchedule();
        BlockIteratorClosure<NodeBitMap> closure = new BlockIteratorClosure<NodeBitMap>() {

            @Override
            protected List<NodeBitMap> processLoop(Loop<Block> loop, NodeBitMap initialState) {
                return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
            }

            @Override
            protected NodeBitMap processBlock(final Block block, final NodeBitMap currentState) {
                final List<Node> list = graph.getLastSchedule().getBlockToNodesMap().get(block);
                /*
                     * A stateAfter is not valid directly after its associated state split, but
                     * right before the next fixed node. Therefore a pending stateAfter is kept that
                     * will be checked at the correct position.
                     */
                FrameState pendingStateAfter = null;
                for (final Node node : list) {
                    if (node instanceof ValueNode) {
                        FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
                        if (node instanceof FullInfopointNode) {
                            stateAfter = ((FullInfopointNode) node).getState();
                        }
                        if (pendingStateAfter != null && node instanceof FixedNode) {
                            pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                                @Override
                                public void apply(Node usage, Node nonVirtualNode) {
                                    assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list;
                                }
                            });
                            pendingStateAfter = null;
                        }
                        if (node instanceof AbstractMergeNode) {
                            // phis aren't scheduled, so they need to be added explicitly
                            currentState.markAll(((AbstractMergeNode) node).phis());
                            if (node instanceof LoopBeginNode) {
                                // remember the state at the loop entry, it's restored at exits
                                loopEntryStates.put((LoopBeginNode) node, currentState.copy());
                            }
                        } else if (node instanceof ProxyNode) {
                            assert false : "proxy nodes should not be in the schedule";
                        } else if (node instanceof LoopExitNode) {
                            if (graph.hasValueProxies()) {
                                for (ProxyNode proxy : ((LoopExitNode) node).proxies()) {
                                    for (Node input : proxy.inputs()) {
                                        if (input != proxy.proxyPoint()) {
                                            assert currentState.isMarked(input) : input + " not available at " + proxy + " in block " + block + "\n" + list;
                                        }
                                    }
                                }
                                // loop contents are only accessible via proxies at the exit
                                currentState.clearAll();
                                currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
                            }
                            // Loop proxies aren't scheduled, so they need to be added
                            // explicitly
                            currentState.markAll(((LoopExitNode) node).proxies());
                        } else {
                            for (Node input : node.inputs()) {
                                if (input != stateAfter) {
                                    if (input instanceof FrameState) {
                                        ((FrameState) input).applyToNonVirtual(new VirtualState.NodeClosure<Node>() {

                                            @Override
                                            public void apply(Node usage, Node nonVirtual) {
                                                assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list;
                                            }
                                        });
                                    } else {
                                        assert currentState.isMarked(input) || input instanceof VirtualObjectNode || input instanceof ConstantNode : input + " not available at " + node + " in block " + block + "\n" + list;
                                    }
                                }
                            }
                        }
                        if (node instanceof AbstractEndNode) {
                            AbstractMergeNode merge = ((AbstractEndNode) node).merge();
                            for (PhiNode phi : merge.phis()) {
                                ValueNode phiValue = phi.valueAt((AbstractEndNode) node);
                                assert phiValue == null || currentState.isMarked(phiValue) || phiValue instanceof ConstantNode : phiValue + " not available at phi " + phi + " / end " + node + " in block " + block;
                            }
                        }
                        if (stateAfter != null) {
                            assert pendingStateAfter == null;
                            pendingStateAfter = stateAfter;
                        }
                        currentState.mark(node);
                    }
                }
                if (pendingStateAfter != null) {
                    pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                        @Override
                        public void apply(Node usage, Node nonVirtualNode) {
                            assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list;
                        }
                    });
                }
                return currentState;
            }

            @Override
            protected NodeBitMap merge(Block merge, List<NodeBitMap> states) {
                NodeBitMap result = states.get(0);
                for (int i = 1; i < states.size(); i++) {
                    result.intersect(states.get(i));
                }
                return result;
            }

            @Override
            protected NodeBitMap getInitialState() {
                NodeBitMap ret = graph.createNodeBitMap();
                ret.markAll(graph.getNodes().filter(ConstantNode.class));
                return ret;
            }

            @Override
            protected NodeBitMap cloneState(NodeBitMap oldState) {
                return oldState.copy();
            }
        };
        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
    } catch (Throwable t) {
        graph.getDebug().handle(t);
    }
    return true;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) VirtualState(org.graalvm.compiler.nodes.VirtualState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ArrayList(java.util.ArrayList) List(java.util.List) Loop(org.graalvm.compiler.core.common.cfg.Loop) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) BlockIteratorClosure(org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 27 with FrameState

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

the class GraphOrder method assertNonCyclicGraph.

/**
 * Quick (and imprecise) assertion that there are no (invalid) cycles in the given graph. First,
 * an ordered list of all nodes in the graph (a total ordering) is created. A second run over
 * this list checks whether inputs are scheduled before their usages.
 *
 * @param graph the graph to be checked.
 * @throws AssertionError if a cycle was detected.
 */
public static boolean assertNonCyclicGraph(StructuredGraph graph) {
    List<Node> order = createOrder(graph);
    NodeBitMap visited = graph.createNodeBitMap();
    visited.clearAll();
    for (Node node : order) {
        if (node instanceof PhiNode && ((PhiNode) node).merge() instanceof LoopBeginNode) {
            assert visited.isMarked(((PhiNode) node).valueAt(0));
        // nothing to do
        } else {
            for (Node input : node.inputs()) {
                if (!visited.isMarked(input)) {
                    if (input instanceof FrameState) {
                    // nothing to do - frame states are known, allowed cycles
                    } else {
                        assert false : "unexpected cycle detected at input " + node + " -> " + input;
                    }
                }
            }
        }
        visited.mark(node);
    }
    return true;
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FrameState(org.graalvm.compiler.nodes.FrameState)

Example 28 with FrameState

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

the class AArch64ReadNode method replace.

/**
 * replace a ReadNode with an AArch64-specific variant which knows how to merge a downstream
 * zero or sign extend into the read operation.
 *
 * @param readNode
 */
public static void replace(ReadNode readNode) {
    assert readNode.getUsageCount() == 1;
    assert readNode.getUsageAt(0) instanceof ZeroExtendNode || readNode.getUsageAt(0) instanceof SignExtendNode;
    ValueNode usage = (ValueNode) readNode.getUsageAt(0);
    boolean isSigned = usage instanceof SignExtendNode;
    IntegerStamp accessStamp = ((IntegerStamp) readNode.getAccessStamp());
    AddressNode address = readNode.getAddress();
    LocationIdentity location = readNode.getLocationIdentity();
    Stamp stamp = usage.stamp(NodeView.DEFAULT);
    GuardingNode guard = readNode.getGuard();
    BarrierType barrierType = readNode.getBarrierType();
    boolean nullCheck = readNode.getNullCheck();
    FrameState stateBefore = readNode.stateBefore();
    AArch64ReadNode clone = new AArch64ReadNode(address, location, stamp, guard, barrierType, nullCheck, stateBefore, accessStamp, isSigned);
    StructuredGraph graph = readNode.graph();
    graph.add(clone);
    // splice out the extend node
    usage.replaceAtUsagesAndDelete(readNode);
    // swap the clone for the read
    graph.replaceFixedWithFixed(readNode, clone);
}
Also used : SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) FrameState(org.graalvm.compiler.nodes.FrameState) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LocationIdentity(org.graalvm.word.LocationIdentity) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode)

Example 29 with FrameState

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

the class PartialEscapeClosure method processNodeWithState.

private void processNodeWithState(NodeWithState nodeWithState, BlockT state, GraphEffectList effects) {
    for (FrameState fs : nodeWithState.states()) {
        FrameState frameState = getUniqueFramestate(nodeWithState, fs);
        EconomicSet<VirtualObjectNode> virtual = EconomicSet.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
        frameState.applyToNonVirtual(new CollectVirtualObjectsClosure(virtual, effects, state));
        collectLockedVirtualObjects(state, virtual);
        collectReferencedVirtualObjects(state, virtual);
        addVirtualMappings(frameState, virtual, state, effects);
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) FrameState(org.graalvm.compiler.nodes.FrameState)

Example 30 with FrameState

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

the class PartialEscapeClosure method getUniqueFramestate.

private static FrameState getUniqueFramestate(NodeWithState nodeWithState, FrameState frameState) {
    if (frameState.hasMoreThanOneUsage()) {
        // Can happen for example from inlined snippets with multiple state split nodes.
        FrameState copy = (FrameState) frameState.copyWithInputs();
        nodeWithState.asNode().replaceFirstInput(frameState, copy);
        return copy;
    }
    return frameState;
}
Also used : FrameState(org.graalvm.compiler.nodes.FrameState)

Aggregations

FrameState (org.graalvm.compiler.nodes.FrameState)73 ValueNode (org.graalvm.compiler.nodes.ValueNode)38 Node (org.graalvm.compiler.graph.Node)27 FixedNode (org.graalvm.compiler.nodes.FixedNode)21 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)19 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)19 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)16 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)16 PhiNode (org.graalvm.compiler.nodes.PhiNode)16 EndNode (org.graalvm.compiler.nodes.EndNode)15 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)15 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)14 MergeNode (org.graalvm.compiler.nodes.MergeNode)14 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)13 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)12 StateSplit (org.graalvm.compiler.nodes.StateSplit)12 MonitorIdNode (org.graalvm.compiler.nodes.java.MonitorIdNode)12 DebugContext (org.graalvm.compiler.debug.DebugContext)11 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)11 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)11