blob: b8f6e204a9c7815db33b9feeaff9761360354f1e [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 Carruth29a18a42015-09-12 09:09:14 +000036#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruth66445382014-01-11 08:16:35 +000037
38using namespace llvm;
39
40namespace {
41
Chandler Carruthd8330982014-01-12 09:34:22 +000042/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000043struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000044 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000045 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000046};
47
Chandler Carruth0b576b32015-01-06 02:50:06 +000048/// \brief No-op module analysis.
49struct NoOpModuleAnalysis {
50 struct Result {};
51 Result run(Module &) { return Result(); }
52 static StringRef name() { return "NoOpModuleAnalysis"; }
53 static void *ID() { return (void *)&PassID; }
54private:
55 static char PassID;
56};
57
58char NoOpModuleAnalysis::PassID;
59
Chandler Carruth572e3402014-04-21 11:12:00 +000060/// \brief No-op CGSCC pass which does nothing.
61struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000062 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000063 return PreservedAnalyses::all();
64 }
65 static StringRef name() { return "NoOpCGSCCPass"; }
66};
67
Chandler Carruth0b576b32015-01-06 02:50:06 +000068/// \brief No-op CGSCC analysis.
69struct NoOpCGSCCAnalysis {
70 struct Result {};
71 Result run(LazyCallGraph::SCC &) { return Result(); }
72 static StringRef name() { return "NoOpCGSCCAnalysis"; }
73 static void *ID() { return (void *)&PassID; }
74private:
75 static char PassID;
76};
77
78char NoOpCGSCCAnalysis::PassID;
79
Chandler Carruthd8330982014-01-12 09:34:22 +000080/// \brief No-op function pass which does nothing.
81struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000082 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000083 static StringRef name() { return "NoOpFunctionPass"; }
84};
85
Chandler Carruth0b576b32015-01-06 02:50:06 +000086/// \brief No-op function analysis.
87struct NoOpFunctionAnalysis {
88 struct Result {};
89 Result run(Function &) { return Result(); }
90 static StringRef name() { return "NoOpFunctionAnalysis"; }
91 static void *ID() { return (void *)&PassID; }
92private:
93 static char PassID;
94};
95
96char NoOpFunctionAnalysis::PassID;
97
Chandler Carruth66445382014-01-11 08:16:35 +000098} // End anonymous namespace.
99
Chandler Carruth1ff77242015-03-07 09:02:36 +0000100void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000101#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
102 MAM.registerPass(CREATE_PASS);
103#include "PassRegistry.def"
104}
105
Chandler Carruth1ff77242015-03-07 09:02:36 +0000106void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000107#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
108 CGAM.registerPass(CREATE_PASS);
109#include "PassRegistry.def"
110}
111
Chandler Carruth1ff77242015-03-07 09:02:36 +0000112void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000113#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
114 FAM.registerPass(CREATE_PASS);
115#include "PassRegistry.def"
116}
117
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000118#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000119static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000120#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000121#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000122 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000123 return true;
124#include "PassRegistry.def"
125
Chandler Carruth66445382014-01-11 08:16:35 +0000126 return false;
127}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000128#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000129
Chandler Carruth572e3402014-04-21 11:12:00 +0000130static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000131#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000132#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000133 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000134 return true;
135#include "PassRegistry.def"
136
Chandler Carruth572e3402014-04-21 11:12:00 +0000137 return false;
138}
139
Chandler Carruthd8330982014-01-12 09:34:22 +0000140static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000141#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000142#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000143 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000144 return true;
145#include "PassRegistry.def"
146
Chandler Carruthd8330982014-01-12 09:34:22 +0000147 return false;
148}
149
Chandler Carruth1ff77242015-03-07 09:02:36 +0000150bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000151#define MODULE_PASS(NAME, CREATE_PASS) \
152 if (Name == NAME) { \
153 MPM.addPass(CREATE_PASS); \
154 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000155 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000156#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
157 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000158 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000159 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000160 } \
161 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000162 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000163 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000164 }
165#include "PassRegistry.def"
166
Chandler Carruth66445382014-01-11 08:16:35 +0000167 return false;
168}
169
Chandler Carruth1ff77242015-03-07 09:02:36 +0000170bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000171#define CGSCC_PASS(NAME, CREATE_PASS) \
172 if (Name == NAME) { \
173 CGPM.addPass(CREATE_PASS); \
174 return true; \
175 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000176#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
177 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000178 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000179 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000180 } \
181 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000182 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000183 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000184 }
185#include "PassRegistry.def"
186
Chandler Carruth572e3402014-04-21 11:12:00 +0000187 return false;
188}
189
Chandler Carruth1ff77242015-03-07 09:02:36 +0000190bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
191 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000192#define FUNCTION_PASS(NAME, CREATE_PASS) \
193 if (Name == NAME) { \
194 FPM.addPass(CREATE_PASS); \
195 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000196 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000197#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
198 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000199 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000200 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000201 } \
202 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000203 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000204 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000205 }
206#include "PassRegistry.def"
207
Chandler Carruthd8330982014-01-12 09:34:22 +0000208 return false;
209}
210
Chandler Carruth1ff77242015-03-07 09:02:36 +0000211bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
212 StringRef &PipelineText,
213 bool VerifyEachPass,
214 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000215 for (;;) {
216 // Parse nested pass managers by recursing.
217 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000218 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000219
220 // Parse the inner pipeline inte the nested manager.
221 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000222 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
223 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000224 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000225 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000226 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000227 PipelineText = PipelineText.substr(1);
228
229 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000230 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000231 } else {
232 // Otherwise try to parse a pass name.
233 size_t End = PipelineText.find_first_of(",)");
234 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
235 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000236 if (VerifyEachPass)
237 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000238
239 PipelineText = PipelineText.substr(End);
240 }
241
242 if (PipelineText.empty() || PipelineText[0] == ')')
243 return true;
244
245 assert(PipelineText[0] == ',');
246 PipelineText = PipelineText.substr(1);
247 }
248}
249
Chandler Carruth1ff77242015-03-07 09:02:36 +0000250bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
251 StringRef &PipelineText,
252 bool VerifyEachPass,
253 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000254 for (;;) {
255 // Parse nested pass managers by recursing.
256 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000257 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000258
259 // Parse the inner pipeline into the nested manager.
260 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000261 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
262 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000263 PipelineText.empty())
264 return false;
265 assert(PipelineText[0] == ')');
266 PipelineText = PipelineText.substr(1);
267
268 // Add the nested pass manager with the appropriate adaptor.
269 CGPM.addPass(std::move(NestedCGPM));
270 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000271 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000272
273 // Parse the inner pipeline inte the nested manager.
274 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000275 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
276 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000277 PipelineText.empty())
278 return false;
279 assert(PipelineText[0] == ')');
280 PipelineText = PipelineText.substr(1);
281
282 // Add the nested pass manager with the appropriate adaptor.
283 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
284 } else {
285 // Otherwise try to parse a pass name.
286 size_t End = PipelineText.find_first_of(",)");
287 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
288 return false;
289 // FIXME: No verifier support for CGSCC passes!
290
291 PipelineText = PipelineText.substr(End);
292 }
293
294 if (PipelineText.empty() || PipelineText[0] == ')')
295 return true;
296
297 assert(PipelineText[0] == ',');
298 PipelineText = PipelineText.substr(1);
299 }
300}
301
Chandler Carruth1ff77242015-03-07 09:02:36 +0000302bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
303 StringRef &PipelineText,
304 bool VerifyEachPass,
305 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000306 for (;;) {
307 // Parse nested pass managers by recursing.
308 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000309 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000310
311 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000312 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000313 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
314 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000315 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000316 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000317 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000318 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000319
320 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000321 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000322 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000323 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000324
325 // Parse the inner pipeline inte the nested manager.
326 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000327 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
328 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000329 PipelineText.empty())
330 return false;
331 assert(PipelineText[0] == ')');
332 PipelineText = PipelineText.substr(1);
333
334 // Add the nested pass manager with the appropriate adaptor.
335 MPM.addPass(
336 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000337 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000338 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000339
340 // Parse the inner pipeline inte the nested manager.
341 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000342 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
343 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000344 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000345 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000346 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000347 PipelineText = PipelineText.substr(1);
348
349 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000350 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000351 } else {
352 // Otherwise try to parse a pass name.
353 size_t End = PipelineText.find_first_of(",)");
354 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
355 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000356 if (VerifyEachPass)
357 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000358
359 PipelineText = PipelineText.substr(End);
360 }
361
362 if (PipelineText.empty() || PipelineText[0] == ')')
363 return true;
364
365 assert(PipelineText[0] == ',');
366 PipelineText = PipelineText.substr(1);
367 }
368}
369
370// Primary pass pipeline description parsing routine.
371// FIXME: Should this routine accept a TargetMachine or require the caller to
372// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000373bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
374 StringRef PipelineText, bool VerifyEachPass,
375 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000376 // By default, try to parse the pipeline as-if it were within an implicit
377 // 'module(...)' pass pipeline. If this will parse at all, it needs to
378 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000379 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000380 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000381
Chandler Carruthea368f12015-01-06 08:37:58 +0000382 // This isn't parsable as a module pipeline, look for the end of a pass name
383 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000384 StringRef FirstName =
385 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000386 assert(!isModulePassName(FirstName) &&
387 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000388
Chandler Carruthea368f12015-01-06 08:37:58 +0000389 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
390 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000391 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000392 CGSCCPassManager CGPM(DebugLogging);
393 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
394 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000395 !PipelineText.empty())
396 return false;
397 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
398 return true;
399 }
400
Chandler Carruthea368f12015-01-06 08:37:58 +0000401 // Similarly, if this looks like a Function pass, parse the whole thing as
402 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000403 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000404 FunctionPassManager FPM(DebugLogging);
405 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
406 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000407 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000408 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000409 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000410 return true;
411 }
Chandler Carruth66445382014-01-11 08:16:35 +0000412
413 return false;
414}