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