Search in sources :

Example 1 with TimerCollection

use of com.oracle.truffle.espresso.perf.TimerCollection in project graal by oracle.

the class LivenessAnalysis method analyze.

@SuppressWarnings("try")
public static LivenessAnalysis analyze(Method.MethodVersion methodVersion) {
    EspressoContext context = methodVersion.getMethod().getContext();
    if (!enableLivenessAnalysis(context, methodVersion)) {
        return NO_ANALYSIS;
    }
    Method method = methodVersion.getMethod();
    TimerCollection scope = method.getContext().getTimers();
    try (DebugCloseable liveness = LIVENESS_TIMER.scope(scope)) {
        Graph<? extends LinkedBlock> graph;
        try (DebugCloseable builder = BUILDER_TIMER.scope(scope)) {
            graph = GraphBuilder.build(method);
        }
        // Transform the graph into a more manageable graph consisting of only the history of
        // load/stores.
        LoadStoreFinder loadStoreClosure;
        try (DebugCloseable loadStore = LOADSTORE_TIMER.scope(scope)) {
            loadStoreClosure = new LoadStoreFinder(graph, method);
            loadStoreClosure.analyze();
        }
        // Computes the entry/end live sets for each variable for each block.
        BlockBoundaryFinder blockBoundaryFinder;
        try (DebugCloseable boundary = STATE_TIMER.scope(scope)) {
            blockBoundaryFinder = new BlockBoundaryFinder(methodVersion, loadStoreClosure.result());
            DepthFirstBlockIterator.analyze(method, graph, blockBoundaryFinder);
        }
        try (DebugCloseable propagation = PROPAGATE_TIMER.scope(scope)) {
            // Forces loop ends to inherit the loop entry state, and propagates the changes.
            LoopPropagatorClosure loopPropagation = new LoopPropagatorClosure(graph, blockBoundaryFinder.result());
            while (loopPropagation.process(graph)) {
            /*
                     * This loop should iterate at MOST exactly the maximum number of nested loops
                     * in the method.
                     *
                     * The reasoning is the following:
                     *
                     * - The only reason a new iteration is required is when a loop entry's state
                     * gets modified by the previous iteration.
                     *
                     * - This can happen only if a new live variable gets propagated from an outer
                     * loop.
                     *
                     * - Which means that we do not need to re-propagate the state of the outermost
                     * loop.
                     */
            }
        }
        // frees as early as possible each dead local.
        try (DebugCloseable actionFinder = ACTION_TIMER.scope(scope)) {
            Builder builder = new Builder(graph, methodVersion, blockBoundaryFinder.result());
            builder.build();
            return new LivenessAnalysis(builder.actions, builder.edge, builder.onStart);
        }
    }
}
Also used : TimerCollection(com.oracle.truffle.espresso.perf.TimerCollection) GraphBuilder(com.oracle.truffle.espresso.analysis.GraphBuilder) EspressoContext(com.oracle.truffle.espresso.runtime.EspressoContext) Method(com.oracle.truffle.espresso.impl.Method) DebugCloseable(com.oracle.truffle.espresso.perf.DebugCloseable)

Aggregations

GraphBuilder (com.oracle.truffle.espresso.analysis.GraphBuilder)1 Method (com.oracle.truffle.espresso.impl.Method)1 DebugCloseable (com.oracle.truffle.espresso.perf.DebugCloseable)1 TimerCollection (com.oracle.truffle.espresso.perf.TimerCollection)1 EspressoContext (com.oracle.truffle.espresso.runtime.EspressoContext)1