Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/optimizer.cpp

Revision 1650:40bd4a0d4870, 8.6 kB (checked in by Tomas Lindquist Olsen, 2 years ago)

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.

Line 
1 #include "gen/optimizer.h"
2 #include "gen/cl_helpers.h"
3
4 #include "gen/passes/Passes.h"
5
6 #include "llvm/PassManager.h"
7 #include "llvm/LinkAllPasses.h"
8 #include "llvm/Analysis/LoopPass.h"
9 #include "llvm/Analysis/Verifier.h"
10 #include "llvm/Target/TargetData.h"
11 #include "llvm/Support/CommandLine.h"
12 #include "llvm/Support/PassNameParser.h"
13
14 #include "root.h"       // error()
15 #include <cstring>      // strcmp();
16
17 using namespace llvm;
18
19 // Allow the user to specify specific optimizations to run.
20 static cl::list<const PassInfo*, bool, PassNameParser>
21     passList(
22         cl::desc("Running specific optimizations:"),
23         cl::Hidden      // to clean up --help output
24     );
25
26 static cl::opt<unsigned char> optimizeLevel(
27     cl::desc("Setting the optimization level:"),
28     cl::ZeroOrMore,
29     cl::values(
30         clEnumValN(2, "O",  "Equivalent to -O2"),
31         clEnumValN(0, "O0", "No optimizations (default)"),
32         clEnumValN(1, "O1", "Simple optimizations"),
33         clEnumValN(2, "O2", "Good optimizations"),
34         clEnumValN(3, "O3", "Aggressive optimizations"),
35         clEnumValN(4, "O4", "Link-time optimization"), //  not implemented?
36         clEnumValN(5, "O5", "Link-time optimization"), //  not implemented?
37         clEnumValEnd),
38     cl::init(0));
39
40 static cl::opt<bool>
41 verifyEach("verify-each",
42     cl::desc("Run verifier after each optimization pass"),
43     cl::Hidden,
44     cl::ZeroOrMore);
45
46 static cl::opt<bool>
47 disableLangSpecificPasses("disable-d-passes",
48     cl::desc("Disable D-specific passes in -O<N>"),
49     cl::ZeroOrMore);
50
51 static cl::opt<bool>
52 disableSimplifyRuntimeCalls("disable-simplify-drtcalls",
53     cl::desc("Disable simplification of runtime calls in -O<N>"),
54     cl::ZeroOrMore);
55
56 static cl::opt<bool>
57 disableGCToStack("disable-gc2stack",
58     cl::desc("Disable promotion of GC allocations to stack memory in -O<N>"),
59     cl::ZeroOrMore);
60
61 static cl::opt<opts::BoolOrDefaultAdapter, false, opts::FlagParser>
62 enableInlining("inlining",
63     cl::desc("(*) Enable function inlining in -O<N>"),
64     cl::ZeroOrMore);
65
66 // Determine whether or not to run the inliner as part of the default list of
67 // optimization passes.
68 // If not explicitly specified, treat as false for -O0-2, and true for -O3.
69 bool doInline() {
70     return enableInlining == cl::BOU_TRUE
71         || (enableInlining == cl::BOU_UNSET && optimizeLevel >= 3);
72 }
73
74 // Determine whether the inliner will be run.
75 bool willInline() {
76     if (doInline())
77         return true;
78     // It may also have been specified explicitly on the command line as an explicit pass
79     typedef cl::list<const PassInfo*, bool, PassNameParser> PL;
80     for (PL::iterator I = passList.begin(), E = passList.end(); I != E; ++I) {
81         if (!std::strcmp((*I)->getPassArgument(), "inline"))
82             return true;
83     }
84     return false;
85 }
86
87 // Some extra accessors for the linker: (llvm-ld version only, currently unused?)
88 int optLevel() {
89     return optimizeLevel;
90 }
91
92 bool optimize() {
93     return optimizeLevel || doInline() || !passList.empty();
94 }
95
96 static void addPass(PassManager& pm, Pass* pass) {
97     pm.add(pass);
98
99     if (verifyEach) pm.add(createVerifierPass());
100 }
101
102 // this function inserts some or all of the std-compile-opts passes depending on the
103 // optimization level given.
104 static void addPassesForOptLevel(PassManager& pm) {
105     // -O1
106     if (optimizeLevel >= 1)
107     {
108         //addPass(pm, createStripDeadPrototypesPass());
109         addPass(pm, createGlobalDCEPass());
110         addPass(pm, createPromoteMemoryToRegisterPass());
111         addPass(pm, createCFGSimplificationPass());
112         if (optimizeLevel == 1)
113             addPass(pm, createPromoteMemoryToRegisterPass());
114         else
115             addPass(pm, createScalarReplAggregatesPass());
116         addPass(pm, createGlobalOptimizerPass());
117     }
118
119     // -O2
120     if (optimizeLevel >= 2)
121     {
122         addPass(pm, createIPConstantPropagationPass());
123         addPass(pm, createDeadArgEliminationPass());
124         addPass(pm, createInstructionCombiningPass());
125         addPass(pm, createCFGSimplificationPass());
126         addPass(pm, createPruneEHPass());
127         addPass(pm, createFunctionAttrsPass());
128         addPass(pm, createTailCallEliminationPass());
129         addPass(pm, createCFGSimplificationPass());
130         addPass(pm, createGVNPass());
131     }
132
133     // -inline
134     if (doInline()) {
135         addPass(pm, createFunctionInliningPass());
136
137         if (optimizeLevel >= 2) {
138             // Run some optimizations to clean up after inlining.
139             addPass(pm, createScalarReplAggregatesPass());
140             addPass(pm, createInstructionCombiningPass());
141             // -instcombine + gvn == devirtualization :)
142             addPass(pm, createGVNPass());
143
144             // Inline again, to catch things like now nonvirtual
145             // function calls, foreach delegates passed to inlined
146             // opApply's, etc. where the actual function being called
147             // wasn't known during the first inliner pass.
148             addPass(pm, createFunctionInliningPass());
149         }
150     }
151
152     if (optimizeLevel >= 2) {
153         if (!disableLangSpecificPasses) {
154             if (!disableSimplifyRuntimeCalls)
155                 addPass(pm, createSimplifyDRuntimeCalls());
156
157 #if USE_METADATA
158             if (!disableGCToStack)
159                 addPass(pm, createGarbageCollect2Stack());
160 #endif // USE_METADATA
161         }
162         // Run some clean-up passes
163         addPass(pm, createInstructionCombiningPass());
164         addPass(pm, createScalarReplAggregatesPass());
165         addPass(pm, createCFGSimplificationPass());
166         addPass(pm, createInstructionCombiningPass());
167     }
168
169     // -O3
170     if (optimizeLevel >= 3)
171     {
172         addPass(pm, createArgumentPromotionPass());
173         addPass(pm, createTailDuplicationPass());
174         addPass(pm, createSimplifyLibCallsPass());
175         addPass(pm, createInstructionCombiningPass());
176         addPass(pm, createJumpThreadingPass());
177         addPass(pm, createCFGSimplificationPass());
178         addPass(pm, createScalarReplAggregatesPass());
179         addPass(pm, createInstructionCombiningPass());
180         addPass(pm, createConstantPropagationPass());
181
182         addPass(pm, createReassociatePass());
183         addPass(pm, createLoopRotatePass());
184         addPass(pm, createLICMPass());
185         addPass(pm, createLoopUnswitchPass());
186         addPass(pm, createLoopIndexSplitPass());
187         addPass(pm, createInstructionCombiningPass());
188         addPass(pm, createIndVarSimplifyPass());
189         addPass(pm, createLoopDeletionPass());
190         addPass(pm, createLoopUnrollPass());
191         addPass(pm, createInstructionCombiningPass());
192         addPass(pm, createGVNPass());
193         addPass(pm, createMemCpyOptPass());
194         addPass(pm, createSCCPPass());
195
196         addPass(pm, createInstructionCombiningPass());
197         addPass(pm, createConstantPropagationPass());
198
199         addPass(pm, createDeadStoreEliminationPass());
200         addPass(pm, createAggressiveDCEPass());
201         addPass(pm, createCFGSimplificationPass());
202         addPass(pm, createDeadTypeEliminationPass());
203         addPass(pm, createConstantMergePass());
204     }
205
206     if (optimizeLevel >= 1) {
207         addPass(pm, createStripExternalsPass());
208         addPass(pm, createGlobalDCEPass());
209     }
210
211     // level -O4 and -O5 are linktime optimizations
212 }
213
214 //////////////////////////////////////////////////////////////////////////////////////////
215 // This function runs optimization passes based on command line arguments.
216 // Returns true if any optimization passes were invoked.
217 bool ldc_optimize_module(llvm::Module* m)
218 {
219     if (!optimize())
220         return false;
221
222     PassManager pm;
223
224     if (verifyEach) pm.add(createVerifierPass());
225
226     addPass(pm, new TargetData(m));
227
228     bool optimize = optimizeLevel != 0 || doInline();
229
230     unsigned optPos = optimizeLevel != 0
231                     ? optimizeLevel.getPosition()
232                     : enableInlining.getPosition();
233
234     for (size_t i = 0; i < passList.size(); i++) {
235         // insert -O<N> / -enable-inlining in right position
236         if (optimize && optPos < passList.getPosition(i)) {
237             addPassesForOptLevel(pm);
238             optimize = false;
239         }
240
241         const PassInfo* pass = passList[i];
242         if (PassInfo::NormalCtor_t ctor = pass->getNormalCtor()) {
243             addPass(pm, ctor());
244         } else {
245             const char* arg = pass->getPassArgument(); // may return null
246             if (arg)
247                 error("Can't create pass '-%s' (%s)", arg, pass->getPassName());
248             else
249                 error("Can't create pass (%s)", pass->getPassName());
250             assert(0);  // Should be unreachable; root.h:error() calls exit()
251         }
252     }
253     // insert -O<N> / -enable-inlining if specified at the end,
254     if (optimize)
255         addPassesForOptLevel(pm);
256
257     pm.run(*m);
258     return true;
259 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.