Search in sources :

Example 11 with LoopsData

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

the class LoopPartialUnrollPhase method checkCounted.

private static boolean checkCounted(StructuredGraph graph, LoopsDataProvider loopsDataProvider, Graph.Mark mark) {
    LoopsData dataCounted;
    dataCounted = loopsDataProvider.getLoopsData(graph);
    dataCounted.detectedCountedLoops();
    for (LoopEx anyLoop : dataCounted.loops()) {
        if (graph.isNew(mark, anyLoop.loopBegin())) {
            assert anyLoop.isCounted() : "pre/post transformation loses counted loop " + anyLoop.loopBegin();
        }
    }
    return true;
}
Also used : LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx)

Example 12 with LoopsData

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

the class LoopPartialUnrollPhase method unroll.

@SuppressWarnings("try")
private void unroll(StructuredGraph graph, CoreProviders context) {
    EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
    boolean changed = true;
    EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides = null;
    boolean prePostInserted = false;
    while (changed) {
        changed = false;
        try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
            LoopsData dataCounted = context.getLoopsDataProvider().getLoopsData(graph);
            dataCounted.detectedCountedLoops();
            Graph.Mark mark = graph.getMark();
            for (LoopEx loop : dataCounted.countedLoops()) {
                if (!LoopTransformations.isUnrollableLoop(loop)) {
                    continue;
                }
                if (getPolicies().shouldPartiallyUnroll(loop, context)) {
                    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;
                        changed = true;
                    } else if (prePostInserted) {
                        if (opaqueUnrolledStrides == null) {
                            opaqueUnrolledStrides = EconomicMap.create(Equivalence.IDENTITY);
                        }
                        LoopTransformations.partialUnroll(loop, opaqueUnrolledStrides);
                        changed = true;
                    }
                }
            }
            dataCounted.deleteUnusedNodes();
            if (!listener.getNodes().isEmpty()) {
                canonicalizer.applyIncremental(graph, context, listener.getNodes());
                listener.getNodes().clear();
            }
            assert !prePostInserted || checkCounted(graph, context.getLoopsDataProvider(), mark);
        }
    }
    if (opaqueUnrolledStrides != null) {
        try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
            for (OpaqueNode opaque : opaqueUnrolledStrides.getValues()) {
                opaque.remove();
            }
            if (!listener.getNodes().isEmpty()) {
                canonicalizer.applyIncremental(graph, context, listener.getNodes());
            }
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) Graph(org.graalvm.compiler.graph.Graph) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) EconomicSetNodeEventListener(org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener)

Example 13 with LoopsData

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

the class LoopSafepointEliminationPhase method run.

