blob: bd30fce7dc90b8c337fd56eacd70d9a7a3801f4a [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"
Chandler Carruthbf71a342014-02-06 04:37:03 +000025#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000026#include "llvm/Analysis/LoopInfo.h"
Hongbin Zheng3f978402016-02-25 17:54:07 +000027#include "llvm/Analysis/PostDominators.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000028#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth2b3d0442016-02-20 04:01:45 +000029#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
Chandler Carruthd6091a02016-02-20 04:03:06 +000030#include "llvm/Analysis/ScopedNoAliasAA.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000031#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000032#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruthc1dc3842016-02-20 04:04:52 +000033#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000034#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000035#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000036#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000037#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000038#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000039#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000040#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth9c4ed172016-02-18 11:03:11 +000041#include "llvm/Transforms/IPO/FunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000042#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000043#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000044#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000045#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000046#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000047#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000048#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000049#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000050
51using namespace llvm;
52
53namespace {
54
Chandler Carruthd8330982014-01-12 09:34:22 +000055/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000056struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000057 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000058 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000059};
60
Chandler Carruth0b576b32015-01-06 02:50:06 +000061/// \brief No-op module analysis.
62struct NoOpModuleAnalysis {
63 struct Result {};
64 Result run(Module &) { return Result(); }
65 static StringRef name() { return "NoOpModuleAnalysis"; }
66 static void *ID() { return (void *)&PassID; }
67private:
68 static char PassID;
69};
70
71char NoOpModuleAnalysis::PassID;
72
Chandler Carruth572e3402014-04-21 11:12:00 +000073/// \brief No-op CGSCC pass which does nothing.
74struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000075 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000076 return PreservedAnalyses::all();
77 }
78 static StringRef name() { return "NoOpCGSCCPass"; }
79};
80
Chandler Carruth0b576b32015-01-06 02:50:06 +000081/// \brief No-op CGSCC analysis.
82struct NoOpCGSCCAnalysis {
83 struct Result {};
84 Result run(LazyCallGraph::SCC &) { return Result(); }
85 static StringRef name() { return "NoOpCGSCCAnalysis"; }
86 static void *ID() { return (void *)&PassID; }
87private:
88 static char PassID;
89};
90
91char NoOpCGSCCAnalysis::PassID;
92
Chandler Carruthd8330982014-01-12 09:34:22 +000093/// \brief No-op function pass which does nothing.
94struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000095 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000096 static StringRef name() { return "NoOpFunctionPass"; }
97};
98
Chandler Carruth0b576b32015-01-06 02:50:06 +000099/// \brief No-op function analysis.
100struct NoOpFunctionAnalysis {
101 struct Result {};
102 Result run(Function &) { return Result(); }
103 static StringRef name() { return "NoOpFunctionAnalysis"; }
104 static void *ID() { return (void *)&PassID; }
105private:
106 static char PassID;
107};
108
109char NoOpFunctionAnalysis::PassID;
110
Justin Bognereecc3c82016-02-25 07:23:08 +0000111/// \brief No-op loop pass which does nothing.
112struct NoOpLoopPass {
113 PreservedAnalyses run(Loop &L) { return PreservedAnalyses::all(); }
114 static StringRef name() { return "NoOpLoopPass"; }
115};
116
117/// \brief No-op loop analysis.
118struct NoOpLoopAnalysis {
119 struct Result {};
120 Result run(Loop &) { return Result(); }
121 static StringRef name() { return "NoOpLoopAnalysis"; }
122 static void *ID() { return (void *)&PassID; }
123private:
124 static char PassID;
125};
126
127char NoOpLoopAnalysis::PassID;
128
Chandler Carruth66445382014-01-11 08:16:35 +0000129} // End anonymous namespace.
130
Chandler Carruth1ff77242015-03-07 09:02:36 +0000131void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000132#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000133 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000134#include "PassRegistry.def"
135}
136
Chandler Carruth1ff77242015-03-07 09:02:36 +0000137void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000138#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000139 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000140#include "PassRegistry.def"
141}
142
Chandler Carruth1ff77242015-03-07 09:02:36 +0000143void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000144#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000145 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000146#include "PassRegistry.def"
147}
148
Justin Bognereecc3c82016-02-25 07:23:08 +0000149void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
150#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
151 LAM.registerPass([&] { return CREATE_PASS; });
152#include "PassRegistry.def"
153}
154
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000155#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000156static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000157#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000158#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000159 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000160 return true;
161#include "PassRegistry.def"
162
Chandler Carruth66445382014-01-11 08:16:35 +0000163 return false;
164}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000165#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000166
Chandler Carruth572e3402014-04-21 11:12:00 +0000167static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000168#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000169#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000170 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000171 return true;
172#include "PassRegistry.def"
173
Chandler Carruth572e3402014-04-21 11:12:00 +0000174 return false;
175}
176
Chandler Carruthd8330982014-01-12 09:34:22 +0000177static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000178#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000179#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000180 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000181 return true;
182#include "PassRegistry.def"
183
Chandler Carruthd8330982014-01-12 09:34:22 +0000184 return false;
185}
186
Justin Bognereecc3c82016-02-25 07:23:08 +0000187static bool isLoopPassName(StringRef Name) {
188#define LOOP_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
189#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
190 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
191 return true;
192#include "PassRegistry.def"
193
194 return false;
195}
196
Chandler Carruth1ff77242015-03-07 09:02:36 +0000197bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000198#define MODULE_PASS(NAME, CREATE_PASS) \
199 if (Name == NAME) { \
200 MPM.addPass(CREATE_PASS); \
201 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000202 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000203#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
204 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000205 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000206 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000207 } \
208 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000209 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000210 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000211 }
212#include "PassRegistry.def"
213
Chandler Carruth66445382014-01-11 08:16:35 +0000214 return false;
215}
216
Chandler Carruth1ff77242015-03-07 09:02:36 +0000217bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000218#define CGSCC_PASS(NAME, CREATE_PASS) \
219 if (Name == NAME) { \
220 CGPM.addPass(CREATE_PASS); \
221 return true; \
222 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000223#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
224 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000225 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000226 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000227 } \
228 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000229 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000230 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000231 }
232#include "PassRegistry.def"
233
Chandler Carruth572e3402014-04-21 11:12:00 +0000234 return false;
235}
236
Chandler Carruth1ff77242015-03-07 09:02:36 +0000237bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
238 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000239#define FUNCTION_PASS(NAME, CREATE_PASS) \
240 if (Name == NAME) { \
241 FPM.addPass(CREATE_PASS); \
242 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000243 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000244#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
245 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000246 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000247 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000248 } \
249 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000250 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000251 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000252 }
253#include "PassRegistry.def"
254
Chandler Carruthd8330982014-01-12 09:34:22 +0000255 return false;
256}
257
Justin Bognereecc3c82016-02-25 07:23:08 +0000258bool PassBuilder::parseLoopPassName(LoopPassManager &FPM,
259 StringRef Name) {
260#define LOOP_PASS(NAME, CREATE_PASS) \
261 if (Name == NAME) { \
262 FPM.addPass(CREATE_PASS); \
263 return true; \
264 }
265#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
266 if (Name == "require<" NAME ">") { \
267 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
268 return true; \
269 } \
270 if (Name == "invalidate<" NAME ">") { \
271 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
272 return true; \
273 }
274#include "PassRegistry.def"
275
276 return false;
277}
278
Chandler Carruthedf59962016-02-18 09:45:17 +0000279bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
280#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
281 if (Name == NAME) { \
282 AA.registerFunctionAnalysis<decltype(CREATE_PASS)>(); \
283 return true; \
284 }
285#include "PassRegistry.def"
286
287 return false;
288}
289
Justin Bognereecc3c82016-02-25 07:23:08 +0000290bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
291 StringRef &PipelineText,
292 bool VerifyEachPass,
293 bool DebugLogging) {
294 for (;;) {
295 // Parse nested pass managers by recursing.
296 if (PipelineText.startswith("loop(")) {
297 LoopPassManager NestedLPM(DebugLogging);
298
299 // Parse the inner pipeline inte the nested manager.
300 PipelineText = PipelineText.substr(strlen("loop("));
301 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
302 DebugLogging) ||
303 PipelineText.empty())
304 return false;
305 assert(PipelineText[0] == ')');
306 PipelineText = PipelineText.substr(1);
307
308 // Add the nested pass manager with the appropriate adaptor.
309 LPM.addPass(std::move(NestedLPM));
310 } else {
311 // Otherwise try to parse a pass name.
312 size_t End = PipelineText.find_first_of(",)");
313 if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
314 return false;
315 // TODO: Ideally, we would run a LoopVerifierPass() here in the
316 // VerifyEachPass case, but we don't have such a verifier yet.
317
318 PipelineText = PipelineText.substr(End);
319 }
320
321 if (PipelineText.empty() || PipelineText[0] == ')')
322 return true;
323
324 assert(PipelineText[0] == ',');
325 PipelineText = PipelineText.substr(1);
326 }
327}
328
Chandler Carruth1ff77242015-03-07 09:02:36 +0000329bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
330 StringRef &PipelineText,
331 bool VerifyEachPass,
332 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000333 for (;;) {
334 // Parse nested pass managers by recursing.
335 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000336 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000337
338 // Parse the inner pipeline inte the nested manager.
339 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000340 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
341 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000342 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000343 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000344 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000345 PipelineText = PipelineText.substr(1);
346
347 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000348 FPM.addPass(std::move(NestedFPM));
Justin Bognereecc3c82016-02-25 07:23:08 +0000349 } else if (PipelineText.startswith("loop(")) {
350 LoopPassManager NestedLPM(DebugLogging);
351
352 // Parse the inner pipeline inte the nested manager.
353 PipelineText = PipelineText.substr(strlen("loop("));
354 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
355 DebugLogging) ||
356 PipelineText.empty())
357 return false;
358 assert(PipelineText[0] == ')');
359 PipelineText = PipelineText.substr(1);
360
361 // Add the nested pass manager with the appropriate adaptor.
362 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000363 } else {
364 // Otherwise try to parse a pass name.
365 size_t End = PipelineText.find_first_of(",)");
366 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
367 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000368 if (VerifyEachPass)
369 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000370
371 PipelineText = PipelineText.substr(End);
372 }
373
374 if (PipelineText.empty() || PipelineText[0] == ')')
375 return true;
376
377 assert(PipelineText[0] == ',');
378 PipelineText = PipelineText.substr(1);
379 }
380}
381
Chandler Carruth1ff77242015-03-07 09:02:36 +0000382bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
383 StringRef &PipelineText,
384 bool VerifyEachPass,
385 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000386 for (;;) {
387 // Parse nested pass managers by recursing.
388 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000389 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000390
391 // Parse the inner pipeline into the nested manager.
392 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000393 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
394 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000395 PipelineText.empty())
396 return false;
397 assert(PipelineText[0] == ')');
398 PipelineText = PipelineText.substr(1);
399
400 // Add the nested pass manager with the appropriate adaptor.
401 CGPM.addPass(std::move(NestedCGPM));
402 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000403 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000404
405 // Parse the inner pipeline inte the nested manager.
406 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000407 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
408 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000409 PipelineText.empty())
410 return false;
411 assert(PipelineText[0] == ')');
412 PipelineText = PipelineText.substr(1);
413
414 // Add the nested pass manager with the appropriate adaptor.
415 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
416 } else {
417 // Otherwise try to parse a pass name.
418 size_t End = PipelineText.find_first_of(",)");
419 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
420 return false;
421 // FIXME: No verifier support for CGSCC passes!
422
423 PipelineText = PipelineText.substr(End);
424 }
425
426 if (PipelineText.empty() || PipelineText[0] == ')')
427 return true;
428
429 assert(PipelineText[0] == ',');
430 PipelineText = PipelineText.substr(1);
431 }
432}
433
Chandler Carruth1ff77242015-03-07 09:02:36 +0000434bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
435 StringRef &PipelineText,
436 bool VerifyEachPass,
437 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000438 for (;;) {
439 // Parse nested pass managers by recursing.
440 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000441 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000442
443 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000444 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000445 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
446 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000447 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000448 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000449 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000450 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000451
452 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000453 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000454 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000455 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000456
457 // Parse the inner pipeline inte the nested manager.
458 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000459 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
460 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000461 PipelineText.empty())
462 return false;
463 assert(PipelineText[0] == ')');
464 PipelineText = PipelineText.substr(1);
465
466 // Add the nested pass manager with the appropriate adaptor.
467 MPM.addPass(
468 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000469 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000470 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000471
472 // Parse the inner pipeline inte the nested manager.
473 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000474 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
475 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000476 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000477 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000478 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000479 PipelineText = PipelineText.substr(1);
480
481 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000482 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000483 } else {
484 // Otherwise try to parse a pass name.
485 size_t End = PipelineText.find_first_of(",)");
486 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
487 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000488 if (VerifyEachPass)
489 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000490
491 PipelineText = PipelineText.substr(End);
492 }
493
494 if (PipelineText.empty() || PipelineText[0] == ')')
495 return true;
496
497 assert(PipelineText[0] == ',');
498 PipelineText = PipelineText.substr(1);
499 }
500}
501
502// Primary pass pipeline description parsing routine.
503// FIXME: Should this routine accept a TargetMachine or require the caller to
504// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000505bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
506 StringRef PipelineText, bool VerifyEachPass,
507 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000508 // By default, try to parse the pipeline as-if it were within an implicit
509 // 'module(...)' pass pipeline. If this will parse at all, it needs to
510 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000511 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000512 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000513
Chandler Carruthea368f12015-01-06 08:37:58 +0000514 // This isn't parsable as a module pipeline, look for the end of a pass name
515 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000516 StringRef FirstName =
517 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000518 assert(!isModulePassName(FirstName) &&
519 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000520
Chandler Carruthea368f12015-01-06 08:37:58 +0000521 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
522 // pipeline.
Justin Bognereecc3c82016-02-25 07:23:08 +0000523 if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000524 CGSCCPassManager CGPM(DebugLogging);
525 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
526 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000527 !PipelineText.empty())
528 return false;
529 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
530 return true;
531 }
532
Chandler Carruthea368f12015-01-06 08:37:58 +0000533 // Similarly, if this looks like a Function pass, parse the whole thing as
534 // a Function pipelien.
Justin Bognereecc3c82016-02-25 07:23:08 +0000535 if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000536 FunctionPassManager FPM(DebugLogging);
537 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
538 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000539 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000540 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000541 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000542 return true;
543 }
Chandler Carruth66445382014-01-11 08:16:35 +0000544
Justin Bognereecc3c82016-02-25 07:23:08 +0000545 // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
546 if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
547 LoopPassManager LPM(DebugLogging);
548 if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
549 DebugLogging) ||
550 !PipelineText.empty())
551 return false;
552 FunctionPassManager FPM(DebugLogging);
553 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
554 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
555 return true;
556 }
557
558
Chandler Carruth66445382014-01-11 08:16:35 +0000559 return false;
560}
Chandler Carruthedf59962016-02-18 09:45:17 +0000561
562bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
563 while (!PipelineText.empty()) {
564 StringRef Name;
565 std::tie(Name, PipelineText) = PipelineText.split(',');
566 if (!parseAAPassName(AA, Name))
567 return false;
568 }
569
570 return true;
571}