[PM] Sink the no-op pass parsing logic into the .def-based registry to
[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 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
71 #include "PassRegistry.def"
72
73   // We also support building a require pass around any analysis.
74 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
75   if (Name == "require<" NAME ">")                                             \
76     return true;
77 #include "PassRegistry.def"
78
79   return false;
80 }
81
82 static bool isCGSCCPassName(StringRef Name) {
83 #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
84 #include "PassRegistry.def"
85
86   // We also support building a require pass around any analysis.
87 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
88   if (Name == "require<" NAME ">")                                             \
89     return true;
90 #include "PassRegistry.def"
91
92   return false;
93 }
94
95 static bool isFunctionPassName(StringRef Name) {
96 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
97 #include "PassRegistry.def"
98
99   // We also support building a require pass around any analysis.
100 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
101   if (Name == "require<" NAME ">")                                             \
102     return true;
103 #include "PassRegistry.def"
104
105   return false;
106 }
107
108 static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
109 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
110   if (Name == NAME) {                                                          \
111     MPM.addPass(CREATE_PASS);                                                  \
112     return true;                                                               \
113   }
114 #include "PassRegistry.def"
115
116   // We also support building a require pass around any analysis.
117 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
118   if (Name == "require<" NAME ">") {                                           \
119     MPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
120     return true;                                                               \
121   }
122 #include "PassRegistry.def"
123
124   return false;
125 }
126
127 static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
128 #define CGSCC_PASS(NAME, CREATE_PASS)                                          \
129   if (Name == NAME) {                                                          \
130     CGPM.addPass(CREATE_PASS);                                                 \
131     return true;                                                               \
132   }
133 #include "PassRegistry.def"
134
135   // We also support building a require pass around any analysis.
136 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
137   if (Name == "require<" NAME ">") {                                           \
138     CGPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());        \
139     return true;                                                               \
140   }
141 #include "PassRegistry.def"
142
143   return false;
144 }
145
146 static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
147 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
148   if (Name == NAME) {                                                          \
149     FPM.addPass(CREATE_PASS);                                                  \
150     return true;                                                               \
151   }
152 #include "PassRegistry.def"
153
154   // We also support building a require pass around any analysis.
155 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
156   if (Name == "require<" NAME ">") {                                           \
157     FPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
158     return true;                                                               \
159   }
160 #include "PassRegistry.def"
161
162   return false;
163 }
164
165 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
166                                       StringRef &PipelineText,
167                                       bool VerifyEachPass) {
168   for (;;) {
169     // Parse nested pass managers by recursing.
170     if (PipelineText.startswith("function(")) {
171       FunctionPassManager NestedFPM;
172
173       // Parse the inner pipeline inte the nested manager.
174       PipelineText = PipelineText.substr(strlen("function("));
175       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
176           PipelineText.empty())
177         return false;
178       assert(PipelineText[0] == ')');
179       PipelineText = PipelineText.substr(1);
180
181       // Add the nested pass manager with the appropriate adaptor.
182       FPM.addPass(std::move(NestedFPM));
183     } else {
184       // Otherwise try to parse a pass name.
185       size_t End = PipelineText.find_first_of(",)");
186       if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
187         return false;
188       if (VerifyEachPass)
189         FPM.addPass(VerifierPass());
190
191       PipelineText = PipelineText.substr(End);
192     }
193
194     if (PipelineText.empty() || PipelineText[0] == ')')
195       return true;
196
197     assert(PipelineText[0] == ',');
198     PipelineText = PipelineText.substr(1);
199   }
200 }
201
202 static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
203                                       StringRef &PipelineText,
204                                       bool VerifyEachPass) {
205   for (;;) {
206     // Parse nested pass managers by recursing.
207     if (PipelineText.startswith("cgscc(")) {
208       CGSCCPassManager NestedCGPM;
209
210       // Parse the inner pipeline into the nested manager.
211       PipelineText = PipelineText.substr(strlen("cgscc("));
212       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
213           PipelineText.empty())
214         return false;
215       assert(PipelineText[0] == ')');
216       PipelineText = PipelineText.substr(1);
217
218       // Add the nested pass manager with the appropriate adaptor.
219       CGPM.addPass(std::move(NestedCGPM));
220     } else if (PipelineText.startswith("function(")) {
221       FunctionPassManager NestedFPM;
222
223       // Parse the inner pipeline inte the nested manager.
224       PipelineText = PipelineText.substr(strlen("function("));
225       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
226           PipelineText.empty())
227         return false;
228       assert(PipelineText[0] == ')');
229       PipelineText = PipelineText.substr(1);
230
231       // Add the nested pass manager with the appropriate adaptor.
232       CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
233     } else {
234       // Otherwise try to parse a pass name.
235       size_t End = PipelineText.find_first_of(",)");
236       if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
237         return false;
238       // FIXME: No verifier support for CGSCC passes!
239
240       PipelineText = PipelineText.substr(End);
241     }
242
243     if (PipelineText.empty() || PipelineText[0] == ')')
244       return true;
245
246     assert(PipelineText[0] == ',');
247     PipelineText = PipelineText.substr(1);
248   }
249 }
250
251 static bool parseModulePassPipeline(ModulePassManager &MPM,
252                                     StringRef &PipelineText,
253                                     bool VerifyEachPass) {
254   for (;;) {
255     // Parse nested pass managers by recursing.
256     if (PipelineText.startswith("module(")) {
257       ModulePassManager NestedMPM;
258
259       // Parse the inner pipeline into the nested manager.
260       PipelineText = PipelineText.substr(strlen("module("));
261       if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
262           PipelineText.empty())
263         return false;
264       assert(PipelineText[0] == ')');
265       PipelineText = PipelineText.substr(1);
266
267       // Now add the nested manager as a module pass.
268       MPM.addPass(std::move(NestedMPM));
269     } else if (PipelineText.startswith("cgscc(")) {
270       CGSCCPassManager NestedCGPM;
271
272       // Parse the inner pipeline inte the nested manager.
273       PipelineText = PipelineText.substr(strlen("cgscc("));
274       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
275           PipelineText.empty())
276         return false;
277       assert(PipelineText[0] == ')');
278       PipelineText = PipelineText.substr(1);
279
280       // Add the nested pass manager with the appropriate adaptor.
281       MPM.addPass(
282           createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
283     } else if (PipelineText.startswith("function(")) {
284       FunctionPassManager NestedFPM;
285
286       // Parse the inner pipeline inte the nested manager.
287       PipelineText = PipelineText.substr(strlen("function("));
288       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
289           PipelineText.empty())
290         return false;
291       assert(PipelineText[0] == ')');
292       PipelineText = PipelineText.substr(1);
293
294       // Add the nested pass manager with the appropriate adaptor.
295       MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
296     } else {
297       // Otherwise try to parse a pass name.
298       size_t End = PipelineText.find_first_of(",)");
299       if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
300         return false;
301       if (VerifyEachPass)
302         MPM.addPass(VerifierPass());
303
304       PipelineText = PipelineText.substr(End);
305     }
306
307     if (PipelineText.empty() || PipelineText[0] == ')')
308       return true;
309
310     assert(PipelineText[0] == ',');
311     PipelineText = PipelineText.substr(1);
312   }
313 }
314
315 // Primary pass pipeline description parsing routine.
316 // FIXME: Should this routine accept a TargetMachine or require the caller to
317 // pre-populate the analysis managers with target-specific stuff?
318 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
319                              bool VerifyEachPass) {
320   // Look at the first entry to figure out which layer to start parsing at.
321   if (PipelineText.startswith("module("))
322     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
323            PipelineText.empty();
324   if (PipelineText.startswith("cgscc(")) {
325     CGSCCPassManager CGPM;
326     if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
327         !PipelineText.empty())
328       return false;
329     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
330     return true;
331   }
332   if (PipelineText.startswith("function(")) {
333     FunctionPassManager FPM;
334     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
335         !PipelineText.empty())
336       return false;
337     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
338     return true;
339   }
340
341   // This isn't a direct pass manager name, look for the end of a pass name.
342   StringRef FirstName =
343       PipelineText.substr(0, PipelineText.find_first_of(",)"));
344   if (isModulePassName(FirstName))
345     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
346            PipelineText.empty();
347
348   if (isCGSCCPassName(FirstName)) {
349     CGSCCPassManager CGPM;
350     if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
351         !PipelineText.empty())
352       return false;
353     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
354     return true;
355   }
356
357   if (isFunctionPassName(FirstName)) {
358     FunctionPassManager FPM;
359     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
360         !PipelineText.empty())
361       return false;
362     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
363     return true;
364   }
365
366   return false;
367 }