blob: 17fb8c77d6814829707ca7b31dbf1ae5e93abbbe [file] [log] [blame]
Chandler Carruth1ff77242015-03-07 09:02:36 +00001//===- Parsing, selection, and construction of pass pipelines -------------===//
Chandler Carruth66445382014-01-11 08:16:35 +00002//
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///
Chandler Carruth1ff77242015-03-07 09:02:36 +000011/// This file provides the implementation of the PassBuilder based on our
12/// static pass registry as well as related functionality. It also provides
13/// helpers to aid in analyzing, debugging, and testing passes and pass
14/// pipelines.
Chandler Carruth66445382014-01-11 08:16:35 +000015///
16//===----------------------------------------------------------------------===//
17
Chandler Carruth1ff77242015-03-07 09:02:36 +000018#include "llvm/Passes/PassBuilder.h"
Chandler Carruth6f5770b102016-02-13 23:32:00 +000019#include "llvm/Analysis/AliasAnalysis.h"
Chandler Carruthdf8b2232015-01-22 21:53:09 +000020#include "llvm/Analysis/AssumptionCache.h"
Chandler Carruthbece8d52016-02-13 23:46:24 +000021#include "llvm/Analysis/BasicAliasAnalysis.h"
Chandler Carruth572e3402014-04-21 11:12:00 +000022#include "llvm/Analysis/CGSCCPassManager.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000023#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000024#include "llvm/Analysis/LoopInfo.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000025#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000026#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000027#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000028#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000029#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000030#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000031#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000032#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000033#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000034#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth9c4ed172016-02-18 11:03:11 +000035#include "llvm/Transforms/IPO/FunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000036#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000037#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000038#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000039#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000040#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000041#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000042#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000043#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000044
45using namespace llvm;
46
47namespace {
48
Chandler Carruthd8330982014-01-12 09:34:22 +000049/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000050struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000051 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000052 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000053};
54
Chandler Carruth0b576b32015-01-06 02:50:06 +000055/// \brief No-op module analysis.
56struct NoOpModuleAnalysis {
57 struct Result {};
58 Result run(Module &) { return Result(); }
59 static StringRef name() { return "NoOpModuleAnalysis"; }
60 static void *ID() { return (void *)&PassID; }
61private:
62 static char PassID;
63};
64
65char NoOpModuleAnalysis::PassID;
66
Chandler Carruth572e3402014-04-21 11:12:00 +000067/// \brief No-op CGSCC pass which does nothing.
68struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000069 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000070 return PreservedAnalyses::all();
71 }
72 static StringRef name() { return "NoOpCGSCCPass"; }
73};
74
Chandler Carruth0b576b32015-01-06 02:50:06 +000075/// \brief No-op CGSCC analysis.
76struct NoOpCGSCCAnalysis {
77 struct Result {};
78 Result run(LazyCallGraph::SCC &) { return Result(); }
79 static StringRef name() { return "NoOpCGSCCAnalysis"; }
80 static void *ID() { return (void *)&PassID; }
81private:
82 static char PassID;
83};
84
85char NoOpCGSCCAnalysis::PassID;
86
Chandler Carruthd8330982014-01-12 09:34:22 +000087/// \brief No-op function pass which does nothing.
88struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000089 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000090 static StringRef name() { return "NoOpFunctionPass"; }
91};
92
Chandler Carruth0b576b32015-01-06 02:50:06 +000093/// \brief No-op function analysis.
94struct NoOpFunctionAnalysis {
95 struct Result {};
96 Result run(Function &) { return Result(); }
97 static StringRef name() { return "NoOpFunctionAnalysis"; }
98 static void *ID() { return (void *)&PassID; }
99private:
100 static char PassID;
101};
102
103char NoOpFunctionAnalysis::PassID;
104
Chandler Carruth66445382014-01-11 08:16:35 +0000105} // End anonymous namespace.
106
Chandler Carruth1ff77242015-03-07 09:02:36 +0000107void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000108#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000109 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000110#include "PassRegistry.def"
111}
112
Chandler Carruth1ff77242015-03-07 09:02:36 +0000113void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000114#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000115 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000116#include "PassRegistry.def"
117}
118
Chandler Carruth1ff77242015-03-07 09:02:36 +0000119void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000120#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000121 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000122#include "PassRegistry.def"
123}
124
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000125#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000126static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000127#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000128#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000129 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000130 return true;
131#include "PassRegistry.def"
132
Chandler Carruth66445382014-01-11 08:16:35 +0000133 return false;
134}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000135#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000136
Chandler Carruth572e3402014-04-21 11:12:00 +0000137static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000138#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000139#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000140 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000141 return true;
142#include "PassRegistry.def"
143
Chandler Carruth572e3402014-04-21 11:12:00 +0000144 return false;
145}
146
Chandler Carruthd8330982014-01-12 09:34:22 +0000147static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000148#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000149#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000150 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000151 return true;
152#include "PassRegistry.def"
153
Chandler Carruthd8330982014-01-12 09:34:22 +0000154 return false;
155}
156
Chandler Carruth1ff77242015-03-07 09:02:36 +0000157bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000158#define MODULE_PASS(NAME, CREATE_PASS) \
159 if (Name == NAME) { \
160 MPM.addPass(CREATE_PASS); \
161 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000162 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000163#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
164 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000165 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000166 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000167 } \
168 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000169 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000170 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000171 }
172#include "PassRegistry.def"
173
Chandler Carruth66445382014-01-11 08:16:35 +0000174 return false;
175}
176
Chandler Carruth1ff77242015-03-07 09:02:36 +0000177bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000178#define CGSCC_PASS(NAME, CREATE_PASS) \
179 if (Name == NAME) { \
180 CGPM.addPass(CREATE_PASS); \
181 return true; \
182 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000183#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
184 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000185 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000186 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000187 } \
188 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000189 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000190 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000191 }
192#include "PassRegistry.def"
193
Chandler Carruth572e3402014-04-21 11:12:00 +0000194 return false;
195}
196
Chandler Carruth1ff77242015-03-07 09:02:36 +0000197bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
198 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000199#define FUNCTION_PASS(NAME, CREATE_PASS) \
200 if (Name == NAME) { \
201 FPM.addPass(CREATE_PASS); \
202 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000203 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000204#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
205 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000206 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000207 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000208 } \
209 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000210 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000211 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000212 }
213#include "PassRegistry.def"
214
Chandler Carruthd8330982014-01-12 09:34:22 +0000215 return false;
216}
217
Chandler Carruthedf59962016-02-18 09:45:17 +0000218bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
219#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
220 if (Name == NAME) { \
221 AA.registerFunctionAnalysis<decltype(CREATE_PASS)>(); \
222 return true; \
223 }
224#include "PassRegistry.def"
225
226 return false;
227}
228
Chandler Carruth1ff77242015-03-07 09:02:36 +0000229bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
230 StringRef &PipelineText,
231 bool VerifyEachPass,
232 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000233 for (;;) {
234 // Parse nested pass managers by recursing.
235 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000236 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000237
238 // Parse the inner pipeline inte the nested manager.
239 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000240 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
241 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000242 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000243 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000244 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000245 PipelineText = PipelineText.substr(1);
246
247 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000248 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000249 } else {
250 // Otherwise try to parse a pass name.
251 size_t End = PipelineText.find_first_of(",)");
252 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
253 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000254 if (VerifyEachPass)
255 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000256
257 PipelineText = PipelineText.substr(End);
258 }
259
260 if (PipelineText.empty() || PipelineText[0] == ')')
261 return true;
262
263 assert(PipelineText[0] == ',');
264 PipelineText = PipelineText.substr(1);
265 }
266}
267
Chandler Carruth1ff77242015-03-07 09:02:36 +0000268bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
269 StringRef &PipelineText,
270 bool VerifyEachPass,
271 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000272 for (;;) {
273 // Parse nested pass managers by recursing.
274 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000275 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000276
277 // Parse the inner pipeline into the nested manager.
278 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000279 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
280 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000281 PipelineText.empty())
282 return false;
283 assert(PipelineText[0] == ')');
284 PipelineText = PipelineText.substr(1);
285
286 // Add the nested pass manager with the appropriate adaptor.
287 CGPM.addPass(std::move(NestedCGPM));
288 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000289 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000290
291 // Parse the inner pipeline inte the nested manager.
292 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000293 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
294 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000295 PipelineText.empty())
296 return false;
297 assert(PipelineText[0] == ')');
298 PipelineText = PipelineText.substr(1);
299
300 // Add the nested pass manager with the appropriate adaptor.
301 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
302 } else {
303 // Otherwise try to parse a pass name.
304 size_t End = PipelineText.find_first_of(",)");
305 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
306 return false;
307 // FIXME: No verifier support for CGSCC passes!
308
309 PipelineText = PipelineText.substr(End);
310 }
311
312 if (PipelineText.empty() || PipelineText[0] == ')')
313 return true;
314
315 assert(PipelineText[0] == ',');
316 PipelineText = PipelineText.substr(1);
317 }
318}
319
Chandler Carruth1ff77242015-03-07 09:02:36 +0000320bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
321 StringRef &PipelineText,
322 bool VerifyEachPass,
323 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000324 for (;;) {
325 // Parse nested pass managers by recursing.
326 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000327 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000328
329 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000330 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000331 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
332 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000333 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000334 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000335 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000336 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000337
338 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000339 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000340 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000341 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000342
343 // Parse the inner pipeline inte the nested manager.
344 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000345 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
346 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000347 PipelineText.empty())
348 return false;
349 assert(PipelineText[0] == ')');
350 PipelineText = PipelineText.substr(1);
351
352 // Add the nested pass manager with the appropriate adaptor.
353 MPM.addPass(
354 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000355 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000356 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000357
358 // Parse the inner pipeline inte the nested manager.
359 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000360 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
361 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000362 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000363 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000364 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000365 PipelineText = PipelineText.substr(1);
366
367 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000368 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000369 } else {
370 // Otherwise try to parse a pass name.
371 size_t End = PipelineText.find_first_of(",)");
372 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
373 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000374 if (VerifyEachPass)
375 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000376
377 PipelineText = PipelineText.substr(End);
378 }
379
380 if (PipelineText.empty() || PipelineText[0] == ')')
381 return true;
382
383 assert(PipelineText[0] == ',');
384 PipelineText = PipelineText.substr(1);
385 }
386}
387
388// Primary pass pipeline description parsing routine.
389// FIXME: Should this routine accept a TargetMachine or require the caller to
390// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000391bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
392 StringRef PipelineText, bool VerifyEachPass,
393 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000394 // By default, try to parse the pipeline as-if it were within an implicit
395 // 'module(...)' pass pipeline. If this will parse at all, it needs to
396 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000397 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000398 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000399
Chandler Carruthea368f12015-01-06 08:37:58 +0000400 // This isn't parsable as a module pipeline, look for the end of a pass name
401 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000402 StringRef FirstName =
403 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000404 assert(!isModulePassName(FirstName) &&
405 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000406
Chandler Carruthea368f12015-01-06 08:37:58 +0000407 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
408 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000409 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000410 CGSCCPassManager CGPM(DebugLogging);
411 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
412 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000413 !PipelineText.empty())
414 return false;
415 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
416 return true;
417 }
418
Chandler Carruthea368f12015-01-06 08:37:58 +0000419 // Similarly, if this looks like a Function pass, parse the whole thing as
420 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000421 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000422 FunctionPassManager FPM(DebugLogging);
423 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
424 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000425 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000426 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000427 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000428 return true;
429 }
Chandler Carruth66445382014-01-11 08:16:35 +0000430
431 return false;
432}
Chandler Carruthedf59962016-02-18 09:45:17 +0000433
434bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
435 while (!PipelineText.empty()) {
436 StringRef Name;
437 std::tie(Name, PipelineText) = PipelineText.split(',');
438 if (!parseAAPassName(AA, Name))
439 return false;
440 }
441
442 return true;
443}