blob: f043c92fd4f01359b981f6f88d30d420b8761b06 [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"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000027#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth2b3d0442016-02-20 04:01:45 +000028#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
Chandler Carruthd6091a02016-02-20 04:03:06 +000029#include "llvm/Analysis/ScopedNoAliasAA.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000030#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000031#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruthc1dc3842016-02-20 04:04:52 +000032#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000033#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000034#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000035#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000036#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000037#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000038#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000039#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth9c4ed172016-02-18 11:03:11 +000040#include "llvm/Transforms/IPO/FunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000041#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000042#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000043#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000044#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000045#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000046#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000047#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000048#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000049
50using namespace llvm;
51
52namespace {
53
Chandler Carruthd8330982014-01-12 09:34:22 +000054/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000055struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000056 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000057 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000058};
59
Chandler Carruth0b576b32015-01-06 02:50:06 +000060/// \brief No-op module analysis.
61struct NoOpModuleAnalysis {
62 struct Result {};
63 Result run(Module &) { return Result(); }
64 static StringRef name() { return "NoOpModuleAnalysis"; }
65 static void *ID() { return (void *)&PassID; }
66private:
67 static char PassID;
68};
69
70char NoOpModuleAnalysis::PassID;
71
Chandler Carruth572e3402014-04-21 11:12:00 +000072/// \brief No-op CGSCC pass which does nothing.
73struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000074 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000075 return PreservedAnalyses::all();
76 }
77 static StringRef name() { return "NoOpCGSCCPass"; }
78};
79
Chandler Carruth0b576b32015-01-06 02:50:06 +000080/// \brief No-op CGSCC analysis.
81struct NoOpCGSCCAnalysis {
82 struct Result {};
83 Result run(LazyCallGraph::SCC &) { return Result(); }
84 static StringRef name() { return "NoOpCGSCCAnalysis"; }
85 static void *ID() { return (void *)&PassID; }
86private:
87 static char PassID;
88};
89
90char NoOpCGSCCAnalysis::PassID;
91
Chandler Carruthd8330982014-01-12 09:34:22 +000092/// \brief No-op function pass which does nothing.
93struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000094 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000095 static StringRef name() { return "NoOpFunctionPass"; }
96};
97
Chandler Carruth0b576b32015-01-06 02:50:06 +000098/// \brief No-op function analysis.
99struct NoOpFunctionAnalysis {
100 struct Result {};
101 Result run(Function &) { return Result(); }
102 static StringRef name() { return "NoOpFunctionAnalysis"; }
103 static void *ID() { return (void *)&PassID; }
104private:
105 static char PassID;
106};
107
108char NoOpFunctionAnalysis::PassID;
109
Justin Bognereecc3c82016-02-25 07:23:08 +0000110/// \brief No-op loop pass which does nothing.
111struct NoOpLoopPass {
112 PreservedAnalyses run(Loop &L) { return PreservedAnalyses::all(); }
113 static StringRef name() { return "NoOpLoopPass"; }
114};
115
116/// \brief No-op loop analysis.
117struct NoOpLoopAnalysis {
118 struct Result {};
119 Result run(Loop &) { return Result(); }
120 static StringRef name() { return "NoOpLoopAnalysis"; }
121 static void *ID() { return (void *)&PassID; }
122private:
123 static char PassID;
124};
125
126char NoOpLoopAnalysis::PassID;
127
Chandler Carruth66445382014-01-11 08:16:35 +0000128} // End anonymous namespace.
129
Chandler Carruth1ff77242015-03-07 09:02:36 +0000130void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000131#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000132 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000133#include "PassRegistry.def"
134}
135
Chandler Carruth1ff77242015-03-07 09:02:36 +0000136void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000137#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000138 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000139#include "PassRegistry.def"
140}
141
Chandler Carruth1ff77242015-03-07 09:02:36 +0000142void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000143#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000144 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000145#include "PassRegistry.def"
146}
147
Justin Bognereecc3c82016-02-25 07:23:08 +0000148void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
149#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
150 LAM.registerPass([&] { return CREATE_PASS; });
151#include "PassRegistry.def"
152}
153
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000154#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000155static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000156#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000157#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000158 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000159 return true;
160#include "PassRegistry.def"
161
Chandler Carruth66445382014-01-11 08:16:35 +0000162 return false;
163}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000164#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000165
Chandler Carruth572e3402014-04-21 11:12:00 +0000166static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000167#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000168#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000169 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000170 return true;
171#include "PassRegistry.def"
172
Chandler Carruth572e3402014-04-21 11:12:00 +0000173 return false;
174}
175
Chandler Carruthd8330982014-01-12 09:34:22 +0000176static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000177#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000178#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000179 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000180 return true;
181#include "PassRegistry.def"
182
Chandler Carruthd8330982014-01-12 09:34:22 +0000183 return false;
184}
185
Justin Bognereecc3c82016-02-25 07:23:08 +0000186static bool isLoopPassName(StringRef Name) {
187#define LOOP_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
188#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
189 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
190 return true;
191#include "PassRegistry.def"
192
193 return false;
194}
195
Chandler Carruth1ff77242015-03-07 09:02:36 +0000196bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000197#define MODULE_PASS(NAME, CREATE_PASS) \
198 if (Name == NAME) { \
199 MPM.addPass(CREATE_PASS); \
200 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000201 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000202#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
203 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000204 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000205 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000206 } \
207 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000208 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000209 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000210 }
211#include "PassRegistry.def"
212
Chandler Carruth66445382014-01-11 08:16:35 +0000213 return false;
214}
215
Chandler Carruth1ff77242015-03-07 09:02:36 +0000216bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000217#define CGSCC_PASS(NAME, CREATE_PASS) \
218 if (Name == NAME) { \
219 CGPM.addPass(CREATE_PASS); \
220 return true; \
221 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000222#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
223 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000224 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000225 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000226 } \
227 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000228 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000229 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000230 }
231#include "PassRegistry.def"
232
Chandler Carruth572e3402014-04-21 11:12:00 +0000233 return false;
234}
235
Chandler Carruth1ff77242015-03-07 09:02:36 +0000236bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
237 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000238#define FUNCTION_PASS(NAME, CREATE_PASS) \
239 if (Name == NAME) { \
240 FPM.addPass(CREATE_PASS); \
241 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000242 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000243#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
244 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000245 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000246 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000247 } \
248 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000249 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000250 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000251 }
252#include "PassRegistry.def"
253
Chandler Carruthd8330982014-01-12 09:34:22 +0000254 return false;
255}
256
Justin Bognereecc3c82016-02-25 07:23:08 +0000257bool PassBuilder::parseLoopPassName(LoopPassManager &FPM,
258 StringRef Name) {
259#define LOOP_PASS(NAME, CREATE_PASS) \
260 if (Name == NAME) { \
261 FPM.addPass(CREATE_PASS); \
262 return true; \
263 }
264#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
265 if (Name == "require<" NAME ">") { \
266 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
267 return true; \
268 } \
269 if (Name == "invalidate<" NAME ">") { \
270 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
271 return true; \
272 }
273#include "PassRegistry.def"
274
275 return false;
276}
277
Chandler Carruthedf59962016-02-18 09:45:17 +0000278bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
279#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
280 if (Name == NAME) { \
281 AA.registerFunctionAnalysis<decltype(CREATE_PASS)>(); \
282 return true; \
283 }
284#include "PassRegistry.def"
285
286 return false;
287}
288
Justin Bognereecc3c82016-02-25 07:23:08 +0000289bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
290 StringRef &PipelineText,
291 bool VerifyEachPass,
292 bool DebugLogging) {
293 for (;;) {
294 // Parse nested pass managers by recursing.
295 if (PipelineText.startswith("loop(")) {
296 LoopPassManager NestedLPM(DebugLogging);
297
298 // Parse the inner pipeline inte the nested manager.
299 PipelineText = PipelineText.substr(strlen("loop("));
300 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
301 DebugLogging) ||
302 PipelineText.empty())
303 return false;
304 assert(PipelineText[0] == ')');
305 PipelineText = PipelineText.substr(1);
306
307 // Add the nested pass manager with the appropriate adaptor.
308 LPM.addPass(std::move(NestedLPM));
309 } else {
310 // Otherwise try to parse a pass name.
311 size_t End = PipelineText.find_first_of(",)");
312 if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
313 return false;
314 // TODO: Ideally, we would run a LoopVerifierPass() here in the
315 // VerifyEachPass case, but we don't have such a verifier yet.
316
317 PipelineText = PipelineText.substr(End);
318 }
319
320 if (PipelineText.empty() || PipelineText[0] == ')')
321 return true;
322
323 assert(PipelineText[0] == ',');
324 PipelineText = PipelineText.substr(1);
325 }
326}
327
Chandler Carruth1ff77242015-03-07 09:02:36 +0000328bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
329 StringRef &PipelineText,
330 bool VerifyEachPass,
331 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000332 for (;;) {
333 // Parse nested pass managers by recursing.
334 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000335 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000336
337 // Parse the inner pipeline inte the nested manager.
338 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000339 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
340 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000341 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000342 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000343 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000344 PipelineText = PipelineText.substr(1);
345
346 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000347 FPM.addPass(std::move(NestedFPM));
Justin Bognereecc3c82016-02-25 07:23:08 +0000348 } else if (PipelineText.startswith("loop(")) {
349 LoopPassManager NestedLPM(DebugLogging);
350
351 // Parse the inner pipeline inte the nested manager.
352 PipelineText = PipelineText.substr(strlen("loop("));
353 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
354 DebugLogging) ||
355 PipelineText.empty())
356 return false;
357 assert(PipelineText[0] == ')');
358 PipelineText = PipelineText.substr(1);
359
360 // Add the nested pass manager with the appropriate adaptor.
361 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000362 } else {
363 // Otherwise try to parse a pass name.
364 size_t End = PipelineText.find_first_of(",)");
365 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
366 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000367 if (VerifyEachPass)
368 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000369
370 PipelineText = PipelineText.substr(End);
371 }
372
373 if (PipelineText.empty() || PipelineText[0] == ')')
374 return true;
375
376 assert(PipelineText[0] == ',');
377 PipelineText = PipelineText.substr(1);
378 }
379}
380
Chandler Carruth1ff77242015-03-07 09:02:36 +0000381bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
382 StringRef &PipelineText,
383 bool VerifyEachPass,
384 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000385 for (;;) {
386 // Parse nested pass managers by recursing.
387 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000388 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000389
390 // Parse the inner pipeline into the nested manager.
391 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000392 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
393 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000394 PipelineText.empty())
395 return false;
396 assert(PipelineText[0] == ')');
397 PipelineText = PipelineText.substr(1);
398
399 // Add the nested pass manager with the appropriate adaptor.
400 CGPM.addPass(std::move(NestedCGPM));
401 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000402 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000403
404 // Parse the inner pipeline inte the nested manager.
405 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000406 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
407 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000408 PipelineText.empty())
409 return false;
410 assert(PipelineText[0] == ')');
411 PipelineText = PipelineText.substr(1);
412
413 // Add the nested pass manager with the appropriate adaptor.
414 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
415 } else {
416 // Otherwise try to parse a pass name.
417 size_t End = PipelineText.find_first_of(",)");
418 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
419 return false;
420 // FIXME: No verifier support for CGSCC passes!
421
422 PipelineText = PipelineText.substr(End);
423 }
424
425 if (PipelineText.empty() || PipelineText[0] == ')')
426 return true;
427
428 assert(PipelineText[0] == ',');
429 PipelineText = PipelineText.substr(1);
430 }
431}
432
Chandler Carruth1ff77242015-03-07 09:02:36 +0000433bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
434 StringRef &PipelineText,
435 bool VerifyEachPass,
436 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000437 for (;;) {
438 // Parse nested pass managers by recursing.
439 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000440 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000441
442 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000443 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000444 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
445 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000446 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000447 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000448 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000449 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000450
451 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000452 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000453 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000454 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000455
456 // Parse the inner pipeline inte the nested manager.
457 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000458 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
459 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000460 PipelineText.empty())
461 return false;
462 assert(PipelineText[0] == ')');
463 PipelineText = PipelineText.substr(1);
464
465 // Add the nested pass manager with the appropriate adaptor.
466 MPM.addPass(
467 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000468 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000469 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000470
471 // Parse the inner pipeline inte the nested manager.
472 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000473 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
474 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000475 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000476 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000477 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000478 PipelineText = PipelineText.substr(1);
479
480 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000481 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000482 } else {
483 // Otherwise try to parse a pass name.
484 size_t End = PipelineText.find_first_of(",)");
485 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
486 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000487 if (VerifyEachPass)
488 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000489
490 PipelineText = PipelineText.substr(End);
491 }
492
493 if (PipelineText.empty() || PipelineText[0] == ')')
494 return true;
495
496 assert(PipelineText[0] == ',');
497 PipelineText = PipelineText.substr(1);
498 }
499}
500
501// Primary pass pipeline description parsing routine.
502// FIXME: Should this routine accept a TargetMachine or require the caller to
503// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000504bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
505 StringRef PipelineText, bool VerifyEachPass,
506 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000507 // By default, try to parse the pipeline as-if it were within an implicit
508 // 'module(...)' pass pipeline. If this will parse at all, it needs to
509 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000510 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000511 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000512
Chandler Carruthea368f12015-01-06 08:37:58 +0000513 // This isn't parsable as a module pipeline, look for the end of a pass name
514 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000515 StringRef FirstName =
516 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000517 assert(!isModulePassName(FirstName) &&
518 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000519
Chandler Carruthea368f12015-01-06 08:37:58 +0000520 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
521 // pipeline.
Justin Bognereecc3c82016-02-25 07:23:08 +0000522 if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000523 CGSCCPassManager CGPM(DebugLogging);
524 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
525 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000526 !PipelineText.empty())
527 return false;
528 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
529 return true;
530 }
531
Chandler Carruthea368f12015-01-06 08:37:58 +0000532 // Similarly, if this looks like a Function pass, parse the whole thing as
533 // a Function pipelien.
Justin Bognereecc3c82016-02-25 07:23:08 +0000534 if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000535 FunctionPassManager FPM(DebugLogging);
536 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
537 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000538 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000539 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000540 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000541 return true;
542 }
Chandler Carruth66445382014-01-11 08:16:35 +0000543
Justin Bognereecc3c82016-02-25 07:23:08 +0000544 // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
545 if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
546 LoopPassManager LPM(DebugLogging);
547 if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
548 DebugLogging) ||
549 !PipelineText.empty())
550 return false;
551 FunctionPassManager FPM(DebugLogging);
552 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
553 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
554 return true;
555 }
556
557
Chandler Carruth66445382014-01-11 08:16:35 +0000558 return false;
559}
Chandler Carruthedf59962016-02-18 09:45:17 +0000560
561bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
562 while (!PipelineText.empty()) {
563 StringRef Name;
564 std::tie(Name, PipelineText) = PipelineText.split(',');
565 if (!parseAAPassName(AA, Name))
566 return false;
567 }
568
569 return true;
570}