Search in sources :

Example 1 with ControlFlowGraph

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

the class FinalizeProfileNodesPhase method assignRandomSources.

private static void assignRandomSources(StructuredGraph graph) {
    ValueNode seed = graph.unique(new RandomSeedNode());
    ControlFlowGraph cfg = ControlFlowGraph.compute(graph, false, true, false, false);
    Map<LoopBeginNode, ValueNode> loopRandomValueCache = new HashMap<>();
    for (ProfileNode node : getProfileNodes(graph)) {
        ValueNode random;
        Block block = cfg.blockFor(node);
        Loop<Block> loop = block.getLoop();
        // pseudo-random number generator into the loop
        if (loop != null) {
            LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
            random = loopRandomValueCache.get(loopBegin);
            if (random == null) {
                PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(NodeView.DEFAULT), loopBegin));
                phi.addInput(seed);
                // X_{n+1} = a*X_n + c, using glibc-like constants
                ValueNode a = ConstantNode.forInt(1103515245, graph);
                ValueNode c = ConstantNode.forInt(12345, graph);
                ValueNode next = graph.addOrUniqueWithInputs(new AddNode(c, new MulNode(phi, a)));
                for (int i = 0; i < loopBegin.getLoopEndCount(); i++) {
                    phi.addInput(next);
                }
                random = phi;
                loopRandomValueCache.put(loopBegin, random);
            }
        } else {
            // Graal doesn't compile methods with irreducible loops. So all profile nodes that
            // are not in a loop are guaranteed to be executed at most once. We feed the seed
            // value to such nodes directly.
            random = seed;
        }
        node.setRandom(random);
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) HashMap(java.util.HashMap) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ProfileNode(org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block) RandomSeedNode(org.graalvm.compiler.hotspot.nodes.profiling.RandomSeedNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode)

Example 2 with ControlFlowGraph

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

the class ConditionalEliminationPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, PhaseContext context) {
    try (DebugContext.Scope s = graph.getDebug().scope("DominatorConditionalElimination")) {
        BlockMap<List<Node>> blockToNodes = null;
        NodeMap<Block> nodeToBlock = null;
        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
        if (fullSchedule) {
            if (moveGuards) {
                cfg.visitDominatorTree(new MoveGuardsUpwards(), graph.hasValueProxies());
            }
            try (DebugContext.Scope scheduleScope = graph.getDebug().scope(SchedulePhase.class)) {
                SchedulePhase.run(graph, SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER, cfg);
            } catch (Throwable t) {
                throw graph.getDebug().handle(t);
            }
            ScheduleResult r = graph.getLastSchedule();
            blockToNodes = r.getBlockToNodesMap();
            nodeToBlock = r.getNodeToBlockMap();
        } else {
            nodeToBlock = cfg.getNodeToBlock();
            blockToNodes = getBlockToNodes(cfg);
        }
        ControlFlowGraph.RecursiveVisitor<?> visitor = createVisitor(graph, cfg, blockToNodes, nodeToBlock, context);
        cfg.visitDominatorTree(visitor, graph.hasValueProxies());
    }
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) AbstractControlFlowGraph(org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) Block(org.graalvm.compiler.nodes.cfg.Block) List(java.util.List) DebugContext(org.graalvm.compiler.debug.DebugContext)

Example 3 with ControlFlowGraph

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

the class DeoptimizationGroupingPhase method run.

