Search in sources :

Example 1 with HashSetNodeEventListener

use of org.graalvm.compiler.phases.common.util.HashSetNodeEventListener 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 2 with HashSetNodeEventListener

use of org.graalvm.compiler.phases.common.util.HashSetNodeEventListener in project graal by oracle.

the class IterativeConditionalEliminationPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, PhaseContext context) {
    HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NODE_ADDED);
    int count = 0;
    while (true) {
        try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
            new ConditionalEliminationPhase(fullSchedule).apply(graph, context);
        }
        if (listener.getNodes().isEmpty()) {
            break;
        }
        for (Node node : graph.getNodes()) {
            if (node instanceof Simplifiable) {
                listener.getNodes().add(node);
            }
        }
        canonicalizer.applyIncremental(graph, context, listener.getNodes());
        listener.getNodes().clear();
        if (++count > MAX_ITERATIONS) {
            throw new RetryableBailoutException("Number of iterations in ConditionalEliminationPhase phase exceeds %d", MAX_ITERATIONS);
        }
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) RetryableBailoutException(org.graalvm.compiler.core.common.RetryableBailoutException) Node(org.graalvm.compiler.graph.Node) Simplifiable(org.graalvm.compiler.graph.spi.Simplifiable)

Example 3 with HashSetNodeEventListener

use of org.graalvm.compiler.phases.common.util.HashSetNodeEventListener in project graal by oracle.

the class GraphChangeMonitoringPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, C context) {
    /*
         * Phase may add nodes but not end up using them so ignore additions. Nodes going dead and
         * having their inputs change are the main interesting differences.
         */
    HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NodeEvent.NODE_ADDED);
    StructuredGraph graphCopy = (StructuredGraph) graph.copy(graph.getDebug());
    DebugContext debug = graph.getDebug();
    try (NodeEventScope s = graphCopy.trackNodeEvents(listener)) {
        try (DebugContext.Scope s2 = debug.sandbox("WithoutMonitoring", null)) {
            super.run(graphCopy, context);
        } catch (Throwable t) {
            debug.handle(t);
        }
    }
    EconomicSet<Node> filteredNodes = EconomicSet.create(Equivalence.IDENTITY);
    for (Node n : listener.getNodes()) {
        if (n instanceof LogicConstantNode) {
        // Ignore LogicConstantNode since those are sometimes created and deleted as part of
        // running a phase.
        } else {
            filteredNodes.add(n);
        }
    }
    if (!filteredNodes.isEmpty()) {
        /* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */
        listener = new HashSetNodeEventListener();
        try (NodeEventScope s = graph.trackNodeEvents(listener)) {
            try (DebugContext.Scope s2 = debug.scope("WithGraphChangeMonitoring")) {
                if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
                    debug.dump(DebugContext.DETAILED_LEVEL, graph, "*** Before phase %s", getName());
                }
                super.run(graph, context);
                if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
                    debug.dump(DebugContext.DETAILED_LEVEL, graph, "*** After phase %s %s", getName(), filteredNodes);
                }
                debug.log("*** %s %s %s\n", message, graph, filteredNodes);
            }
        }
    } else {
        // Go ahead and run it normally even though it should have no effect
        super.run(graph, context);
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) Node(org.graalvm.compiler.graph.Node) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) DebugContext(org.graalvm.compiler.debug.DebugContext)

Example 4 with HashSetNodeEventListener

use of org.graalvm.compiler.phases.common.util.HashSetNodeEventListener 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)

Example 5 with HashSetNodeEventListener

use of org.graalvm.compiler.phases.common.util.HashSetNodeEventListener in project graal by oracle.

the class LoopPartialUnrollPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, PhaseContext context) {
    if (graph.hasLoops()) {
        HashSetNodeEventListener listener = new HashSetNodeEventListener();
        boolean changed = true;
        while (changed) {
            changed = false;
            try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
                LoopsData dataCounted = new LoopsData(graph);
                dataCounted.detectedCountedLoops();
                Graph.Mark mark = graph.getMark();
                boolean prePostInserted = false;
                for (LoopEx loop : dataCounted.countedLoops()) {
                    if (!LoopTransformations.isUnrollableLoop(loop)) {
                        continue;
                    }
                    if (getPolicies().shouldPartiallyUnroll(loop)) {
                        if (loop.loopBegin().isSimpleLoop()) {
                            // First perform the pre/post transformation and do the partial
                            // unroll when we come around again.
                            LoopTransformations.insertPrePostLoops(loop);
                            prePostInserted = true;
                        } else {
                            LoopTransformations.partialUnroll(loop);
                        }
                        changed = true;
                    }
                }
                dataCounted.deleteUnusedNodes();
                if (!listener.getNodes().isEmpty()) {
                    canonicalizer.applyIncremental(graph, context, listener.getNodes());
                    listener.getNodes().clear();
                }
                assert !prePostInserted || checkCounted(graph, mark);
            }
        }
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Graph(org.graalvm.compiler.graph.Graph) LoopsData(org.graalvm.compiler.loop.LoopsData) LoopEx(org.graalvm.compiler.loop.LoopEx)

Aggregations

HashSetNodeEventListener (org.graalvm.compiler.phases.common.util.HashSetNodeEventListener)5 NodeEventScope (org.graalvm.compiler.graph.Graph.NodeEventScope)4 Node (org.graalvm.compiler.graph.Node)4 DebugContext (org.graalvm.compiler.debug.DebugContext)2 Simplifiable (org.graalvm.compiler.graph.spi.Simplifiable)2 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)2 ControlFlowGraph (org.graalvm.compiler.nodes.cfg.ControlFlowGraph)2 EconomicSet (org.graalvm.collections.EconomicSet)1 RetryableBailoutException (org.graalvm.compiler.core.common.RetryableBailoutException)1 CompilationAlarm (org.graalvm.compiler.core.common.util.CompilationAlarm)1 Graph (org.graalvm.compiler.graph.Graph)1 LoopEx (org.graalvm.compiler.loop.LoopEx)1 LoopsData (org.graalvm.compiler.loop.LoopsData)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)1 LogicConstantNode (org.graalvm.compiler.nodes.LogicConstantNode)1 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)1 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)1