TraceBuilderPhase.java revision 12651:6ef01bd40ce2
1190207Srpaulo/*
217680Spst * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
339297Sfenner * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
417680Spst *
517680Spst * This code is free software; you can redistribute it and/or modify it
617680Spst * under the terms of the GNU General Public License version 2 only, as
717680Spst * published by the Free Software Foundation.
817680Spst *
917680Spst * This code is distributed in the hope that it will be useful, but WITHOUT
1017680Spst * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1117680Spst * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1217680Spst * version 2 for more details (a copy is included in the LICENSE file that
1317680Spst * accompanied this code).
1417680Spst *
1517680Spst * You should have received a copy of the GNU General Public License version
1617680Spst * 2 along with this work; if not, write to the Free Software Foundation,
1717680Spst * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1817680Spst *
1917680Spst * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2017680Spst * or visit www.oracle.com if you need additional information or have any
2117680Spst * questions.
2217680Spst */
2317680Spstpackage org.graalvm.compiler.lir.alloc.trace;
24127668Sbms
25127668Sbmsimport static org.graalvm.compiler.lir.alloc.trace.TraceUtil.isTrivialTrace;
26127668Sbms
27127668Sbmsimport java.util.List;
28127668Sbms
29127668Sbmsimport org.graalvm.compiler.core.common.alloc.BiDirectionalTraceBuilder;
3017680Spstimport org.graalvm.compiler.core.common.alloc.SingleBlockTraceBuilder;
31127668Sbmsimport org.graalvm.compiler.core.common.alloc.Trace;
32127668Sbmsimport org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
33127668Sbmsimport org.graalvm.compiler.core.common.alloc.TraceBuilderResult.TrivialTracePredicate;
34190207Srpauloimport org.graalvm.compiler.core.common.alloc.TraceStatisticsPrinter;
35127668Sbmsimport org.graalvm.compiler.core.common.alloc.UniDirectionalTraceBuilder;
36127668Sbmsimport org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
37127668Sbmsimport org.graalvm.compiler.debug.Debug;
38127668Sbmsimport org.graalvm.compiler.debug.GraalError;
3917680Spstimport org.graalvm.compiler.lir.LIR;
4017680Spstimport org.graalvm.compiler.lir.gen.LIRGenerationResult;
4117680Spstimport org.graalvm.compiler.lir.phases.AllocationPhase;
42127668Sbmsimport org.graalvm.compiler.options.EnumOptionValue;
43127668Sbmsimport org.graalvm.compiler.options.Option;
44190207Srpauloimport org.graalvm.compiler.options.OptionType;
45127668Sbmsimport org.graalvm.compiler.options.OptionValue;
46127668Sbms
47146773Ssamimport jdk.vm.ci.code.TargetDescription;
4817680Spst
4917680Spstpublic class TraceBuilderPhase extends AllocationPhase {
5017680Spst
5117680Spst    public enum TraceBuilder {
52172683Smlaier        UniDirectional,
5339297Sfenner        BiDirectional,
54127668Sbms        SingleBlock
5517680Spst    }
5617680Spst
57190207Srpaulo    public static class Options {
5817680Spst        // @formatter:off
59190207Srpaulo        @Option(help = "Trace building algorithm.", type = OptionType.Debug)
60190207Srpaulo        public static final EnumOptionValue<TraceBuilder> TraceBuilding = new EnumOptionValue<>(TraceBuilder.UniDirectional);
6117680Spst        @Option(help = "Schedule trivial traces as early as possible.", type = OptionType.Debug)
6217680Spst        public static final OptionValue<Boolean> TraceRAScheduleTrivialTracesEarly = new OptionValue<>(true);
6317680Spst        // @formatter:on
6417680Spst    }
6517680Spst
6617680Spst    private static final int TRACE_LOG_LEVEL = 1;
6717680Spst    public static final int TRACE_DUMP_LEVEL = 3;
6817680Spst
6917680Spst    @Override
70146773Ssam    protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
71127668Sbms        AbstractBlockBase<?>[] linearScanOrder = lirGenRes.getLIR().linearScanOrder();
72127668Sbms        AbstractBlockBase<?> startBlock = linearScanOrder[0];
73127668Sbms        LIR lir = lirGenRes.getLIR();
7417680Spst        assert startBlock.equals(lir.getControlFlowGraph().getStartBlock());
75127668Sbms
76146773Ssam        final TraceBuilderResult traceBuilderResult = getTraceBuilderResult(lir, startBlock, linearScanOrder);
77146773Ssam
78127668Sbms        if (Debug.isLogEnabled(TRACE_LOG_LEVEL)) {
79127668Sbms            List<Trace> traces = traceBuilderResult.getTraces();
80127668Sbms            for (int i = 0; i < traces.size(); i++) {
81127668Sbms                Trace trace = traces.get(i);
82127668Sbms                Debug.log(TRACE_LOG_LEVEL, "Trace %5d: %s%s", i, trace, isTrivialTrace(lirGenRes.getLIR(), trace) ? " (trivial)" : "");
83127668Sbms            }
84127668Sbms        }
85127668Sbms        TraceStatisticsPrinter.printTraceStatistics(traceBuilderResult, lirGenRes.getCompilationUnitName());
86127668Sbms        Debug.dump(TRACE_DUMP_LEVEL, traceBuilderResult, "After TraceBuilding");
87127668Sbms        context.contextAdd(traceBuilderResult);
88127668Sbms    }
89127668Sbms
90127668Sbms    private static TraceBuilderResult getTraceBuilderResult(LIR lir, AbstractBlockBase<?> startBlock, AbstractBlockBase<?>[] linearScanOrder) {
91190207Srpaulo        TraceBuilderResult.TrivialTracePredicate pred = getTrivialTracePredicate(lir);
92190207Srpaulo
93190207Srpaulo        TraceBuilder selectedTraceBuilder = Options.TraceBuilding.getValue();
94190207Srpaulo        Debug.log(TRACE_LOG_LEVEL, "Building Traces using %s", selectedTraceBuilder);
95162017Ssam        switch (Options.TraceBuilding.getValue()) {
96127668Sbms            case SingleBlock:
97127668Sbms                return SingleBlockTraceBuilder.computeTraces(startBlock, linearScanOrder, pred);
98127668Sbms            case BiDirectional:
99127668Sbms                return BiDirectionalTraceBuilder.computeTraces(startBlock, linearScanOrder, pred);
100146773Ssam            case UniDirectional:
101146773Ssam                return UniDirectionalTraceBuilder.computeTraces(startBlock, linearScanOrder, pred);
102146773Ssam        }
103146773Ssam        throw GraalError.shouldNotReachHere("Unknown trace building algorithm: " + Options.TraceBuilding.getValue());
104146773Ssam    }
105146773Ssam
106146773Ssam    public static TraceBuilderResult.TrivialTracePredicate getTrivialTracePredicate(LIR lir) {
107146773Ssam        if (!Options.TraceRAScheduleTrivialTracesEarly.getValue()) {
108146773Ssam            return null;
109146773Ssam        }
110146773Ssam        return new TrivialTracePredicate() {
11117680Spst            @Override
11217680Spst            public boolean isTrivialTrace(Trace trace) {
11317680Spst                return TraceUtil.isTrivialTrace(lir, trace);
11417680Spst            }
11517680Spst        };
11617680Spst    }
11717680Spst}
11817680Spst