blob: 8ba81f72a71715c590b62ebd69d871c478c4d09a [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 Carruthdf8b2232015-01-22 21:53:09 +000019#include "llvm/Analysis/AssumptionCache.h"
Chandler Carruth572e3402014-04-21 11:12:00 +000020#include "llvm/Analysis/CGSCCPassManager.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000021#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000022#include "llvm/Analysis/LoopInfo.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000023#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000024#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000025#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000026#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000027#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000028#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000029#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000030#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000031#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000032#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000033#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000034#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000035#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000036#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000037#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000038#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000039#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000040#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000041
42using namespace llvm;
43
44namespace {
45
Chandler Carruthd8330982014-01-12 09:34:22 +000046/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000047struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000048 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000049 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000050};
51
Chandler Carruth0b576b32015-01-06 02:50:06 +000052/// \brief No-op module analysis.
53struct NoOpModuleAnalysis {
54 struct Result {};
55 Result run(Module &) { return Result(); }
56 static StringRef name() { return "NoOpModuleAnalysis"; }
57 static void *ID() { return (void *)&PassID; }
58private:
59 static char PassID;
60};
61
62char NoOpModuleAnalysis::PassID;
63
Chandler Carruth572e3402014-04-21 11:12:00 +000064/// \brief No-op CGSCC pass which does nothing.
65struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000066 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000067 return PreservedAnalyses::all();
68 }
69 static StringRef name() { return "NoOpCGSCCPass"; }
70};
71
Chandler Carruth0b576b32015-01-06 02:50:06 +000072/// \brief No-op CGSCC analysis.
73struct NoOpCGSCCAnalysis {
74 struct Result {};
75 Result run(LazyCallGraph::SCC &) { return Result(); }
76 static StringRef name() { return "NoOpCGSCCAnalysis"; }
77 static void *ID() { return (void *)&PassID; }
78private:
79 static char PassID;
80};
81
82char NoOpCGSCCAnalysis::PassID;
83
Chandler Carruthd8330982014-01-12 09:34:22 +000084/// \brief No-op function pass which does nothing.
85struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000086 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000087 static StringRef name() { return "NoOpFunctionPass"; }
88};
89
Chandler Carruth0b576b32015-01-06 02:50:06 +000090/// \brief No-op function analysis.
91struct NoOpFunctionAnalysis {
92 struct Result {};
93 Result run(Function &) { return Result(); }
94 static StringRef name() { return "NoOpFunctionAnalysis"; }
95 static void *ID() { return (void *)&PassID; }
96private:
97 static char PassID;
98};
99
100char NoOpFunctionAnalysis::PassID;
101
Chandler Carruth66445382014-01-11 08:16:35 +0000102} // End anonymous namespace.
103
Chandler Carruth1ff77242015-03-07 09:02:36 +0000104void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000105#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
106 MAM.registerPass(CREATE_PASS);
107#include "PassRegistry.def"
108}
109
Chandler Carruth1ff77242015-03-07 09:02:36 +0000110void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000111#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
112 CGAM.registerPass(CREATE_PASS);
113#include "PassRegistry.def"
114}
115
Chandler Carruth1ff77242015-03-07 09:02:36 +0000116void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000117#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
118 FAM.registerPass(CREATE_PASS);
119#include "PassRegistry.def"
120}
121
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000122#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000123static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000124#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000125#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000126 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000127 return true;
128#include "PassRegistry.def"
129
Chandler Carruth66445382014-01-11 08:16:35 +0000130 return false;
131}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000132#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000133
Chandler Carruth572e3402014-04-21 11:12:00 +0000134static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000135#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000136#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000137 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000138 return true;
139#include "PassRegistry.def"
140
Chandler Carruth572e3402014-04-21 11:12:00 +0000141 return false;
142}
143
Chandler Carruthd8330982014-01-12 09:34:22 +0000144static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000145#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000146#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000147 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000148 return true;
149#include "PassRegistry.def"
150
Chandler Carruthd8330982014-01-12 09:34:22 +0000151 return false;
152}
153
Chandler Carruth1ff77242015-03-07 09:02:36 +0000154bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000155#define MODULE_PASS(NAME, CREATE_PASS) \
156 if (Name == NAME) { \
157 MPM.addPass(CREATE_PASS); \
158 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000159 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000160#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
161 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000162 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000163 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000164 } \
165 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000166 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000167 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000168 }
169#include "PassRegistry.def"
170
Chandler Carruth66445382014-01-11 08:16:35 +0000171 return false;
172}
173
Chandler Carruth1ff77242015-03-07 09:02:36 +0000174bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000175#define CGSCC_PASS(NAME, CREATE_PASS) \
176 if (Name == NAME) { \
177 CGPM.addPass(CREATE_PASS); \
178 return true; \
179 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000180#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
181 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000182 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000183 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000184 } \
185 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000186 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000187 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000188 }
189#include "PassRegistry.def"
190
Chandler Carruth572e3402014-04-21 11:12:00 +0000191 return false;
192}
193
Chandler Carruth1ff77242015-03-07 09:02:36 +0000194bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
195 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000196#define FUNCTION_PASS(NAME, CREATE_PASS) \
197 if (Name == NAME) { \
198 FPM.addPass(CREATE_PASS); \
199 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000200 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000201#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
202 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000203 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000204 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000205 } \
206 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000207 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000208 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000209 }
210#include "PassRegistry.def"
211
Chandler Carruthd8330982014-01-12 09:34:22 +0000212 return false;
213}
214
Chandler Carruth1ff77242015-03-07 09:02:36 +0000215bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
216 StringRef &PipelineText,
217 bool VerifyEachPass,
218 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000219 for (;;) {
220 // Parse nested pass managers by recursing.
221 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000222 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000223
224 // Parse the inner pipeline inte the nested manager.
225 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000226 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
227 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000228 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000229 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000230 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000231 PipelineText = PipelineText.substr(1);
232
233 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000234 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000235 } else {
236 // Otherwise try to parse a pass name.
237 size_t End = PipelineText.find_first_of(",)");
238 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
239 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000240 if (VerifyEachPass)
241 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000242
243 PipelineText = PipelineText.substr(End);
244 }
245
246 if (PipelineText.empty() || PipelineText[0] == ')')
247 return true;
248
249 assert(PipelineText[0] == ',');
250 PipelineText = PipelineText.substr(1);
251 }
252}
253
Chandler Carruth1ff77242015-03-07 09:02:36 +0000254bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
255 StringRef &PipelineText,
256 bool VerifyEachPass,
257 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000258 for (;;) {
259 // Parse nested pass managers by recursing.
260 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000261 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000262
263 // Parse the inner pipeline into the nested manager.
264 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000265 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
266 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000267 PipelineText.empty())
268 return false;
269 assert(PipelineText[0] == ')');
270 PipelineText = PipelineText.substr(1);
271
272 // Add the nested pass manager with the appropriate adaptor.
273 CGPM.addPass(std::move(NestedCGPM));
274 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000275 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000276
277 // Parse the inner pipeline inte the nested manager.
278 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000279 if (!parseFunctionPassPipeline(NestedFPM, 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(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
288 } else {
289 // Otherwise try to parse a pass name.
290 size_t End = PipelineText.find_first_of(",)");
291 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
292 return false;
293 // FIXME: No verifier support for CGSCC passes!
294
295 PipelineText = PipelineText.substr(End);
296 }
297
298 if (PipelineText.empty() || PipelineText[0] == ')')
299 return true;
300
301 assert(PipelineText[0] == ',');
302 PipelineText = PipelineText.substr(1);
303 }
304}
305
Chandler Carruth1ff77242015-03-07 09:02:36 +0000306bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
307 StringRef &PipelineText,
308 bool VerifyEachPass,
309 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000310 for (;;) {
311 // Parse nested pass managers by recursing.
312 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000313 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000314
315 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000316 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000317 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
318 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000319 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000320 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000321 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000322 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000323
324 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000325 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000326 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000327 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000328
329 // Parse the inner pipeline inte the nested manager.
330 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000331 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
332 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000333 PipelineText.empty())
334 return false;
335 assert(PipelineText[0] == ')');
336 PipelineText = PipelineText.substr(1);
337
338 // Add the nested pass manager with the appropriate adaptor.
339 MPM.addPass(
340 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000341 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000342 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000343
344 // Parse the inner pipeline inte the nested manager.
345 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000346 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
347 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000348 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000349 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000350 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000351 PipelineText = PipelineText.substr(1);
352
353 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000354 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000355 } else {
356 // Otherwise try to parse a pass name.
357 size_t End = PipelineText.find_first_of(",)");
358 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
359 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000360 if (VerifyEachPass)
361 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000362
363 PipelineText = PipelineText.substr(End);
364 }
365
366 if (PipelineText.empty() || PipelineText[0] == ')')
367 return true;
368
369 assert(PipelineText[0] == ',');
370 PipelineText = PipelineText.substr(1);
371 }
372}
373
374// Primary pass pipeline description parsing routine.
375// FIXME: Should this routine accept a TargetMachine or require the caller to
376// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000377bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
378 StringRef PipelineText, bool VerifyEachPass,
379 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000380 // By default, try to parse the pipeline as-if it were within an implicit
381 // 'module(...)' pass pipeline. If this will parse at all, it needs to
382 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000383 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000384 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000385
Chandler Carruthea368f12015-01-06 08:37:58 +0000386 // This isn't parsable as a module pipeline, look for the end of a pass name
387 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000388 StringRef FirstName =
389 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000390 assert(!isModulePassName(FirstName) &&
391 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000392
Chandler Carruthea368f12015-01-06 08:37:58 +0000393 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
394 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000395 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000396 CGSCCPassManager CGPM(DebugLogging);
397 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
398 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000399 !PipelineText.empty())
400 return false;
401 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
402 return true;
403 }
404
Chandler Carruthea368f12015-01-06 08:37:58 +0000405 // Similarly, if this looks like a Function pass, parse the whole thing as
406 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000407 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000408 FunctionPassManager FPM(DebugLogging);
409 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
410 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000411 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000412 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000413 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000414 return true;
415 }
Chandler Carruth66445382014-01-11 08:16:35 +0000416
417 return false;
418}