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