[PM] Add a nice low-tech registry of passes as a boring macro expansion
[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/LazyCallGraph.h"
19 #include "llvm/IR/IRPrintingPasses.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/IR/Verifier.h"
22 #include "llvm/Support/Debug.h"
23
24 using namespace llvm;
25
26 namespace {
27
28 /// \brief No-op module pass which does nothing.
29 struct NoOpModulePass {
30   PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
31   static StringRef name() { return "NoOpModulePass"; }
32 };
33
34 /// \brief No-op function pass which does nothing.
35 struct NoOpFunctionPass {
36   PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); }
37   static StringRef name() { return "NoOpFunctionPass"; }
38 };
39
40 } // End anonymous namespace.
41
42 static bool isModulePassName(StringRef Name) {
43   if (Name == "no-op-module") return true;
44
45 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
46 #include "PassRegistry.def"
47
48   return false;
49 }
50
51 static bool isFunctionPassName(StringRef Name) {
52   if (Name == "no-op-function") return true;
53
54 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
55 #include "PassRegistry.def"
56
57   return false;
58 }
59
60 static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
61   if (Name == "no-op-module") {
62     MPM.addPass(NoOpModulePass());
63     return true;
64   }
65
66 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
67   if (Name == NAME) {                                                          \
68     MPM.addPass(CREATE_PASS);                                                  \
69     return true;                                                               \
70   }
71 #include "PassRegistry.def"
72
73   return false;
74 }
75
76 static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
77   if (Name == "no-op-function") {
78     FPM.addPass(NoOpFunctionPass());
79     return true;
80   }
81
82 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
83   if (Name == NAME) {                                                          \
84     FPM.addPass(CREATE_PASS);                                                  \
85     return true;                                                               \
86   }
87 #include "PassRegistry.def"
88
89   return false;
90 }
91
92 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
93                                       StringRef &PipelineText,
94                                       bool VerifyEachPass) {
95   for (;;) {
96     // Parse nested pass managers by recursing.
97     if (PipelineText.startswith("function(")) {
98       FunctionPassManager NestedFPM;
99
100       // Parse the inner pipeline inte the nested manager.
101       PipelineText = PipelineText.substr(strlen("function("));
102       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
103           PipelineText.empty())
104         return false;
105       assert(PipelineText[0] == ')');
106       PipelineText = PipelineText.substr(1);
107
108       // Add the nested pass manager with the appropriate adaptor.
109       FPM.addPass(std::move(NestedFPM));
110     } else {
111       // Otherwise try to parse a pass name.
112       size_t End = PipelineText.find_first_of(",)");
113       if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
114         return false;
115       if (VerifyEachPass)
116         FPM.addPass(VerifierPass());
117
118       PipelineText = PipelineText.substr(End);
119     }
120
121     if (PipelineText.empty() || PipelineText[0] == ')')
122       return true;
123
124     assert(PipelineText[0] == ',');
125     PipelineText = PipelineText.substr(1);
126   }
127 }
128
129 static bool parseModulePassPipeline(ModulePassManager &MPM,
130                                     StringRef &PipelineText,
131                                     bool VerifyEachPass) {
132   for (;;) {
133     // Parse nested pass managers by recursing.
134     if (PipelineText.startswith("module(")) {
135       ModulePassManager NestedMPM;
136
137       // Parse the inner pipeline into the nested manager.
138       PipelineText = PipelineText.substr(strlen("module("));
139       if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
140           PipelineText.empty())
141         return false;
142       assert(PipelineText[0] == ')');
143       PipelineText = PipelineText.substr(1);
144
145       // Now add the nested manager as a module pass.
146       MPM.addPass(std::move(NestedMPM));
147     } else if (PipelineText.startswith("function(")) {
148       FunctionPassManager NestedFPM;
149
150       // Parse the inner pipeline inte the nested manager.
151       PipelineText = PipelineText.substr(strlen("function("));
152       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
153           PipelineText.empty())
154         return false;
155       assert(PipelineText[0] == ')');
156       PipelineText = PipelineText.substr(1);
157
158       // Add the nested pass manager with the appropriate adaptor.
159       MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
160     } else {
161       // Otherwise try to parse a pass name.
162       size_t End = PipelineText.find_first_of(",)");
163       if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
164         return false;
165       if (VerifyEachPass)
166         MPM.addPass(VerifierPass());
167
168       PipelineText = PipelineText.substr(End);
169     }
170
171     if (PipelineText.empty() || PipelineText[0] == ')')
172       return true;
173
174     assert(PipelineText[0] == ',');
175     PipelineText = PipelineText.substr(1);
176   }
177 }
178
179 // Primary pass pipeline description parsing routine.
180 // FIXME: Should this routine accept a TargetMachine or require the caller to
181 // pre-populate the analysis managers with target-specific stuff?
182 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
183                              bool VerifyEachPass) {
184   // Look at the first entry to figure out which layer to start parsing at.
185   if (PipelineText.startswith("module("))
186     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
187            PipelineText.empty();
188   if (PipelineText.startswith("function(")) {
189     FunctionPassManager FPM;
190     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
191         !PipelineText.empty())
192       return false;
193     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
194     return true;
195   }
196
197   // This isn't a direct pass manager name, look for the end of a pass name.
198   StringRef FirstName =
199       PipelineText.substr(0, PipelineText.find_first_of(",)"));
200   if (isModulePassName(FirstName))
201     return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
202            PipelineText.empty();
203
204   if (isFunctionPassName(FirstName)) {
205     FunctionPassManager FPM;
206     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
207         !PipelineText.empty())
208       return false;
209     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
210     return true;
211   }
212
213   return false;
214 }