blob: 68ce41aeaff642332bb52259789db86e9642f9e7 [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 Carruthdf8b2232015-01-22 21:53:09 +000020#include "llvm/Analysis/AssumptionCache.h"
Chandler Carruthbece8d52016-02-13 23:46:24 +000021#include "llvm/Analysis/BasicAliasAnalysis.h"
Chandler Carruth572e3402014-04-21 11:12:00 +000022#include "llvm/Analysis/CGSCCPassManager.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000023#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000024#include "llvm/Analysis/LoopInfo.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000025#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000026#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000027#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000028#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000029#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000030#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000031#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000032#include "llvm/Support/Debug.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000033#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000034#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000035#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000036#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000037#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000038#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000039#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000040#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000041#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000042#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth66445382014-01-11 08:16:35 +000043
44using namespace llvm;
45
46namespace {
47
Chandler Carruthd8330982014-01-12 09:34:22 +000048/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000049struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000050 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000051 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000052};
53
Chandler Carruth0b576b32015-01-06 02:50:06 +000054/// \brief No-op module analysis.
55struct NoOpModuleAnalysis {
56 struct Result {};
57 Result run(Module &) { return Result(); }
58 static StringRef name() { return "NoOpModuleAnalysis"; }
59 static void *ID() { return (void *)&PassID; }
60private:
61 static char PassID;
62};
63
64char NoOpModuleAnalysis::PassID;
65
Chandler Carruth572e3402014-04-21 11:12:00 +000066/// \brief No-op CGSCC pass which does nothing.
67struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000068 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000069 return PreservedAnalyses::all();
70 }
71 static StringRef name() { return "NoOpCGSCCPass"; }
72};
73
Chandler Carruth0b576b32015-01-06 02:50:06 +000074/// \brief No-op CGSCC analysis.
75struct NoOpCGSCCAnalysis {
76 struct Result {};
77 Result run(LazyCallGraph::SCC &) { return Result(); }
78 static StringRef name() { return "NoOpCGSCCAnalysis"; }
79 static void *ID() { return (void *)&PassID; }
80private:
81 static char PassID;
82};
83
84char NoOpCGSCCAnalysis::PassID;
85
Chandler Carruthd8330982014-01-12 09:34:22 +000086/// \brief No-op function pass which does nothing.
87struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000088 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000089 static StringRef name() { return "NoOpFunctionPass"; }
90};
91
Chandler Carruth0b576b32015-01-06 02:50:06 +000092/// \brief No-op function analysis.
93struct NoOpFunctionAnalysis {
94 struct Result {};
95 Result run(Function &) { return Result(); }
96 static StringRef name() { return "NoOpFunctionAnalysis"; }
97 static void *ID() { return (void *)&PassID; }
98private:
99 static char PassID;
100};
101
102char NoOpFunctionAnalysis::PassID;
103
Chandler Carruth66445382014-01-11 08:16:35 +0000104} // End anonymous namespace.
105
Chandler Carruth1ff77242015-03-07 09:02:36 +0000106void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000107#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
108 MAM.registerPass(CREATE_PASS);
109#include "PassRegistry.def"
110}
111
Chandler Carruth1ff77242015-03-07 09:02:36 +0000112void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000113#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
114 CGAM.registerPass(CREATE_PASS);
115#include "PassRegistry.def"
116}
117
Chandler Carruth1ff77242015-03-07 09:02:36 +0000118void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000119#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
120 FAM.registerPass(CREATE_PASS);
121#include "PassRegistry.def"
122}
123
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000124#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000125static bool isModulePassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000126#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000127#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000128 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000129 return true;
130#include "PassRegistry.def"
131
Chandler Carruth66445382014-01-11 08:16:35 +0000132 return false;
133}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000134#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000135
Chandler Carruth572e3402014-04-21 11:12:00 +0000136static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000137#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000138#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000139 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000140 return true;
141#include "PassRegistry.def"
142
Chandler Carruth572e3402014-04-21 11:12:00 +0000143 return false;
144}
145
Chandler Carruthd8330982014-01-12 09:34:22 +0000146static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000147#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000148#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000149 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000150 return true;
151#include "PassRegistry.def"
152
Chandler Carruthd8330982014-01-12 09:34:22 +0000153 return false;
154}
155
Chandler Carruth1ff77242015-03-07 09:02:36 +0000156bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000157#define MODULE_PASS(NAME, CREATE_PASS) \
158 if (Name == NAME) { \
159 MPM.addPass(CREATE_PASS); \
160 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000161 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000162#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
163 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000164 MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000165 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000166 } \
167 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000168 MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000169 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000170 }
171#include "PassRegistry.def"
172
Chandler Carruth66445382014-01-11 08:16:35 +0000173 return false;
174}
175
Chandler Carruth1ff77242015-03-07 09:02:36 +0000176bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000177#define CGSCC_PASS(NAME, CREATE_PASS) \
178 if (Name == NAME) { \
179 CGPM.addPass(CREATE_PASS); \
180 return true; \
181 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000182#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
183 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000184 CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000185 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000186 } \
187 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000188 CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000189 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000190 }
191#include "PassRegistry.def"
192
Chandler Carruth572e3402014-04-21 11:12:00 +0000193 return false;
194}
195
Chandler Carruth1ff77242015-03-07 09:02:36 +0000196bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
197 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000198#define FUNCTION_PASS(NAME, CREATE_PASS) \
199 if (Name == NAME) { \
200 FPM.addPass(CREATE_PASS); \
201 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000202 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000203#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
204 if (Name == "require<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000205 FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000206 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000207 } \
208 if (Name == "invalidate<" NAME ">") { \
Chandler Carruthe5b0a9c2015-01-07 11:14:51 +0000209 FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000210 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000211 }
212#include "PassRegistry.def"
213
Chandler Carruthd8330982014-01-12 09:34:22 +0000214 return false;
215}
216
Chandler Carruth1ff77242015-03-07 09:02:36 +0000217bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
218 StringRef &PipelineText,
219 bool VerifyEachPass,
220 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000221 for (;;) {
222 // Parse nested pass managers by recursing.
223 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000224 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000225
226 // Parse the inner pipeline inte the nested manager.
227 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000228 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
229 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000230 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000231 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000232 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000233 PipelineText = PipelineText.substr(1);
234
235 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000236 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000237 } else {
238 // Otherwise try to parse a pass name.
239 size_t End = PipelineText.find_first_of(",)");
240 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
241 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000242 if (VerifyEachPass)
243 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000244
245 PipelineText = PipelineText.substr(End);
246 }
247
248 if (PipelineText.empty() || PipelineText[0] == ')')
249 return true;
250
251 assert(PipelineText[0] == ',');
252 PipelineText = PipelineText.substr(1);
253 }
254}
255
Chandler Carruth1ff77242015-03-07 09:02:36 +0000256bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
257 StringRef &PipelineText,
258 bool VerifyEachPass,
259 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000260 for (;;) {
261 // Parse nested pass managers by recursing.
262 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000263 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000264
265 // Parse the inner pipeline into the nested manager.
266 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000267 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
268 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000269 PipelineText.empty())
270 return false;
271 assert(PipelineText[0] == ')');
272 PipelineText = PipelineText.substr(1);
273
274 // Add the nested pass manager with the appropriate adaptor.
275 CGPM.addPass(std::move(NestedCGPM));
276 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000277 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000278
279 // Parse the inner pipeline inte the nested manager.
280 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000281 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
282 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000283 PipelineText.empty())
284 return false;
285 assert(PipelineText[0] == ')');
286 PipelineText = PipelineText.substr(1);
287
288 // Add the nested pass manager with the appropriate adaptor.
289 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
290 } else {
291 // Otherwise try to parse a pass name.
292 size_t End = PipelineText.find_first_of(",)");
293 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
294 return false;
295 // FIXME: No verifier support for CGSCC passes!
296
297 PipelineText = PipelineText.substr(End);
298 }
299
300 if (PipelineText.empty() || PipelineText[0] == ')')
301 return true;
302
303 assert(PipelineText[0] == ',');
304 PipelineText = PipelineText.substr(1);
305 }
306}
307
Chandler Carruth1ff77242015-03-07 09:02:36 +0000308bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
309 StringRef &PipelineText,
310 bool VerifyEachPass,
311 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000312 for (;;) {
313 // Parse nested pass managers by recursing.
314 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000315 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000316
317 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000318 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000319 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
320 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000321 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000322 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000323 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000324 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000325
326 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000327 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000328 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000329 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000330
331 // Parse the inner pipeline inte the nested manager.
332 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000333 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
334 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000335 PipelineText.empty())
336 return false;
337 assert(PipelineText[0] == ')');
338 PipelineText = PipelineText.substr(1);
339
340 // Add the nested pass manager with the appropriate adaptor.
341 MPM.addPass(
342 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000343 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000344 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000345
346 // Parse the inner pipeline inte the nested manager.
347 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000348 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
349 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000350 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000351 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000352 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000353 PipelineText = PipelineText.substr(1);
354
355 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000356 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000357 } else {
358 // Otherwise try to parse a pass name.
359 size_t End = PipelineText.find_first_of(",)");
360 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
361 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000362 if (VerifyEachPass)
363 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000364
365 PipelineText = PipelineText.substr(End);
366 }
367
368 if (PipelineText.empty() || PipelineText[0] == ')')
369 return true;
370
371 assert(PipelineText[0] == ',');
372 PipelineText = PipelineText.substr(1);
373 }
374}
375
376// Primary pass pipeline description parsing routine.
377// FIXME: Should this routine accept a TargetMachine or require the caller to
378// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000379bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
380 StringRef PipelineText, bool VerifyEachPass,
381 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000382 // By default, try to parse the pipeline as-if it were within an implicit
383 // 'module(...)' pass pipeline. If this will parse at all, it needs to
384 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000385 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000386 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000387
Chandler Carruthea368f12015-01-06 08:37:58 +0000388 // This isn't parsable as a module pipeline, look for the end of a pass name
389 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000390 StringRef FirstName =
391 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000392 assert(!isModulePassName(FirstName) &&
393 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000394
Chandler Carruthea368f12015-01-06 08:37:58 +0000395 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
396 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000397 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000398 CGSCCPassManager CGPM(DebugLogging);
399 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
400 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000401 !PipelineText.empty())
402 return false;
403 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
404 return true;
405 }
406
Chandler Carruthea368f12015-01-06 08:37:58 +0000407 // Similarly, if this looks like a Function pass, parse the whole thing as
408 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000409 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000410 FunctionPassManager FPM(DebugLogging);
411 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
412 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000413 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000414 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000415 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000416 return true;
417 }
Chandler Carruth66445382014-01-11 08:16:35 +0000418
419 return false;
420}