blob: 1a762dfd71b032f56246f252f59937d9e6089bf7 [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) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000108 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000109#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) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000114 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000115#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) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000120 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000121#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 Carruthedf59962016-02-18 09:45:17 +0000217bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
218#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
219 if (Name == NAME) { \
220 AA.registerFunctionAnalysis<decltype(CREATE_PASS)>(); \
221 return true; \
222 }
223#include "PassRegistry.def"
224
225 return false;
226}
227
Chandler Carruth1ff77242015-03-07 09:02:36 +0000228bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
229 StringRef &PipelineText,
230 bool VerifyEachPass,
231 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000232 for (;;) {
233 // Parse nested pass managers by recursing.
234 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000235 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000236
237 // Parse the inner pipeline inte the nested manager.
238 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000239 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
240 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000241 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000242 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000243 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000244 PipelineText = PipelineText.substr(1);
245
246 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000247 FPM.addPass(std::move(NestedFPM));
Chandler Carruthd8330982014-01-12 09:34:22 +0000248 } else {
249 // Otherwise try to parse a pass name.
250 size_t End = PipelineText.find_first_of(",)");
251 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
252 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000253 if (VerifyEachPass)
254 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000255
256 PipelineText = PipelineText.substr(End);
257 }
258
259 if (PipelineText.empty() || PipelineText[0] == ')')
260 return true;
261
262 assert(PipelineText[0] == ',');
263 PipelineText = PipelineText.substr(1);
264 }
265}
266
Chandler Carruth1ff77242015-03-07 09:02:36 +0000267bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
268 StringRef &PipelineText,
269 bool VerifyEachPass,
270 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000271 for (;;) {
272 // Parse nested pass managers by recursing.
273 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000274 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000275
276 // Parse the inner pipeline into the nested manager.
277 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000278 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
279 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000280 PipelineText.empty())
281 return false;
282 assert(PipelineText[0] == ')');
283 PipelineText = PipelineText.substr(1);
284
285 // Add the nested pass manager with the appropriate adaptor.
286 CGPM.addPass(std::move(NestedCGPM));
287 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000288 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000289
290 // Parse the inner pipeline inte the nested manager.
291 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000292 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
293 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000294 PipelineText.empty())
295 return false;
296 assert(PipelineText[0] == ')');
297 PipelineText = PipelineText.substr(1);
298
299 // Add the nested pass manager with the appropriate adaptor.
300 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
301 } else {
302 // Otherwise try to parse a pass name.
303 size_t End = PipelineText.find_first_of(",)");
304 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
305 return false;
306 // FIXME: No verifier support for CGSCC passes!
307
308 PipelineText = PipelineText.substr(End);
309 }
310
311 if (PipelineText.empty() || PipelineText[0] == ')')
312 return true;
313
314 assert(PipelineText[0] == ',');
315 PipelineText = PipelineText.substr(1);
316 }
317}
318
Chandler Carruth1ff77242015-03-07 09:02:36 +0000319bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
320 StringRef &PipelineText,
321 bool VerifyEachPass,
322 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000323 for (;;) {
324 // Parse nested pass managers by recursing.
325 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000326 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000327
328 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000329 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000330 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
331 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000332 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000333 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000334 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000335 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000336
337 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000338 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000339 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000340 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000341
342 // Parse the inner pipeline inte the nested manager.
343 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000344 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
345 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000346 PipelineText.empty())
347 return false;
348 assert(PipelineText[0] == ')');
349 PipelineText = PipelineText.substr(1);
350
351 // Add the nested pass manager with the appropriate adaptor.
352 MPM.addPass(
353 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000354 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000355 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000356
357 // Parse the inner pipeline inte the nested manager.
358 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000359 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
360 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000361 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000362 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000363 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000364 PipelineText = PipelineText.substr(1);
365
366 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000367 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000368 } else {
369 // Otherwise try to parse a pass name.
370 size_t End = PipelineText.find_first_of(",)");
371 if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
372 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000373 if (VerifyEachPass)
374 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000375
376 PipelineText = PipelineText.substr(End);
377 }
378
379 if (PipelineText.empty() || PipelineText[0] == ')')
380 return true;
381
382 assert(PipelineText[0] == ',');
383 PipelineText = PipelineText.substr(1);
384 }
385}
386
387// Primary pass pipeline description parsing routine.
388// FIXME: Should this routine accept a TargetMachine or require the caller to
389// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000390bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
391 StringRef PipelineText, bool VerifyEachPass,
392 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000393 // By default, try to parse the pipeline as-if it were within an implicit
394 // 'module(...)' pass pipeline. If this will parse at all, it needs to
395 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000396 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000397 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000398
Chandler Carruthea368f12015-01-06 08:37:58 +0000399 // This isn't parsable as a module pipeline, look for the end of a pass name
400 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000401 StringRef FirstName =
402 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000403 assert(!isModulePassName(FirstName) &&
404 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000405
Chandler Carruthea368f12015-01-06 08:37:58 +0000406 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
407 // pipeline.
Chandler Carruth572e3402014-04-21 11:12:00 +0000408 if (isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000409 CGSCCPassManager CGPM(DebugLogging);
410 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
411 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000412 !PipelineText.empty())
413 return false;
414 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
415 return true;
416 }
417
Chandler Carruthea368f12015-01-06 08:37:58 +0000418 // Similarly, if this looks like a Function pass, parse the whole thing as
419 // a Function pipelien.
Chandler Carruthd8330982014-01-12 09:34:22 +0000420 if (isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000421 FunctionPassManager FPM(DebugLogging);
422 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
423 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000424 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000425 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000426 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000427 return true;
428 }
Chandler Carruth66445382014-01-11 08:16:35 +0000429
430 return false;
431}
Chandler Carruthedf59962016-02-18 09:45:17 +0000432
433bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
434 while (!PipelineText.empty()) {
435 StringRef Name;
436 std::tie(Name, PipelineText) = PipelineText.split(',');
437 if (!parseAAPassName(AA, Name))
438 return false;
439 }
440
441 return true;
442}