blob: 3acd0f3742cad2aa51e6c40c635b81fee1d01de7 [file] [log] [blame]
Chandler Carruth66445382014-01-11 08:16:35 +00001//===- 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"
Chandler Carruth572e3402014-04-21 11:12:00 +000018#include "llvm/Analysis/CGSCCPassManager.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000019#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000020#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000021#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000022#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000023#include "llvm/Support/Debug.h"
Chandler Carruth66445382014-01-11 08:16:35 +000024
25using namespace llvm;
26
27namespace {
28
Chandler Carruthd8330982014-01-12 09:34:22 +000029/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000030struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000031 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000032 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000033};
34
Chandler Carruth0b576b32015-01-06 02:50:06 +000035/// \brief No-op module analysis.
36struct NoOpModuleAnalysis {
37 struct Result {};
38 Result run(Module &) { return Result(); }
39 static StringRef name() { return "NoOpModuleAnalysis"; }
40 static void *ID() { return (void *)&PassID; }
41private:
42 static char PassID;
43};
44
45char NoOpModuleAnalysis::PassID;
46
Chandler Carruth572e3402014-04-21 11:12:00 +000047/// \brief No-op CGSCC pass which does nothing.
48struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000049 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000050 return PreservedAnalyses::all();
51 }
52 static StringRef name() { return "NoOpCGSCCPass"; }
53};
54
Chandler Carruth0b576b32015-01-06 02:50:06 +000055/// \brief No-op CGSCC analysis.
56struct NoOpCGSCCAnalysis {
57 struct Result {};
58 Result run(LazyCallGraph::SCC &) { return Result(); }
59 static StringRef name() { return "NoOpCGSCCAnalysis"; }
60 static void *ID() { return (void *)&PassID; }
61private:
62 static char PassID;
63};
64
65char NoOpCGSCCAnalysis::PassID;
66
Chandler Carruthd8330982014-01-12 09:34:22 +000067/// \brief No-op function pass which does nothing.
68struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000069 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000070 static StringRef name() { return "NoOpFunctionPass"; }
71};
72
Chandler Carruth0b576b32015-01-06 02:50:06 +000073/// \brief No-op function analysis.
74struct NoOpFunctionAnalysis {
75 struct Result {};
76 Result run(Function &) { return Result(); }
77 static StringRef name() { return "NoOpFunctionAnalysis"; }
78 static void *ID() { return (void *)&PassID; }
79private:
80 static char PassID;
81};
82
83char NoOpFunctionAnalysis::PassID;
84
Chandler Carruth66445382014-01-11 08:16:35 +000085} // End anonymous namespace.
86
Chandler Carruthb70f6732015-01-06 02:21:37 +000087void llvm::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
88#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
89 MAM.registerPass(CREATE_PASS);
90#include "PassRegistry.def"
91}
92
93void llvm::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
94#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
95 CGAM.registerPass(CREATE_PASS);
96#include "PassRegistry.def"
97}
98
99void llvm::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
100#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
101 FAM.registerPass(CREATE_PASS);
102#include "PassRegistry.def"
103}
104
Chandler Carruth66445382014-01-11 08:16:35 +0000105static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000106#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
107#include "PassRegistry.def"
Chandler Carruth66445382014-01-11 08:16:35 +0000108
Chandler Carruth628503e2015-01-06 02:10:51 +0000109 // We also support building a require pass around any analysis.
110#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
111 if (Name == "require<" NAME ">") \
112 return true;
113#include "PassRegistry.def"
114
Chandler Carruth66445382014-01-11 08:16:35 +0000115 return false;
116}
117
Chandler Carruth572e3402014-04-21 11:12:00 +0000118static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000119#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
120#include "PassRegistry.def"
121
Chandler Carruth628503e2015-01-06 02:10:51 +0000122 // We also support building a require pass around any analysis.
123#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
124 if (Name == "require<" NAME ">") \
125 return true;
126#include "PassRegistry.def"
127
Chandler Carruth572e3402014-04-21 11:12:00 +0000128 return false;
129}
130
Chandler Carruthd8330982014-01-12 09:34:22 +0000131static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000132#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
133#include "PassRegistry.def"
Chandler Carruthd8330982014-01-12 09:34:22 +0000134
Chandler Carruth628503e2015-01-06 02:10:51 +0000135 // We also support building a require pass around any analysis.
136#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
137 if (Name == "require<" NAME ">") \
138 return true;
139#include "PassRegistry.def"
140
Chandler Carruthd8330982014-01-12 09:34:22 +0000141 return false;
142}
143
Chandler Carruth66445382014-01-11 08:16:35 +0000144static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000145#define MODULE_PASS(NAME, CREATE_PASS) \
146 if (Name == NAME) { \
147 MPM.addPass(CREATE_PASS); \
148 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000149 }
Chandler Carruth58944182014-04-21 08:08:50 +0000150#include "PassRegistry.def"
151
Chandler Carruth628503e2015-01-06 02:10:51 +0000152 // We also support building a require pass around any analysis.
153#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
154 if (Name == "require<" NAME ">") { \
155 MPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>()); \
156 return true; \
157 }
158#include "PassRegistry.def"
159
Chandler Carruth66445382014-01-11 08:16:35 +0000160 return false;
161}
162
Chandler Carruth572e3402014-04-21 11:12:00 +0000163static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000164#define CGSCC_PASS(NAME, CREATE_PASS) \
165 if (Name == NAME) { \
166 CGPM.addPass(CREATE_PASS); \
167 return true; \
168 }
169#include "PassRegistry.def"
170
Chandler Carruth628503e2015-01-06 02:10:51 +0000171 // We also support building a require pass around any analysis.
172#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
173 if (Name == "require<" NAME ">") { \
174 CGPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>()); \
175 return true; \
176 }
177#include "PassRegistry.def"
178
Chandler Carruth572e3402014-04-21 11:12:00 +0000179 return false;
180}
181
Chandler Carruthd8330982014-01-12 09:34:22 +0000182static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000183#define FUNCTION_PASS(NAME, CREATE_PASS) \
184 if (Name == NAME) { \
185 FPM.addPass(CREATE_PASS); \
186 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000187 }
Chandler Carruth58944182014-04-21 08:08:50 +0000188#include "PassRegistry.def"
189
Chandler Carruth628503e2015-01-06 02:10:51 +0000190 // We also support building a require pass around any analysis.
191#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
192 if (Name == "require<" NAME ">") { \
193 FPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>()); \
194 return true; \
195 }
196#include "PassRegistry.def"
197
Chandler Carruthd8330982014-01-12 09:34:22 +0000198 return false;
199}
200
201static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
Chandler Carruth4d356312014-01-20 11:34:08 +0000202 StringRef &PipelineText,
203 bool VerifyEachPass) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000204 for (;;) {
205 // Parse nested pass managers by recursing.
206 if (PipelineText.startswith("function(")) {
207 FunctionPassManager NestedFPM;
208
209 // Parse the inner pipeline inte the nested manager.
210 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth4d356312014-01-20 11:34:08 +0000211 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000212 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000213 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000214 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000215 PipelineText = PipelineText.substr(1);
216
217 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000218 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000219 } else {
220 // Otherwise try to parse a pass name.
221 size_t End = PipelineText.find_first_of(",)");
222 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
223 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000224 if (VerifyEachPass)
225 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000226
227 PipelineText = PipelineText.substr(End);
228 }
229
230 if (PipelineText.empty() || PipelineText[0] == ')')
231 return true;
232
233 assert(PipelineText[0] == ',');
234 PipelineText = PipelineText.substr(1);
235 }
236}
237
Chandler Carruth572e3402014-04-21 11:12:00 +0000238static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
239 StringRef &PipelineText,
240 bool VerifyEachPass) {
241 for (;;) {
242 // Parse nested pass managers by recursing.
243 if (PipelineText.startswith("cgscc(")) {
244 CGSCCPassManager NestedCGPM;
245
246 // Parse the inner pipeline into the nested manager.
247 PipelineText = PipelineText.substr(strlen("cgscc("));
248 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
249 PipelineText.empty())
250 return false;
251 assert(PipelineText[0] == ')');
252 PipelineText = PipelineText.substr(1);
253
254 // Add the nested pass manager with the appropriate adaptor.
255 CGPM.addPass(std::move(NestedCGPM));
256 } else if (PipelineText.startswith("function(")) {
257 FunctionPassManager NestedFPM;
258
259 // Parse the inner pipeline inte the nested manager.
260 PipelineText = PipelineText.substr(strlen("function("));
261 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
262 PipelineText.empty())
263 return false;
264 assert(PipelineText[0] == ')');
265 PipelineText = PipelineText.substr(1);
266
267 // Add the nested pass manager with the appropriate adaptor.
268 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
269 } else {
270 // Otherwise try to parse a pass name.
271 size_t End = PipelineText.find_first_of(",)");
272 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
273 return false;
274 // FIXME: No verifier support for CGSCC passes!
275
276 PipelineText = PipelineText.substr(End);
277 }
278
279 if (PipelineText.empty() || PipelineText[0] == ')')
280 return true;
281
282 assert(PipelineText[0] == ',');
283 PipelineText = PipelineText.substr(1);
284 }
285}
286
Chandler Carruth66445382014-01-11 08:16:35 +0000287static bool parseModulePassPipeline(ModulePassManager &MPM,
Chandler Carruth4d356312014-01-20 11:34:08 +0000288 StringRef &PipelineText,
289 bool VerifyEachPass) {
Chandler Carruth66445382014-01-11 08:16:35 +0000290 for (;;) {
291 // Parse nested pass managers by recursing.
292 if (PipelineText.startswith("module(")) {
Chandler Carruth258dbb32014-01-11 12:06:47 +0000293 ModulePassManager NestedMPM;
294
295 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000296 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth4d356312014-01-20 11:34:08 +0000297 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000298 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000299 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000300 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000301 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000302
303 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000304 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000305 } else if (PipelineText.startswith("cgscc(")) {
306 CGSCCPassManager NestedCGPM;
307
308 // Parse the inner pipeline inte the nested manager.
309 PipelineText = PipelineText.substr(strlen("cgscc("));
310 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
311 PipelineText.empty())
312 return false;
313 assert(PipelineText[0] == ')');
314 PipelineText = PipelineText.substr(1);
315
316 // Add the nested pass manager with the appropriate adaptor.
317 MPM.addPass(
318 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000319 } else if (PipelineText.startswith("function(")) {
320 FunctionPassManager NestedFPM;
321
322 // Parse the inner pipeline inte the nested manager.
323 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth4d356312014-01-20 11:34:08 +0000324 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000325 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000326 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000327 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000328 PipelineText = PipelineText.substr(1);
329
330 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000331 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000332 } else {
333 // Otherwise try to parse a pass name.
334 size_t End = PipelineText.find_first_of(",)");
335 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
336 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000337 if (VerifyEachPass)
338 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000339
340 PipelineText = PipelineText.substr(End);
341 }
342
343 if (PipelineText.empty() || PipelineText[0] == ')')
344 return true;
345
346 assert(PipelineText[0] == ',');
347 PipelineText = PipelineText.substr(1);
348 }
349}
350
351// Primary pass pipeline description parsing routine.
352// FIXME: Should this routine accept a TargetMachine or require the caller to
353// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth4d356312014-01-20 11:34:08 +0000354bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
355 bool VerifyEachPass) {
Chandler Carruth66445382014-01-11 08:16:35 +0000356 // Look at the first entry to figure out which layer to start parsing at.
357 if (PipelineText.startswith("module("))
Chandler Carruth4d356312014-01-20 11:34:08 +0000358 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
359 PipelineText.empty();
Chandler Carruth572e3402014-04-21 11:12:00 +0000360 if (PipelineText.startswith("cgscc(")) {
361 CGSCCPassManager CGPM;
362 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
363 !PipelineText.empty())
364 return false;
365 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
366 return true;
367 }
Chandler Carruthd8330982014-01-12 09:34:22 +0000368 if (PipelineText.startswith("function(")) {
369 FunctionPassManager FPM;
Chandler Carruth4d356312014-01-20 11:34:08 +0000370 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
371 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000372 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000373 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000374 return true;
375 }
Chandler Carruth66445382014-01-11 08:16:35 +0000376
377 // This isn't a direct pass manager name, look for the end of a pass name.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000378 StringRef FirstName =
379 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruth66445382014-01-11 08:16:35 +0000380 if (isModulePassName(FirstName))
Chandler Carruth4d356312014-01-20 11:34:08 +0000381 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
382 PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000383
Chandler Carruth572e3402014-04-21 11:12:00 +0000384 if (isCGSCCPassName(FirstName)) {
385 CGSCCPassManager CGPM;
386 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
387 !PipelineText.empty())
388 return false;
389 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
390 return true;
391 }
392
Chandler Carruthd8330982014-01-12 09:34:22 +0000393 if (isFunctionPassName(FirstName)) {
394 FunctionPassManager FPM;
Chandler Carruth4d356312014-01-20 11:34:08 +0000395 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
396 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000397 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000398 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000399 return true;
400 }
Chandler Carruth66445382014-01-11 08:16:35 +0000401
402 return false;
403}