Search in sources :

Example 6 with ScheduleResult

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

the class MemoryScheduleTest method testStringHashCode.

@Test
public void testStringHashCode() {
    ScheduleResult schedule = getFinalSchedule("testStringHashCodeSnippet", TestMode.WITHOUT_FRAMESTATES);
    assertReadWithinStartBlock(schedule, true);
    assertReadWithinAllReturnBlocks(schedule, false);
    hash = 0x1337;
    value[0] = 'a';
    value[1] = 'b';
    value[2] = 'c';
    test("testStringHashCodeSnippet");
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) Test(org.junit.Test)

Example 7 with ScheduleResult

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

the class MemoryScheduleTest method testLoop7.

@Test
public void testLoop7() {
    ScheduleResult schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES);
    assertDeepEquals(18, schedule.getCFG().getBlocks().length);
    assertReadWithinStartBlock(schedule, false);
    assertReadWithinAllReturnBlocks(schedule, false);
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) Test(org.junit.Test)

Example 8 with ScheduleResult

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

the class GraalCompiler method emitLIR0.

@SuppressWarnings("try")
private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites, String[] allocationRestrictedTo) {
    DebugContext debug = graph.getDebug();
    try (DebugContext.Scope ds = debug.scope("EmitLIR");
        DebugCloseable a = EmitLIR.start(debug)) {
        assert !graph.hasValueProxies();
        ScheduleResult schedule = graph.getLastSchedule();
        Block[] blocks = schedule.getCFG().getBlocks();
        Block startBlock = schedule.getCFG().getStartBlock();
        assert startBlock != null;
        assert startBlock.getPredecessorCount() == 0;
        AbstractBlockBase<?>[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock);
        AbstractBlockBase<?>[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock);
        LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions(), graph.getDebug());
        FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
        LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub);
        LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes);
        NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
        // LIR generation
        LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
        new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
        try (DebugContext.Scope s = debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
            // Dump LIR along with HIR (the LIR is looked up from context)
            debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
            LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
            return result;
        } catch (Throwable e) {
            throw debug.handle(e);
        }
    } catch (Throwable e) {
        throw debug.handle(e);
    } finally {
        graph.checkCancellation();
    }
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) FrameMapBuilder(org.graalvm.compiler.lir.framemap.FrameMapBuilder) DebugContext(org.graalvm.compiler.debug.DebugContext) AbstractBlockBase(org.graalvm.compiler.core.common.cfg.AbstractBlockBase) NodeLIRBuilderTool(org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool) LIRGenerationResult(org.graalvm.compiler.lir.gen.LIRGenerationResult) LIRGenerationContext(org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext) LIR(org.graalvm.compiler.lir.LIR) Block(org.graalvm.compiler.nodes.cfg.Block) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) LIRGeneratorTool(org.graalvm.compiler.lir.gen.LIRGeneratorTool)

Example 9 with ScheduleResult

use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult 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 10 with ScheduleResult

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

the class EffectsPhase method runAnalysis.

@SuppressWarnings("try")
public boolean runAnalysis(StructuredGraph graph, PhaseContextT context) {
    boolean changed = false;
    CompilationAlarm compilationAlarm = CompilationAlarm.current();
    DebugContext debug = graph.getDebug();
    for (int iteration = 0; iteration < maxIterations && !compilationAlarm.hasExpired(); iteration++) {
        try (DebugContext.Scope s = debug.scope(debug.areScopesEnabled() ? "iteration " + iteration : null)) {
            ScheduleResult schedule;
            ControlFlowGraph cfg;
            if (unscheduled) {
                schedule = null;
                cfg = ControlFlowGraph.compute(graph, true, true, false, false);
            } else {
                new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph, false);
                schedule = graph.getLastSchedule();
                cfg = schedule.getCFG();
            }
            try (DebugContext.Scope scheduleScope = debug.scope("EffectsPhaseWithSchedule", schedule)) {
                Closure<?> closure = createEffectsClosure(context, schedule, cfg);
                ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
                if (closure.needsApplyEffects()) {
                    // apply the effects collected during this iteration
                    HashSetNodeEventListener listener = new HashSetNodeEventListener();
                    try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
                        closure.applyEffects();
                    }
                    if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
                        debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
                    }
                    new DeadCodeEliminationPhase(Required).apply(graph);
                    EconomicSet<Node> changedNodes = listener.getNodes();
                    for (Node node : graph.getNodes()) {
                        if (node instanceof Simplifiable) {
                            changedNodes.add(node);
                        }
                    }
                    postIteration(graph, context, changedNodes);
                }
                if (closure.hasChanged()) {
                    changed = true;
                } else {
                    break;
                }
            } catch (Throwable t) {
                throw debug.handle(t);
            }
        }
    }
    return changed;
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) CompilationAlarm(org.graalvm.compiler.core.common.util.CompilationAlarm) Node(org.graalvm.compiler.graph.Node) DebugContext(org.graalvm.compiler.debug.DebugContext) HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) DeadCodeEliminationPhase(org.graalvm.compiler.phases.common.DeadCodeEliminationPhase) Simplifiable(org.graalvm.compiler.graph.spi.Simplifiable)

Aggregations

ScheduleResult (org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult)38 Test (org.junit.Test)24 Block (org.graalvm.compiler.nodes.cfg.Block)14 Node (org.graalvm.compiler.graph.Node)10 SchedulePhase (org.graalvm.compiler.phases.schedule.SchedulePhase)9 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)8 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 ValueNode (org.graalvm.compiler.nodes.ValueNode)6 List (java.util.List)5 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)5 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)5 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)5 DebugContext (org.graalvm.compiler.debug.DebugContext)4 FixedNode (org.graalvm.compiler.nodes.FixedNode)4 FrameState (org.graalvm.compiler.nodes.FrameState)4 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)4 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)4 InitializeKlassNode (org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode)3 LoadConstantIndirectlyFixedNode (org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyFixedNode)3 LoadConstantIndirectlyNode (org.graalvm.compiler.hotspot.nodes.aot.LoadConstantIndirectlyNode)3