blob: 7c683472cc2c9586f55351f1b5c513e13f4d46dd [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 Carruth83ba2692015-01-24 04:19:17 +000032#include "llvm/Transforms/InstCombine/InstCombine.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000033#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000034#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruthfdffd872015-02-01 11:34:21 +000035#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000036
37using namespace llvm;
38
39namespace {
40
Chandler Carruthd8330982014-01-12 09:34:22 +000041/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000042struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000043 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000044 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000045};
46
Chandler Carruth0b576b32015-01-06 02:50:06 +000047/// \brief No-op module analysis.
48struct NoOpModuleAnalysis {
49 struct Result {};
50 Result run(Module &) { return Result(); }
51 static StringRef name() { return "NoOpModuleAnalysis"; }
52 static void *ID() { return (void *)&PassID; }
53private:
54 static char PassID;
55};
56
57char NoOpModuleAnalysis::PassID;
58
Chandler Carruth572e3402014-04-21 11:12:00 +000059/// \brief No-op CGSCC pass which does nothing.
60struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000061 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000062 return PreservedAnalyses::all();
63 }
64 static StringRef name() { return "NoOpCGSCCPass"; }
65};
66
Chandler Carruth0b576b32015-01-06 02:50:06 +000067/// \brief No-op CGSCC analysis.
68struct NoOpCGSCCAnalysis {
69 struct Result {};
70 Result run(LazyCallGraph::SCC &) { return Result(); }
71 static StringRef name() { return "NoOpCGSCCAnalysis"; }
72 static void *ID() { return (void *)&PassID; }
73private:
74 static char PassID;
75};
76
77char NoOpCGSCCAnalysis::PassID;
78
Chandler Carruthd8330982014-01-12 09:34:22 +000079/// \brief No-op function pass which does nothing.
80struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000081 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000082 static StringRef name() { return "NoOpFunctionPass"; }
83};
84
Chandler Carruth0b576b32015-01-06 02:50:06 +000085/// \brief No-op function analysis.
86struct NoOpFunctionAnalysis {
87 struct Result {};
88 Result run(Function &) { return Result(); }
89 static StringRef name() { return "NoOpFunctionAnalysis"; }
90 static void *ID() { return (void *)&PassID; }
91private:
92 static char PassID;
93};
94
95char NoOpFunctionAnalysis::PassID;
96
Chandler Carruth66445382014-01-11 08:16:35 +000097} // End anonymous namespace.
98
Chandler Carruth1ff77242015-03-07 09:02:36 +000099void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000100#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
101 MAM.registerPass(CREATE_PASS);
102#include "PassRegistry.def"
103}
104
Chandler Carruth1ff77242015-03-07 09:02:36 +0000105void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000106#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
107 CGAM.registerPass(CREATE_PASS);
108#include "PassRegistry.def"
109}
110
Chandler Carruth1ff77242015-03-07 09:02:36 +0000111void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000112#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
113 FAM.registerPass(CREATE_PASS);
114#include "PassRegistry.def"
115}
116
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000117#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000118static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000119#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000120#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000121 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000122 return true;
123#include "PassRegistry.def"
124
Chandler Carruth66445382014-01-11 08:16:35 +0000125 return false;
126}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000127#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000128
Chandler Carruth572e3402014-04-21 11:12:00 +0000129static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000130#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000131#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000132 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000133 return true;
134#include "PassRegistry.def"
135
Chandler Carruth572e3402014-04-21 11:12:00 +0000136 return false;
137}
138
Chandler Carruthd8330982014-01-12 09:34:22 +0000139static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000140#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000141#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000142 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000143 return true;
144#include "PassRegistry.def"
145
Chandler Carruthd8330982014-01-12 09:34:22 +0000146 return false;
147}
148
Chandler Carruth1ff77242015-03-07 09:02:36 +0000149bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000150#define MODULE_PASS(NAME, CREATE_PASS) \
151 if (Name == NAME) { \
152 MPM.addPass(CREATE_PASS); \
153 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000154 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000155#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
156 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000157 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000158 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000159 } \
160 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000161 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000162 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000163 }
164#include "PassRegistry.def"
165
Chandler Carruth66445382014-01-11 08:16:35 +0000166 return false;
167}
168
Chandler Carruth1ff77242015-03-07 09:02:36 +0000169bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000170#define CGSCC_PASS(NAME, CREATE_PASS) \
171 if (Name == NAME) { \
172 CGPM.addPass(CREATE_PASS); \
173 return true; \
174 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000175#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
176 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000177 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000178 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000179 } \
180 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000181 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000182 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000183 }
184#include "PassRegistry.def"
185
Chandler Carruth572e3402014-04-21 11:12:00 +0000186 return false;
187}
188
Chandler Carruth1ff77242015-03-07 09:02:36 +0000189bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
190 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000191#define FUNCTION_PASS(NAME, CREATE_PASS) \
192 if (Name == NAME) { \
193 FPM.addPass(CREATE_PASS); \
194 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000195 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000196#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
197 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000198 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000199 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000200 } \
201 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000202 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000203 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000204 }
205#include "PassRegistry.def"
206
Chandler Carruthd8330982014-01-12 09:34:22 +0000207 return false;
208}
209
Chandler Carruth1ff77242015-03-07 09:02:36 +0000210bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
211 StringRef &PipelineText,
212 bool VerifyEachPass,
213 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000214 for (;;) {
215 // Parse nested pass managers by recursing.
216 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000217 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000218
219 // Parse the inner pipeline inte the nested manager.
220 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000221 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
222 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000223 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000224 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000225 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000226 PipelineText = PipelineText.substr(1);
227
228 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000229 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000230 } else {
231 // Otherwise try to parse a pass name.
232 size_t End = PipelineText.find_first_of(",)");
233 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
234 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000235 if (VerifyEachPass)
236 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000237
238 PipelineText = PipelineText.substr(End);
239 }
240
241 if (PipelineText.empty() || PipelineText[0] == ')')
242 return true;
243
244 assert(PipelineText[0] == ',');
245 PipelineText = PipelineText.substr(1);
246 }
247}
248
Chandler Carruth1ff77242015-03-07 09:02:36 +0000249bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
250 StringRef &PipelineText,
251 bool VerifyEachPass,
252 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000253 for (;;) {
254 // Parse nested pass managers by recursing.
255 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000256 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000257
258 // Parse the inner pipeline into the nested manager.
259 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000260 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
261 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000262 PipelineText.empty())
263 return false;
264 assert(PipelineText[0] == ')');
265 PipelineText = PipelineText.substr(1);
266
267 // Add the nested pass manager with the appropriate adaptor.
268 CGPM.addPass(std::move(NestedCGPM));
269 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000270 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000271
272 // Parse the inner pipeline inte the nested manager.
273 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000274 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
275 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000276 PipelineText.empty())
277 return false;
278 assert(PipelineText[0] == ')');
279 PipelineText = PipelineText.substr(1);
280
281 // Add the nested pass manager with the appropriate adaptor.
282 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
283 } else {
284 // Otherwise try to parse a pass name.
285 size_t End = PipelineText.find_first_of(",)");
286 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
287 return false;
288 // FIXME: No verifier support for CGSCC passes!
289
290 PipelineText = PipelineText.substr(End);
291 }
292
293 if (PipelineText.empty() || PipelineText[0] == ')')
294 return true;
295
296 assert(PipelineText[0] == ',');
297 PipelineText = PipelineText.substr(1);
298 }
299}
300
Chandler Carruth1ff77242015-03-07 09:02:36 +0000301bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
302 StringRef &PipelineText,
303 bool VerifyEachPass,
304 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000305 for (;;) {
306 // Parse nested pass managers by recursing.
307 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000308 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000309
310 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000311 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000312 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
313 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000314 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000315 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000316 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000317 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000318
319 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000320 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000321 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000322 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000323
324 // Parse the inner pipeline inte the nested manager.
325 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000326 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
327 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000328 PipelineText.empty())
329 return false;
330 assert(PipelineText[0] == ')');
331 PipelineText = PipelineText.substr(1);
332
333 // Add the nested pass manager with the appropriate adaptor.
334 MPM.addPass(
335 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000336 } else 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 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000350 } else {
351 // Otherwise try to parse a pass name.
352 size_t End = PipelineText.find_first_of(",)");
353 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
354 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000355 if (VerifyEachPass)
356 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000357
358 PipelineText = PipelineText.substr(End);
359 }
360
361 if (PipelineText.empty() || PipelineText[0] == ')')
362 return true;
363
364 assert(PipelineText[0] == ',');
365 PipelineText = PipelineText.substr(1);
366 }
367}
368
369// Primary pass pipeline description parsing routine.
370// FIXME: Should this routine accept a TargetMachine or require the caller to
371// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000372bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
373 StringRef PipelineText, bool VerifyEachPass,
374 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000375 // By default, try to parse the pipeline as-if it were within an implicit
376 // 'module(...)' pass pipeline. If this will parse at all, it needs to
377 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000378 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000379 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000380
Chandler Carruthea368f12015-01-06 08:37:58 +0000381 // This isn't parsable as a module pipeline, look for the end of a pass name
382 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000383 StringRef FirstName =
384 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000385 assert(!isModulePassName(FirstName) &&
386 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000387
Chandler Carruthea368f12015-01-06 08:37:58 +0000388 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
389 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000390 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000391 CGSCCPassManager CGPM(DebugLogging);
392 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
393 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000394 !PipelineText.empty())
395 return false;
396 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
397 return true;
398 }
399
Chandler Carruthea368f12015-01-06 08:37:58 +0000400 // Similarly, if this looks like a Function pass, parse the whole thing as
401 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000402 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000403 FunctionPassManager FPM(DebugLogging);
404 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
405 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000406 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000407 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000408 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000409 return true;
410 }
Chandler Carruth66445382014-01-11 08:16:35 +0000411
412 return false;
413}