blob: 7d0fe7e681b40007b2ad06d6945cbb4972fe79e0 [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 Carruth4f846a52016-02-20 03:46:03 +000020#include "llvm/Analysis/AliasAnalysisEvaluator.h"
Chandler Carruthdf8b2232015-01-22 21:53:09 +000021#include "llvm/Analysis/AssumptionCache.h"
Chandler Carruthbece8d52016-02-13 23:46:24 +000022#include "llvm/Analysis/BasicAliasAnalysis.h"
Chandler Carruth342c6712016-02-20 03:52:02 +000023#include "llvm/Analysis/CFLAliasAnalysis.h"
Chandler Carruth572e3402014-04-21 11:12:00 +000024#include "llvm/Analysis/CGSCCPassManager.h"
Hongbin Zheng751337f2016-02-25 17:54:15 +000025#include "llvm/Analysis/DominanceFrontier.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000026#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000027#include "llvm/Analysis/LoopInfo.h"
Hongbin Zheng3f978402016-02-25 17:54:07 +000028#include "llvm/Analysis/PostDominators.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000029#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth2b3d0442016-02-20 04:01:45 +000030#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
Chandler Carruthd6091a02016-02-20 04:03:06 +000031#include "llvm/Analysis/ScopedNoAliasAA.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000032#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000033#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruthc1dc3842016-02-20 04:04:52 +000034#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000035#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000036#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000037#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000038#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000039#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000040#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000041#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth9c4ed172016-02-18 11:03:11 +000042#include "llvm/Transforms/IPO/FunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000043#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000044#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000045#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000046#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000047#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000048#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000049#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000050#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000051
52using namespace llvm;
53
54namespace {
55
Chandler Carruthd8330982014-01-12 09:34:22 +000056/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000057struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000058 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000059 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000060};
61
Chandler Carruth0b576b32015-01-06 02:50:06 +000062/// \brief No-op module analysis.
63struct NoOpModuleAnalysis {
64 struct Result {};
65 Result run(Module &) { return Result(); }
66 static StringRef name() { return "NoOpModuleAnalysis"; }
67 static void *ID() { return (void *)&PassID; }
68private:
69 static char PassID;
70};
71
72char NoOpModuleAnalysis::PassID;
73
Chandler Carruth572e3402014-04-21 11:12:00 +000074/// \brief No-op CGSCC pass which does nothing.
75struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000076 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000077 return PreservedAnalyses::all();
78 }
79 static StringRef name() { return "NoOpCGSCCPass"; }
80};
81
Chandler Carruth0b576b32015-01-06 02:50:06 +000082/// \brief No-op CGSCC analysis.
83struct NoOpCGSCCAnalysis {
84 struct Result {};
85 Result run(LazyCallGraph::SCC &) { return Result(); }
86 static StringRef name() { return "NoOpCGSCCAnalysis"; }
87 static void *ID() { return (void *)&PassID; }
88private:
89 static char PassID;
90};
91
92char NoOpCGSCCAnalysis::PassID;
93
Chandler Carruthd8330982014-01-12 09:34:22 +000094/// \brief No-op function pass which does nothing.
95struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000096 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000097 static StringRef name() { return "NoOpFunctionPass"; }
98};
99
Chandler Carruth0b576b32015-01-06 02:50:06 +0000100/// \brief No-op function analysis.
101struct NoOpFunctionAnalysis {
102 struct Result {};
103 Result run(Function &) { return Result(); }
104 static StringRef name() { return "NoOpFunctionAnalysis"; }
105 static void *ID() { return (void *)&PassID; }
106private:
107 static char PassID;
108};
109
110char NoOpFunctionAnalysis::PassID;
111
Justin Bognereecc3c82016-02-25 07:23:08 +0000112/// \brief No-op loop pass which does nothing.
113struct NoOpLoopPass {
114 PreservedAnalyses run(Loop &L) { return PreservedAnalyses::all(); }
115 static StringRef name() { return "NoOpLoopPass"; }
116};
117
118/// \brief No-op loop analysis.
119struct NoOpLoopAnalysis {
120 struct Result {};
121 Result run(Loop &) { return Result(); }
122 static StringRef name() { return "NoOpLoopAnalysis"; }
123 static void *ID() { return (void *)&PassID; }
124private:
125 static char PassID;
126};
127
128char NoOpLoopAnalysis::PassID;
129
Chandler Carruth66445382014-01-11 08:16:35 +0000130} // End anonymous namespace.
131
Chandler Carruth1ff77242015-03-07 09:02:36 +0000132void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000133#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000134 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000135#include "PassRegistry.def"
136}
137
Chandler Carruth1ff77242015-03-07 09:02:36 +0000138void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000139#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000140 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000141#include "PassRegistry.def"
142}
143
Chandler Carruth1ff77242015-03-07 09:02:36 +0000144void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000145#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000146 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000147#include "PassRegistry.def"
148}
149
Justin Bognereecc3c82016-02-25 07:23:08 +0000150void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
151#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
152 LAM.registerPass([&] { return CREATE_PASS; });
153#include "PassRegistry.def"
154}
155
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000156#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000157static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000158#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000159#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000160 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000161 return true;
162#include "PassRegistry.def"
163
Chandler Carruth66445382014-01-11 08:16:35 +0000164 return false;
165}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000166#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000167
Chandler Carruth572e3402014-04-21 11:12:00 +0000168static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000169#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000170#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000171 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000172 return true;
173#include "PassRegistry.def"
174
Chandler Carruth572e3402014-04-21 11:12:00 +0000175 return false;
176}
177
Chandler Carruthd8330982014-01-12 09:34:22 +0000178static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000179#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000180#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000181 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000182 return true;
183#include "PassRegistry.def"
184
Chandler Carruthd8330982014-01-12 09:34:22 +0000185 return false;
186}
187
Justin Bognereecc3c82016-02-25 07:23:08 +0000188static bool isLoopPassName(StringRef Name) {
189#define LOOP_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
190#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
191 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
192 return true;
193#include "PassRegistry.def"
194
195 return false;
196}
197
Chandler Carruth1ff77242015-03-07 09:02:36 +0000198bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000199#define MODULE_PASS(NAME, CREATE_PASS) \
200 if (Name == NAME) { \
201 MPM.addPass(CREATE_PASS); \
202 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000203 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000204#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
205 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000206 MPM.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 MPM.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 Carruth66445382014-01-11 08:16:35 +0000215 return false;
216}
217
Chandler Carruth1ff77242015-03-07 09:02:36 +0000218bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000219#define CGSCC_PASS(NAME, CREATE_PASS) \
220 if (Name == NAME) { \
221 CGPM.addPass(CREATE_PASS); \
222 return true; \
223 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000224#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
225 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000226 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000227 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000228 } \
229 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000230 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000231 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000232 }
233#include "PassRegistry.def"
234
Chandler Carruth572e3402014-04-21 11:12:00 +0000235 return false;
236}
237
Chandler Carruth1ff77242015-03-07 09:02:36 +0000238bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
239 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000240#define FUNCTION_PASS(NAME, CREATE_PASS) \
241 if (Name == NAME) { \
242 FPM.addPass(CREATE_PASS); \
243 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000244 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000245#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
246 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000247 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000248 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000249 } \
250 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000251 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000252 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000253 }
254#include "PassRegistry.def"
255
Chandler Carruthd8330982014-01-12 09:34:22 +0000256 return false;
257}
258
Justin Bognereecc3c82016-02-25 07:23:08 +0000259bool PassBuilder::parseLoopPassName(LoopPassManager &FPM,
260 StringRef Name) {
261#define LOOP_PASS(NAME, CREATE_PASS) \
262 if (Name == NAME) { \
263 FPM.addPass(CREATE_PASS); \
264 return true; \
265 }
266#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
267 if (Name == "require<" NAME ">") { \
268 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
269 return true; \
270 } \
271 if (Name == "invalidate<" NAME ">") { \
272 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
273 return true; \
274 }
275#include "PassRegistry.def"
276
277 return false;
278}
279
Chandler Carruthedf59962016-02-18 09:45:17 +0000280bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
281#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
282 if (Name == NAME) { \
283 AA.registerFunctionAnalysis<decltype(CREATE_PASS)>(); \
284 return true; \
285 }
286#include "PassRegistry.def"
287
288 return false;
289}
290
Justin Bognereecc3c82016-02-25 07:23:08 +0000291bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
292 StringRef &PipelineText,
293 bool VerifyEachPass,
294 bool DebugLogging) {
295 for (;;) {
296 // Parse nested pass managers by recursing.
297 if (PipelineText.startswith("loop(")) {
298 LoopPassManager NestedLPM(DebugLogging);
299
300 // Parse the inner pipeline inte the nested manager.
301 PipelineText = PipelineText.substr(strlen("loop("));
302 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
303 DebugLogging) ||
304 PipelineText.empty())
305 return false;
306 assert(PipelineText[0] == ')');
307 PipelineText = PipelineText.substr(1);
308
309 // Add the nested pass manager with the appropriate adaptor.
310 LPM.addPass(std::move(NestedLPM));
311 } else {
312 // Otherwise try to parse a pass name.
313 size_t End = PipelineText.find_first_of(",)");
314 if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
315 return false;
316 // TODO: Ideally, we would run a LoopVerifierPass() here in the
317 // VerifyEachPass case, but we don't have such a verifier yet.
318
319 PipelineText = PipelineText.substr(End);
320 }
321
322 if (PipelineText.empty() || PipelineText[0] == ')')
323 return true;
324
325 assert(PipelineText[0] == ',');
326 PipelineText = PipelineText.substr(1);
327 }
328}
329
Chandler Carruth1ff77242015-03-07 09:02:36 +0000330bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
331 StringRef &PipelineText,
332 bool VerifyEachPass,
333 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000334 for (;;) {
335 // Parse nested pass managers by recursing.
336 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000337 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000338
339 // Parse the inner pipeline inte the nested manager.
340 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000341 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
342 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000343 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000344 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000345 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000346 PipelineText = PipelineText.substr(1);
347
348 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000349 FPM.addPass(std::move(NestedFPM));
Justin Bognereecc3c82016-02-25 07:23:08 +0000350 } else if (PipelineText.startswith("loop(")) {
351 LoopPassManager NestedLPM(DebugLogging);
352
353 // Parse the inner pipeline inte the nested manager.
354 PipelineText = PipelineText.substr(strlen("loop("));
355 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
356 DebugLogging) ||
357 PipelineText.empty())
358 return false;
359 assert(PipelineText[0] == ')');
360 PipelineText = PipelineText.substr(1);
361
362 // Add the nested pass manager with the appropriate adaptor.
363 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000364 } else {
365 // Otherwise try to parse a pass name.
366 size_t End = PipelineText.find_first_of(",)");
367 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
368 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000369 if (VerifyEachPass)
370 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000371
372 PipelineText = PipelineText.substr(End);
373 }
374
375 if (PipelineText.empty() || PipelineText[0] == ')')
376 return true;
377
378 assert(PipelineText[0] == ',');
379 PipelineText = PipelineText.substr(1);
380 }
381}
382
Chandler Carruth1ff77242015-03-07 09:02:36 +0000383bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
384 StringRef &PipelineText,
385 bool VerifyEachPass,
386 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000387 for (;;) {
388 // Parse nested pass managers by recursing.
389 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000390 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000391
392 // Parse the inner pipeline into the nested manager.
393 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000394 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
395 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000396 PipelineText.empty())
397 return false;
398 assert(PipelineText[0] == ')');
399 PipelineText = PipelineText.substr(1);
400
401 // Add the nested pass manager with the appropriate adaptor.
402 CGPM.addPass(std::move(NestedCGPM));
403 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000404 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000405
406 // Parse the inner pipeline inte the nested manager.
407 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000408 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
409 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000410 PipelineText.empty())
411 return false;
412 assert(PipelineText[0] == ')');
413 PipelineText = PipelineText.substr(1);
414
415 // Add the nested pass manager with the appropriate adaptor.
416 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
417 } else {
418 // Otherwise try to parse a pass name.
419 size_t End = PipelineText.find_first_of(",)");
420 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
421 return false;
422 // FIXME: No verifier support for CGSCC passes!
423
424 PipelineText = PipelineText.substr(End);
425 }
426
427 if (PipelineText.empty() || PipelineText[0] == ')')
428 return true;
429
430 assert(PipelineText[0] == ',');
431 PipelineText = PipelineText.substr(1);
432 }
433}
434
Chandler Carruth1ff77242015-03-07 09:02:36 +0000435bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
436 StringRef &PipelineText,
437 bool VerifyEachPass,
438 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000439 for (;;) {
440 // Parse nested pass managers by recursing.
441 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000442 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000443
444 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000445 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000446 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
447 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000448 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000449 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000450 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000451 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000452
453 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000454 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000455 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000456 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000457
458 // Parse the inner pipeline inte the nested manager.
459 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000460 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
461 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000462 PipelineText.empty())
463 return false;
464 assert(PipelineText[0] == ')');
465 PipelineText = PipelineText.substr(1);
466
467 // Add the nested pass manager with the appropriate adaptor.
468 MPM.addPass(
469 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000470 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000471 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000472
473 // Parse the inner pipeline inte the nested manager.
474 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000475 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
476 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000477 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000478 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000479 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000480 PipelineText = PipelineText.substr(1);
481
482 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000483 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000484 } else {
485 // Otherwise try to parse a pass name.
486 size_t End = PipelineText.find_first_of(",)");
487 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
488 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000489 if (VerifyEachPass)
490 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000491
492 PipelineText = PipelineText.substr(End);
493 }
494
495 if (PipelineText.empty() || PipelineText[0] == ')')
496 return true;
497
498 assert(PipelineText[0] == ',');
499 PipelineText = PipelineText.substr(1);
500 }
501}
502
503// Primary pass pipeline description parsing routine.
504// FIXME: Should this routine accept a TargetMachine or require the caller to
505// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000506bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
507 StringRef PipelineText, bool VerifyEachPass,
508 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000509 // By default, try to parse the pipeline as-if it were within an implicit
510 // 'module(...)' pass pipeline. If this will parse at all, it needs to
511 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000512 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000513 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000514
Chandler Carruthea368f12015-01-06 08:37:58 +0000515 // This isn't parsable as a module pipeline, look for the end of a pass name
516 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000517 StringRef FirstName =
518 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000519 assert(!isModulePassName(FirstName) &&
520 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000521
Chandler Carruthea368f12015-01-06 08:37:58 +0000522 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
523 // pipeline.
Justin Bognereecc3c82016-02-25 07:23:08 +0000524 if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000525 CGSCCPassManager CGPM(DebugLogging);
526 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
527 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000528 !PipelineText.empty())
529 return false;
530 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
531 return true;
532 }
533
Chandler Carruthea368f12015-01-06 08:37:58 +0000534 // Similarly, if this looks like a Function pass, parse the whole thing as
535 // a Function pipelien.
Justin Bognereecc3c82016-02-25 07:23:08 +0000536 if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000537 FunctionPassManager FPM(DebugLogging);
538 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
539 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000540 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000541 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000542 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000543 return true;
544 }
Chandler Carruth66445382014-01-11 08:16:35 +0000545
Justin Bognereecc3c82016-02-25 07:23:08 +0000546 // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
547 if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
548 LoopPassManager LPM(DebugLogging);
549 if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
550 DebugLogging) ||
551 !PipelineText.empty())
552 return false;
553 FunctionPassManager FPM(DebugLogging);
554 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
555 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
556 return true;
557 }
558
559
Chandler Carruth66445382014-01-11 08:16:35 +0000560 return false;
561}
Chandler Carruthedf59962016-02-18 09:45:17 +0000562
563bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
564 while (!PipelineText.empty()) {
565 StringRef Name;
566 std::tie(Name, PipelineText) = PipelineText.split(',');
567 if (!parseAAPassName(AA, Name))
568 return false;
569 }
570
571 return true;
572}