@Override
protected void run(StructuredGraph graph, MidTierContext context) {
    ControlFlowGraph cfg = null;
    for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
        FixedNode target = null;
        PhiNode reasonActionPhi = null;
        PhiNode speculationPhi = null;
        List<AbstractDeoptimizeNode> obsoletes = null;
        for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
            if (target == null) {
                target = deopt;
            } else {
                if (cfg == null) {
                    cfg = ControlFlowGraph.compute(graph, true, true, false, false);
                }
                AbstractMergeNode merge;
                if (target instanceof AbstractDeoptimizeNode) {
                    merge = graph.add(new MergeNode());
                    EndNode firstEnd = graph.add(new EndNode());
                    ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
                    ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
                    reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
                    speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
                    merge.addForwardEnd(firstEnd);
                    reasonActionPhi.addInput(actionAndReason);
                    speculationPhi.addInput(speculation);
                    target.replaceAtPredecessor(firstEnd);
                    exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
                    merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
                    obsoletes = new LinkedList<>();
                    obsoletes.add((AbstractDeoptimizeNode) target);
                    target = merge;
                } else {
                    merge = (AbstractMergeNode) target;
                }
                EndNode newEnd = graph.add(new EndNode());
                merge.addForwardEnd(newEnd);
                reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
                speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
                deopt.replaceAtPredecessor(newEnd);
                exitLoops(deopt, newEnd, cfg);
                obsoletes.add(deopt);
            }
        }
        if (obsoletes != null) {
            ((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
            for (AbstractDeoptimizeNode obsolete : obsoletes) {
                obsolete.safeDelete();
            }
        }
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) EndNode(org.graalvm.compiler.nodes.EndNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 4 with ControlFlowGraph

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

the class FloatingReadPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph) {
    EconomicMap<LoopBeginNode, EconomicSet<LocationIdentity>> modifiedInLoops = null;
    if (graph.hasLoops()) {
        modifiedInLoops = EconomicMap.create(Equivalence.IDENTITY);
        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
        for (Loop<?> l : cfg.getLoops()) {
            HIRLoop loop = (HIRLoop) l;
            processLoop(loop, modifiedInLoops);
        }
    }
    HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES));
    try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
        ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, createFloatingReads, createMemoryMapNodes), graph.start(), new MemoryMapImpl(graph.start()));
    }
    for (Node n : removeExternallyUsedNodes(listener.getNodes())) {
        if (n.isAlive() && n instanceof FloatingNode) {
            n.replaceAtUsages(null);
            GraphUtil.killWithUnusedFloatingInputs(n);
        }
    }
    if (createFloatingReads) {
        assert !graph.isAfterFloatingReadPhase();
        graph.setAfterFloatingReadPhase(true);
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) FloatingAccessNode(org.graalvm.compiler.nodes.memory.FloatingAccessNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) StartNode(org.graalvm.compiler.nodes.StartNode) FloatingReadNode(org.graalvm.compiler.nodes.memory.FloatingReadNode) MemoryNode(org.graalvm.compiler.nodes.memory.MemoryNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MemoryAnchorNode(org.graalvm.compiler.nodes.memory.MemoryAnchorNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) MemoryMapNode(org.graalvm.compiler.nodes.memory.MemoryMapNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) FloatableAccessNode(org.graalvm.compiler.nodes.memory.FloatableAccessNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) PhiNode(org.graalvm.compiler.nodes.PhiNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) EconomicSet(org.graalvm.collections.EconomicSet) HIRLoop(org.graalvm.compiler.nodes.cfg.HIRLoop)

Example 5 with ControlFlowGraph

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

the class ProfileCompiledMethodsPhase method run.

@Override
protected void run(StructuredGraph graph) {
    SchedulePhase schedule = new SchedulePhase(graph.getOptions());
    schedule.apply(graph, false);
    ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    for (Loop<Block> loop : cfg.getLoops()) {
        double loopProbability = cfg.blockFor(loop.getHeader().getBeginNode()).probability();
        if (loopProbability > (1D / Integer.MAX_VALUE)) {
            addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), graph.getLastSchedule(), cfg);
        }
    }
    // don't put the counter increase directly after the start (problems with OSR)
    FixedWithNextNode current = graph.start();
    while (current.next() instanceof FixedWithNextNode) {
        current = (FixedWithNextNode) current.next();
    }
    addSectionCounters(current, Arrays.asList(cfg.getBlocks()), cfg.getLoops(), graph.getLastSchedule(), cfg);
    if (WITH_INVOKES) {
        for (Node node : graph.getNodes()) {
            if (node instanceof Invoke) {
                Invoke invoke = (Invoke) node;
                DynamicCounterNode.addCounterBefore(GROUP_NAME_INVOKES, invoke.callTarget().targetName(), 1, true, invoke.asNode());
            }
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ReinterpretNode(org.graalvm.compiler.nodes.calc.ReinterpretNode) RemNode(org.graalvm.compiler.nodes.calc.RemNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) IntegerDivRemNode(org.graalvm.compiler.nodes.calc.IntegerDivRemNode) BinaryNode(org.graalvm.compiler.nodes.calc.BinaryNode) SwitchNode(org.graalvm.compiler.nodes.extended.SwitchNode) NotNode(org.graalvm.compiler.nodes.calc.NotNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AccessMonitorNode(org.graalvm.compiler.nodes.java.AccessMonitorNode) AbstractNewObjectNode(org.graalvm.compiler.nodes.java.AbstractNewObjectNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) ConvertNode(org.graalvm.compiler.nodes.calc.ConvertNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) DynamicCounterNode(org.graalvm.compiler.nodes.debug.DynamicCounterNode) FloatDivNode(org.graalvm.compiler.nodes.calc.FloatDivNode) Block(org.graalvm.compiler.nodes.cfg.Block) Invoke(org.graalvm.compiler.nodes.Invoke)

Aggregations

ControlFlowGraph (org.graalvm.compiler.nodes.cfg.ControlFlowGraph)17 Block (org.graalvm.compiler.nodes.cfg.Block)12 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)6 FixedNode (org.graalvm.compiler.nodes.FixedNode)6 DebugContext (org.graalvm.compiler.debug.DebugContext)5 Node (org.graalvm.compiler.graph.Node)5 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)5 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)5 PhiNode (org.graalvm.compiler.nodes.PhiNode)4 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)4 List (java.util.List)3 SchedulePhase (org.graalvm.compiler.phases.schedule.SchedulePhase)3 ArrayList (java.util.ArrayList)2 BlockMap (org.graalvm.compiler.core.common.cfg.BlockMap)2 NodeEventScope (org.graalvm.compiler.graph.Graph.NodeEventScope)2 LIR (org.graalvm.compiler.lir.LIR)2 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 EndNode (org.graalvm.compiler.nodes.EndNode)2 IfNode (org.graalvm.compiler.nodes.IfNode)2