[PM] Move the analysis registry into the Passes.cpp file and provide
[oota-llvm.git] / tools / opt / Passes.cpp
1 //===- Passes.cpp - Parsing, selection, and running of passes -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file provides the infrastructure to parse and build a custom pass
12 /// manager based on a commandline flag. It also provides helpers to aid in
13 /// analyzing, debugging, and testing pass structures.
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #include "Passes.h"
18 #include "llvm/Analysis/CGSCCPassManager.h"
19 #include "llvm/Analysis/LazyCallGraph.h"
20 #include "llvm/IR/IRPrintingPasses.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/IR/Verifier.h"
23 #include "llvm/Support/Debug.h"
24
25 using namespace llvm;
26
27 namespace {
28
29 /// \brief No-op module pass which does nothing.
30 struct NoOpModulePass {
31   PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
32   static StringRef name() { return "NoOpModulePass"; }
33 };
34
35 /// \brief No-op CGSCC pass which does nothing.
36 struct NoOpCGSCCPass {
37   PreservedAnalyses run(LazyCallGraph::SCC &C) {
38     return PreservedAnalyses::all();
39   }
40   static StringRef name() { return "NoOpCGSCCPass"; }
41 };
42
43 /// \brief No-op function pass which does nothing.
44 struct NoOpFunctionPass {
45   PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
46   static StringRef name() { return "NoOpFunctionPass"; }
47 };
48
49 } // End anonymous namespace.
50
51 void llvm::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
52 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
53   MAM.registerPass(CREATE_PASS);
54 #include "PassRegistry.def"
55 }
56
57 void llvm::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
58 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
59   CGAM.registerPass(CREATE_PASS);
60 #include "PassRegistry.def"
61 }
62
63 void llvm::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
64 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
65   FAM.registerPass(CREATE_PASS);
66 #include "PassRegistry.def"
67 }
68
69 static bool isModulePassName(StringRef Name) {
70   if (Name == "no-op-module") return true;
71
72 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
73 #include "PassRegistry.def"
74
75   // We also support building a require pass around any analysis.
76 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
77   if (Name == "require<" NAME ">")                                             \
78     return true;
79 #include "PassRegistry.def"
80
81   return false;
82 }
83
84 static bool isCGSCCPassName(StringRef Name) {
85   if (Name == "no-op-cgscc") return true;
86
87 #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
88 #include "PassRegistry.def"
89
90   // We also support building a require pass around any analysis.
91 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
92   if (Name == "require<" NAME ">")                                             \
93     return true;
94 #include "PassRegistry.def"
95
96   return false;
97 }
98
99 static bool isFunctionPassName(StringRef Name) {
100   if (Name == "no-op-function") return true;
101
102 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
103 #include "PassRegistry.def"
104
105   // We also support building a require pass around any analysis.
106 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
107   if (Name == "require<" NAME ">")                                             \
108     return true;
109 #include "PassRegistry.def"
110
111   return false;
112 }
113
114 static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
115   if (Name == "no-op-module") {
116     MPM.addPass(NoOpModulePass());
117     return true;
118   }
119
120 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
121   if (Name == NAME) {                                                          \
122     MPM.addPass(CREATE_PASS);                                                  \
123     return true;                                                               \
124   }
125 #include "PassRegistry.def"
126
127   // We also support building a require pass around any analysis.
128 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
129   if (Name == "require<" NAME ">") {                                           \
130     MPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
131     return true;                                                               \
132   }
133 #include "PassRegistry.def"
134
135   return false;
136 }
137
138 static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
139   if (Name == "no-op-cgscc") {
140     CGPM.addPass(NoOpCGSCCPass());
141     return true;
142   }
143
144 #define CGSCC_PASS(NAME, CREATE_PASS)                                          \
145   if (Name == NAME) {                                                          \
146     CGPM.addPass(CREATE_PASS);                                                 \
147     return true;                                                               \
148   }
149 #include "PassRegistry.def"
150
151   // We also support building a require pass around any analysis.
152 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
153   if (Name == "require<" NAME ">") {                                           \
154     CGPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());        \
155     return true;                                                               \
156   }
157 #include "PassRegistry.def"
158
159   return false;
160 }
161
162 static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
163   if (Name == "no-op-function") {
164     FPM.addPass(NoOpFunctionPass());
165     return true;
166   }
167
168 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
169   if (Name == NAME) {                                                          \
170     FPM.addPass(CREATE_PASS);                                                  \
171     return true;                                                               \
172   }
173 #include "PassRegistry.def"
174
175   // We also support building a require pass around any analysis.
176 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
177   if (Name == "require<" NAME ">") {                                           \
178     FPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
179     return true;                                                               \
180   }
181 #include "PassRegistry.def"
182
183   return false;
184 }
185
186 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
187                                       StringRef &PipelineText,
188                                       bool VerifyEachPass) {
189   for (;;) {
190     // Parse nested pass managers by recursing.
191     if (PipelineText.startswith("function(")) {
192       FunctionPassManager NestedFPM;
193
194       // Parse the inner pipeline inte the nested manager.
195       PipelineText = PipelineText.substr(strlen("function("));
196       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
197           PipelineText.empty())
198         return false;
199       assert(PipelineText[0] == ')');
200       PipelineText = PipelineText.substr(1);
201
202       // Add the nested pass manager with the appropriate adaptor.
203       FPM.addPass(std::move(NestedFPM));
204     } else {
205       // Otherwise try to parse a pass name.
206       size_t End = PipelineText.find_first_of(",)");
207       if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
208         return false;
209       if (VerifyEachPass)
210         FPM.addPass(VerifierPass());
211
212       PipelineText = PipelineText.substr(End);
213     }
214
215     if (PipelineText.empty() || PipelineText[0] == ')')
216       return true;
217
218     assert(PipelineText[0] == ',');
219     PipelineText = PipelineText.substr(1);
220   }
221 }
222
223 static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
224                                       StringRef &PipelineText,
225                                       bool VerifyEachPass) {
226   for (;;) {
227     // Parse nested pass managers by recursing.
228     if (PipelineText.startswith("cgscc(")) {
229       CGSCCPassManager NestedCGPM;
230
231       // Parse the inner pipeline into the nested manager.
232       PipelineText = PipelineText.substr(strlen("cgscc("));
233       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
234           PipelineText.empty())
235         return false;
236       assert(PipelineText[0] == ')');
237       PipelineText = PipelineText.substr(1);
238
239       // Add the nested pass manager with the appropriate adaptor.
240       CGPM.addPass(std::move(NestedCGPM));
241     } else if (PipelineText.startswith("function(")) {
242       FunctionPassManager NestedFPM;
243
244       // Parse the inner pipeline inte the nested manager.
245       PipelineText = PipelineText.substr(strlen("function("));
246       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
247           PipelineText.empty())
248         return false;
249       assert(PipelineText[0] == ')');
250       PipelineText = PipelineText.substr(1);
251
252       // Add the nested pass manager with the appropriate adaptor.
253       CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
254     } else {
255       // Otherwise try to parse a pass name.
256       size_t End = PipelineText.find_first_of(",)");
257       if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
258         return false;
259       // FIXME: No verifier support for CGSCC passes!
260
261       PipelineText = PipelineText.substr(End);
262     }
263
264     if (PipelineText.empty() || PipelineText[0] == ')')
265       return true;
266
267     assert(PipelineText[0] == ',');
268     PipelineText = PipelineText.substr(1);
269   }
270 }
271
272 static bool parseModulePassPipeline(ModulePassManager &MPM,
273                                     StringRef &PipelineText,
274                                     bool VerifyEachPass) {
275   for (;;) {
276     // Parse nested pass managers by recursing.
277     if (PipelineText.startswith("module(")) {
278       ModulePassManager NestedMPM;
279
280       // Parse the inner pipeline into the nested manager.
281       PipelineText = PipelineText.substr(strlen("module("));
282       if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
283           PipelineText.empty())
284         return false;
285       assert(PipelineText[0] == ')');
286       PipelineText = PipelineText.substr(1);
287
288       // Now add the nested manager as a module pass.
289       MPM.addPass(std::move(NestedMPM));
290     } else if (PipelineText.startswith("cgscc(")) {
291       CGSCCPassManager NestedCGPM;
292
293       // Parse the inner pipeline inte the nested manager.
294       PipelineText = PipelineText.substr(strlen("cgscc("));
295       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
296           PipelineText.empty())
297         return false;
298       assert(PipelineText[0] == ')');
299       PipelineText = PipelineText.substr(1);
300
301       // Add the nested pass manager with the appropriate adaptor.
302       MPM.addPass(
303           createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
304     } else if (PipelineText.startswith("function(")) {
305       FunctionPassManager NestedFPM;
306
307       // Parse the inner pipeline inte the nested manager.
308       PipelineText = PipelineText.substr(strlen("function("));
309       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
310           PipelineText.empty())
311         return false;
312       assert(PipelineText[0] == ')');
313       PipelineText = PipelineText.substr(1);
314
315       // Add the nested pass manager with the appropriate adaptor.
316       MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
317     } else {
318       // Otherwise try to parse a pass name.
319       size_t End = PipelineText.find_first_of(",)");
320       if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
321         return false;
322       if (VerifyEachPass)
323         MPM.addPass(VerifierPass());
324
325       PipelineText = PipelineText.substr(End);
326     }
327
328     if (PipelineText.empty() || PipelineText[0] == ')')
329       return true;
330
331     assert(PipelineText[0] == ',');
332     PipelineText = PipelineText.substr(1);
333   }
334 }
335
336 // Primary pass pipeline description parsing routine.
337 // FIXME: Should this routine accept a TargetMachine or require the caller to
338 // pre-populate the analysis managers with target-specific stuff?
339 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
340                              bool VerifyEachPass) {
341   // Look at the first entry to figure out which layer to start parsing at.
342   if (PipelineText.startswith("module("))
343     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
344            PipelineText.empty();
345   if (PipelineText.startswith("cgscc(")) {
346     CGSCCPassManager CGPM;
347     if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
348         !PipelineText.empty())
349       return false;
350     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
351     return true;
352   }
353   if (PipelineText.startswith("function(")) {
354     FunctionPassManager FPM;
355     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
356         !PipelineText.empty())
357       return false;
358     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
359     return true;
360   }
361
362   // This isn't a direct pass manager name, look for the end of a pass name.
363   StringRef FirstName =
364       PipelineText.substr(0, PipelineText.find_first_of(",)"));
365   if (isModulePassName(FirstName))
366     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
367            PipelineText.empty();
368
369   if (isCGSCCPassName(FirstName)) {
370     CGSCCPassManager CGPM;
371     if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
372         !PipelineText.empty())
373       return false;
374     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
375     return true;
376   }
377
378   if (isFunctionPassName(FirstName)) {
379     FunctionPassManager FPM;
380     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
381         !PipelineText.empty())
382       return false;
383     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
384     return true;
385   }
386
387   return false;
388 }