@Override
protected final void run(StructuredGraph graph, MidTierContext context) {
    LoopsData loops = context.getLoopsDataProvider().getLoopsData(graph);
    loops.detectedCountedLoops();
    for (LoopEx loop : loops.countedLoops()) {
        if (loop.loop().getChildren().isEmpty() && (loop.loopBegin().isPreLoop() || loop.loopBegin().isPostLoop() || loopIsIn32BitRange(loop))) {
            boolean hasSafepoint = false;
            for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
                hasSafepoint |= loopEnd.canSafepoint();
            }
            if (hasSafepoint) {
                if (!loop.counted().counterNeverOverflows()) {
                    // Counter can overflow, need to create a guard.
                    boolean allowsLoopLimitChecks = context.getOptimisticOptimizations().useLoopLimitChecks(graph.getOptions());
                    boolean allowsFloatingGuards = graph.getGuardsStage().allowsFloatingGuards();
                    if (allowsLoopLimitChecks && allowsFloatingGuards) {
                        loop.counted().createOverFlowGuard();
                    } else {
                        // Cannot disable this safepoint, because the loop could overflow.
                        continue;
                    }
                }
                loop.loopBegin().disableSafepoint();
                onSafepointDisabledLoopBegin(loop);
            }
        }
    }
    for (LoopEx loop : loops.loops()) {
        for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
            Block b = loops.getCFG().blockFor(loopEnd);
            blocks: while (b != loop.loop().getHeader()) {
                assert b != null;
                for (FixedNode node : b.getNodes()) {
                    boolean canDisableSafepoint = canDisableSafepoint(node, context);
                    boolean disabledInSubclass = onCallInLoop(loopEnd, node);
                    if (canDisableSafepoint) {
                        loopEnd.disableSafepoint();
                        // we can only stop if subclasses also say we can stop iterating blocks
                        if (disabledInSubclass) {
                            break blocks;
                        }
                    }
                }
                b = b.getDominator();
            }
        }
    }
    loops.deleteUnusedNodes();
}
Also used : LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx) Block(org.graalvm.compiler.nodes.cfg.Block) FixedNode(org.graalvm.compiler.nodes.FixedNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 14 with LoopsData

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

the class LoopUnswitchingPhase method run.

@Override
protected void run(StructuredGraph graph, CoreProviders context) {
    DebugContext debug = graph.getDebug();
    if (graph.hasLoops()) {
        boolean unswitched;
        do {
            unswitched = false;
            final LoopsData dataUnswitch = context.getLoopsDataProvider().getLoopsData(graph);
            for (LoopEx loop : dataUnswitch.outerFirst()) {
                if (getPolicies().shouldTryUnswitch(loop)) {
                    List<ControlSplitNode> controlSplits = LoopTransformations.findUnswitchable(loop);
                    if (controlSplits != null) {
                        UNSWITCH_CANDIDATES.increment(debug);
                        UnswitchingDecision decision = getPolicies().shouldUnswitch(loop, controlSplits);
                        if (decision.shouldUnswitch()) {
                            if (debug.isLogEnabled()) {
                                logUnswitch(loop, controlSplits);
                            }
                            LoopTransformations.unswitch(loop, controlSplits, decision.isTrivial());
                            debug.dump(DebugContext.DETAILED_LEVEL, graph, "After unswitch %s", controlSplits);
                            UNSWITCHED.increment(debug);
                            unswitched = true;
                            break;
                        }
                    }
                } else {
                    UNSWITCH_EARLY_REJECTS.increment(debug);
                }
            }
        } while (unswitched);
    }
}
Also used : LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DebugContext(org.graalvm.compiler.debug.DebugContext) UnswitchingDecision(org.graalvm.compiler.nodes.loop.LoopPolicies.UnswitchingDecision)

Example 15 with LoopsData

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

the class LoopPartialUnrollTest method buildGraph.

@SuppressWarnings("try")
public StructuredGraph buildGraph(String name, boolean partialUnroll) {
    CompilationIdentifier id = new CompilationIdentifier() {

        @Override
        public String toString(Verbosity verbosity) {
            return name;
        }
    };
    ResolvedJavaMethod method = getResolvedJavaMethod(name);
    OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.Options.UnrollMaxIterations, 2);
    StructuredGraph graph = parse(builder(method, StructuredGraph.AllowAssumptions.YES, id, options), getEagerGraphBuilderSuite());
    try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
        MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
        CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
        canonicalizer.apply(graph, context);
        new RemoveValueProxyPhase().apply(graph);
        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
        new FloatingReadPhase().apply(graph);
        new DeadCodeEliminationPhase().apply(graph);
        new ConditionalEliminationPhase(true).apply(graph, context);
        new GuardLoweringPhase().apply(graph, context);
        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
        new FrameStateAssignmentPhase().apply(graph);
        new DeoptimizationGroupingPhase().apply(graph, context);
        canonicalizer.apply(graph, context);
        new ConditionalEliminationPhase(true).apply(graph, context);
        if (partialUnroll) {
            LoopsData dataCounted = getDefaultMidTierContext().getLoopsDataProvider().getLoopsData(graph);
            dataCounted.detectedCountedLoops();
            assertTrue(!dataCounted.countedLoops().isEmpty(), "must have counted loops");
            for (LoopEx loop : dataCounted.countedLoops()) {
                LoopFragmentInside newSegment = loop.inside().duplicate();
                newSegment.insertWithinAfter(loop, null);
            }
            canonicalizer.apply(graph, getDefaultMidTierContext());
        }
        new DeadCodeEliminationPhase().apply(graph);
        canonicalizer.apply(graph, context);
        graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "before compare");
        return graph;
    } catch (Throwable e) {
        throw getDebugContext().handle(e);
    }
}
Also used : CompilationIdentifier(org.graalvm.compiler.core.common.CompilationIdentifier) FrameStateAssignmentPhase(org.graalvm.compiler.phases.common.FrameStateAssignmentPhase) LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) OptionValues(org.graalvm.compiler.options.OptionValues) LoopFragmentInside(org.graalvm.compiler.nodes.loop.LoopFragmentInside) RemoveValueProxyPhase(org.graalvm.compiler.phases.common.RemoveValueProxyPhase) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) FloatingReadPhase(org.graalvm.compiler.phases.common.FloatingReadPhase) MidTierContext(org.graalvm.compiler.phases.tiers.MidTierContext) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx) ConditionalEliminationPhase(org.graalvm.compiler.phases.common.ConditionalEliminationPhase) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) DeoptimizationGroupingPhase(org.graalvm.compiler.phases.common.DeoptimizationGroupingPhase) DeadCodeEliminationPhase(org.graalvm.compiler.phases.common.DeadCodeEliminationPhase) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Aggregations

LoopsData (org.graalvm.compiler.nodes.loop.LoopsData)23 LoopEx (org.graalvm.compiler.nodes.loop.LoopEx)19 DebugContext (org.graalvm.compiler.debug.DebugContext)8 Block (org.graalvm.compiler.nodes.cfg.Block)5 Node (org.graalvm.compiler.graph.Node)4 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 GraalCompilerTest (org.graalvm.compiler.core.test.GraalCompilerTest)3 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)3 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 DeadCodeEliminationPhase (org.graalvm.compiler.phases.common.DeadCodeEliminationPhase)3 HashSet (java.util.HashSet)2 SpeculationLog (jdk.vm.ci.meta.SpeculationLog)2 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 FixedNode (org.graalvm.compiler.nodes.FixedNode)2 FrameState (org.graalvm.compiler.nodes.FrameState)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)2 Test (org.junit.Test)2 BytecodePosition (jdk.vm.ci.code.BytecodePosition)1