blob: aeb6b64a25f59fae124cb8df102d541dee4e5bff [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 Carruth8b5a74192016-02-28 22:16:03 +000019#include "llvm/ADT/StringSwitch.h"
Chandler Carruth6f5770b102016-02-13 23:32:00 +000020#include "llvm/Analysis/AliasAnalysis.h"
Chandler Carruth4f846a52016-02-20 03:46:03 +000021#include "llvm/Analysis/AliasAnalysisEvaluator.h"
Chandler Carruthdf8b2232015-01-22 21:53:09 +000022#include "llvm/Analysis/AssumptionCache.h"
Chandler Carruthbece8d52016-02-13 23:46:24 +000023#include "llvm/Analysis/BasicAliasAnalysis.h"
Chandler Carruth342c6712016-02-20 03:52:02 +000024#include "llvm/Analysis/CFLAliasAnalysis.h"
Chandler Carruth572e3402014-04-21 11:12:00 +000025#include "llvm/Analysis/CGSCCPassManager.h"
Chandler Carruth4c660f72016-03-10 11:24:11 +000026#include "llvm/Analysis/CallGraph.h"
Hongbin Zheng751337f2016-02-25 17:54:15 +000027#include "llvm/Analysis/DominanceFrontier.h"
Chandler Carruthbf71a342014-02-06 04:37:03 +000028#include "llvm/Analysis/LazyCallGraph.h"
Chandler Carruthaaf0b4c2015-01-20 10:58:50 +000029#include "llvm/Analysis/LoopInfo.h"
Chandler Carruth61440d22016-03-10 00:55:30 +000030#include "llvm/Analysis/MemoryDependenceAnalysis.h"
Hongbin Zheng3f978402016-02-25 17:54:07 +000031#include "llvm/Analysis/PostDominators.h"
Hongbin Zhengbc539772016-02-25 17:54:25 +000032#include "llvm/Analysis/RegionInfo.h"
Chandler Carruth2f1fd162015-08-17 02:08:17 +000033#include "llvm/Analysis/ScalarEvolution.h"
Chandler Carruth2b3d0442016-02-20 04:01:45 +000034#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
Chandler Carruthd6091a02016-02-20 04:03:06 +000035#include "llvm/Analysis/ScopedNoAliasAA.h"
Chandler Carruth8ca43222015-01-15 11:39:46 +000036#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000037#include "llvm/Analysis/TargetTransformInfo.h"
Chandler Carruthc1dc3842016-02-20 04:04:52 +000038#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
Chandler Carruth64764b42015-01-14 10:19:28 +000039#include "llvm/IR/Dominators.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000040#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth66445382014-01-11 08:16:35 +000041#include "llvm/IR/PassManager.h"
Chandler Carruth4d356312014-01-20 11:34:08 +000042#include "llvm/IR/Verifier.h"
Chandler Carruth52eef882014-01-12 12:15:39 +000043#include "llvm/Support/Debug.h"
Chandler Carruth8b5a74192016-02-28 22:16:03 +000044#include "llvm/Support/Regex.h"
Chandler Carruthe0385522015-02-01 10:11:22 +000045#include "llvm/Target/TargetMachine.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000046#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
Chandler Carruth9c4ed172016-02-18 11:03:11 +000047#include "llvm/Transforms/IPO/FunctionAttrs.h"
Chandler Carruth3a040e62015-12-27 08:41:34 +000048#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
Justin Bogner21e15372015-10-30 23:28:12 +000049#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000050#include "llvm/Transforms/InstCombine/InstCombine.h"
Justin Bogner19b67992015-10-30 23:13:18 +000051#include "llvm/Transforms/Scalar/ADCE.h"
Chandler Carruthe8c686a2015-02-01 10:51:23 +000052#include "llvm/Transforms/Scalar/EarlyCSE.h"
Chandler Carruth43e590e2015-01-24 11:13:02 +000053#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
Chandler Carruth89c45a12016-03-11 08:50:55 +000054#include "llvm/Transforms/Scalar/GVN.h"
Chandler Carruth29a18a42015-09-12 09:09:14 +000055#include "llvm/Transforms/Scalar/SROA.h"
Chandler Carruthf49f1a872015-12-27 08:13:45 +000056#include "llvm/Transforms/Scalar/SimplifyCFG.h"
Chandler Carruth58dde8c2016-02-26 12:17:54 +000057#include <type_traits>
Chandler Carruth66445382014-01-11 08:16:35 +000058
59using namespace llvm;
60
Chandler Carruth8b5a74192016-02-28 22:16:03 +000061static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$");
62
Chandler Carruth66445382014-01-11 08:16:35 +000063namespace {
64
Chandler Carruthd8330982014-01-12 09:34:22 +000065/// \brief No-op module pass which does nothing.
Chandler Carruth66445382014-01-11 08:16:35 +000066struct NoOpModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000067 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +000068 static StringRef name() { return "NoOpModulePass"; }
Chandler Carruth66445382014-01-11 08:16:35 +000069};
70
Chandler Carruth0b576b32015-01-06 02:50:06 +000071/// \brief No-op module analysis.
Chandler Carruth3a634352016-02-26 11:44:45 +000072struct NoOpModuleAnalysis : AnalysisBase<NoOpModuleAnalysis> {
Chandler Carruth0b576b32015-01-06 02:50:06 +000073 struct Result {};
74 Result run(Module &) { return Result(); }
75 static StringRef name() { return "NoOpModuleAnalysis"; }
Chandler Carruth0b576b32015-01-06 02:50:06 +000076};
77
Chandler Carruth572e3402014-04-21 11:12:00 +000078/// \brief No-op CGSCC pass which does nothing.
79struct NoOpCGSCCPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000080 PreservedAnalyses run(LazyCallGraph::SCC &C) {
Chandler Carruth572e3402014-04-21 11:12:00 +000081 return PreservedAnalyses::all();
82 }
83 static StringRef name() { return "NoOpCGSCCPass"; }
84};
85
Chandler Carruth0b576b32015-01-06 02:50:06 +000086/// \brief No-op CGSCC analysis.
Chandler Carruth3a634352016-02-26 11:44:45 +000087struct NoOpCGSCCAnalysis : AnalysisBase<NoOpCGSCCAnalysis> {
Chandler Carruth0b576b32015-01-06 02:50:06 +000088 struct Result {};
89 Result run(LazyCallGraph::SCC &) { return Result(); }
90 static StringRef name() { return "NoOpCGSCCAnalysis"; }
Chandler Carruth0b576b32015-01-06 02:50:06 +000091};
92
Chandler Carruthd8330982014-01-12 09:34:22 +000093/// \brief No-op function pass which does nothing.
94struct NoOpFunctionPass {
Chandler Carruthd174ce42015-01-05 02:47:05 +000095 PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
Chandler Carruthd8330982014-01-12 09:34:22 +000096 static StringRef name() { return "NoOpFunctionPass"; }
97};
98
Chandler Carruth0b576b32015-01-06 02:50:06 +000099/// \brief No-op function analysis.
Chandler Carruth3a634352016-02-26 11:44:45 +0000100struct NoOpFunctionAnalysis : AnalysisBase<NoOpFunctionAnalysis> {
Chandler Carruth0b576b32015-01-06 02:50:06 +0000101 struct Result {};
102 Result run(Function &) { return Result(); }
103 static StringRef name() { return "NoOpFunctionAnalysis"; }
Chandler Carruth0b576b32015-01-06 02:50:06 +0000104};
105
Justin Bognereecc3c82016-02-25 07:23:08 +0000106/// \brief No-op loop pass which does nothing.
107struct NoOpLoopPass {
108 PreservedAnalyses run(Loop &L) { return PreservedAnalyses::all(); }
109 static StringRef name() { return "NoOpLoopPass"; }
110};
111
112/// \brief No-op loop analysis.
Chandler Carruth3a634352016-02-26 11:44:45 +0000113struct NoOpLoopAnalysis : AnalysisBase<NoOpLoopAnalysis> {
Justin Bognereecc3c82016-02-25 07:23:08 +0000114 struct Result {};
115 Result run(Loop &) { return Result(); }
116 static StringRef name() { return "NoOpLoopAnalysis"; }
Justin Bognereecc3c82016-02-25 07:23:08 +0000117};
118
Chandler Carruth66445382014-01-11 08:16:35 +0000119} // End anonymous namespace.
120
Chandler Carruth1ff77242015-03-07 09:02:36 +0000121void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000122#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000123 MAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000124#include "PassRegistry.def"
125}
126
Chandler Carruth1ff77242015-03-07 09:02:36 +0000127void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000128#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000129 CGAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000130#include "PassRegistry.def"
131}
132
Chandler Carruth1ff77242015-03-07 09:02:36 +0000133void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
Chandler Carruthb70f6732015-01-06 02:21:37 +0000134#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruthedf59962016-02-18 09:45:17 +0000135 FAM.registerPass([&] { return CREATE_PASS; });
Chandler Carruthb70f6732015-01-06 02:21:37 +0000136#include "PassRegistry.def"
137}
138
Justin Bognereecc3c82016-02-25 07:23:08 +0000139void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
140#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
141 LAM.registerPass([&] { return CREATE_PASS; });
142#include "PassRegistry.def"
143}
144
Chandler Carruth8b5a74192016-02-28 22:16:03 +0000145void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM,
146 OptimizationLevel Level,
147 bool DebugLogging) {
148 // FIXME: Finish fleshing this out to match the legacy pipelines.
149 FunctionPassManager EarlyFPM(DebugLogging);
150 EarlyFPM.addPass(SimplifyCFGPass());
151 EarlyFPM.addPass(SROA());
152 EarlyFPM.addPass(EarlyCSEPass());
153 EarlyFPM.addPass(LowerExpectIntrinsicPass());
154
155 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
156}
157
158void PassBuilder::addLTOPreLinkDefaultPipeline(ModulePassManager &MPM,
159 OptimizationLevel Level,
160 bool DebugLogging) {
161 // FIXME: We should use a customized pre-link pipeline!
162 addPerModuleDefaultPipeline(MPM, Level, DebugLogging);
163}
164
165void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM,
166 OptimizationLevel Level,
167 bool DebugLogging) {
168 // FIXME: Finish fleshing this out to match the legacy LTO pipelines.
169 FunctionPassManager LateFPM(DebugLogging);
170 LateFPM.addPass(InstCombinePass());
171 LateFPM.addPass(SimplifyCFGPass());
172
173 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
174}
175
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000176#ifndef NDEBUG
Chandler Carruth66445382014-01-11 08:16:35 +0000177static bool isModulePassName(StringRef Name) {
Chandler Carruth8b5a74192016-02-28 22:16:03 +0000178 // Manually handle aliases for pre-configured pipeline fragments.
179 if (Name.startswith("default") || Name.startswith("lto"))
180 return DefaultAliasRegex.match(Name);
181
Chandler Carruth58944182014-04-21 08:08:50 +0000182#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000183#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000184 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000185 return true;
186#include "PassRegistry.def"
187
Chandler Carruth66445382014-01-11 08:16:35 +0000188 return false;
189}
Chandler Carruth9d2e58f2015-01-06 09:10:47 +0000190#endif
Chandler Carruth66445382014-01-11 08:16:35 +0000191
Chandler Carruth572e3402014-04-21 11:12:00 +0000192static bool isCGSCCPassName(StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000193#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000194#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000195 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000196 return true;
197#include "PassRegistry.def"
198
Chandler Carruth572e3402014-04-21 11:12:00 +0000199 return false;
200}
201
Chandler Carruthd8330982014-01-12 09:34:22 +0000202static bool isFunctionPassName(StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000203#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
Chandler Carruth628503e2015-01-06 02:10:51 +0000204#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000205 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
Chandler Carruth628503e2015-01-06 02:10:51 +0000206 return true;
207#include "PassRegistry.def"
208
Chandler Carruthd8330982014-01-12 09:34:22 +0000209 return false;
210}
211
Justin Bognereecc3c82016-02-25 07:23:08 +0000212static bool isLoopPassName(StringRef Name) {
213#define LOOP_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
214#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
215 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
216 return true;
217#include "PassRegistry.def"
218
219 return false;
220}
221
Chandler Carruth8b5a74192016-02-28 22:16:03 +0000222bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name,
223 bool DebugLogging) {
224 // Manually handle aliases for pre-configured pipeline fragments.
225 if (Name.startswith("default") || Name.startswith("lto")) {
226 SmallVector<StringRef, 3> Matches;
227 if (!DefaultAliasRegex.match(Name, &Matches))
228 return false;
229 assert(Matches.size() == 3 && "Must capture two matched strings!");
230
231 auto L = StringSwitch<OptimizationLevel>(Matches[2])
232 .Case("O0", O0)
233 .Case("O1", O1)
234 .Case("O2", O2)
235 .Case("O3", O3)
236 .Case("Os", Os)
237 .Case("Oz", Oz);
238
239 if (Matches[1] == "default") {
240 addPerModuleDefaultPipeline(MPM, L, DebugLogging);
241 } else if (Matches[1] == "lto-pre-link") {
242 addLTOPreLinkDefaultPipeline(MPM, L, DebugLogging);
243 } else {
244 assert(Matches[1] == "lto" && "Not one of the matched options!");
245 addLTODefaultPipeline(MPM, L, DebugLogging);
246 }
247 return true;
248 }
249
Chandler Carruth58944182014-04-21 08:08:50 +0000250#define MODULE_PASS(NAME, CREATE_PASS) \
251 if (Name == NAME) { \
252 MPM.addPass(CREATE_PASS); \
253 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000254 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000255#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
256 if (Name == "require<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000257 MPM.addPass(RequireAnalysisPass< \
258 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000259 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000260 } \
261 if (Name == "invalidate<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000262 MPM.addPass(InvalidateAnalysisPass< \
263 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000264 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000265 }
266#include "PassRegistry.def"
267
Chandler Carruth66445382014-01-11 08:16:35 +0000268 return false;
269}
270
Chandler Carruth1ff77242015-03-07 09:02:36 +0000271bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000272#define CGSCC_PASS(NAME, CREATE_PASS) \
273 if (Name == NAME) { \
274 CGPM.addPass(CREATE_PASS); \
275 return true; \
276 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000277#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
278 if (Name == "require<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000279 CGPM.addPass(RequireAnalysisPass< \
280 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000281 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000282 } \
283 if (Name == "invalidate<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000284 CGPM.addPass(InvalidateAnalysisPass< \
285 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000286 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000287 }
288#include "PassRegistry.def"
289
Chandler Carruth572e3402014-04-21 11:12:00 +0000290 return false;
291}
292
Chandler Carruth1ff77242015-03-07 09:02:36 +0000293bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
294 StringRef Name) {
Chandler Carruth58944182014-04-21 08:08:50 +0000295#define FUNCTION_PASS(NAME, CREATE_PASS) \
296 if (Name == NAME) { \
297 FPM.addPass(CREATE_PASS); \
298 return true; \
Chandler Carruth52eef882014-01-12 12:15:39 +0000299 }
Chandler Carruth628503e2015-01-06 02:10:51 +0000300#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
301 if (Name == "require<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000302 FPM.addPass(RequireAnalysisPass< \
303 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth628503e2015-01-06 02:10:51 +0000304 return true; \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000305 } \
306 if (Name == "invalidate<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000307 FPM.addPass(InvalidateAnalysisPass< \
308 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Chandler Carruth3472ffb2015-01-06 04:49:44 +0000309 return true; \
Chandler Carruth628503e2015-01-06 02:10:51 +0000310 }
311#include "PassRegistry.def"
312
Chandler Carruthd8330982014-01-12 09:34:22 +0000313 return false;
314}
315
Justin Bognereecc3c82016-02-25 07:23:08 +0000316bool PassBuilder::parseLoopPassName(LoopPassManager &FPM,
317 StringRef Name) {
318#define LOOP_PASS(NAME, CREATE_PASS) \
319 if (Name == NAME) { \
320 FPM.addPass(CREATE_PASS); \
321 return true; \
322 }
323#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
324 if (Name == "require<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000325 FPM.addPass(RequireAnalysisPass< \
326 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Justin Bognereecc3c82016-02-25 07:23:08 +0000327 return true; \
328 } \
329 if (Name == "invalidate<" NAME ">") { \
Chandler Carruth470734b2016-02-26 12:30:18 +0000330 FPM.addPass(InvalidateAnalysisPass< \
331 std::remove_reference<decltype(CREATE_PASS)>::type>()); \
Justin Bognereecc3c82016-02-25 07:23:08 +0000332 return true; \
333 }
334#include "PassRegistry.def"
335
336 return false;
337}
338
Chandler Carruthedf59962016-02-18 09:45:17 +0000339bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
340#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
341 if (Name == NAME) { \
Chandler Carruth58dde8c2016-02-26 12:17:54 +0000342 AA.registerFunctionAnalysis< \
343 std::remove_reference<decltype(CREATE_PASS)>::type>(); \
Chandler Carruthedf59962016-02-18 09:45:17 +0000344 return true; \
345 }
346#include "PassRegistry.def"
347
348 return false;
349}
350
Justin Bognereecc3c82016-02-25 07:23:08 +0000351bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
352 StringRef &PipelineText,
353 bool VerifyEachPass,
354 bool DebugLogging) {
355 for (;;) {
356 // Parse nested pass managers by recursing.
357 if (PipelineText.startswith("loop(")) {
358 LoopPassManager NestedLPM(DebugLogging);
359
360 // Parse the inner pipeline inte the nested manager.
361 PipelineText = PipelineText.substr(strlen("loop("));
362 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
363 DebugLogging) ||
364 PipelineText.empty())
365 return false;
366 assert(PipelineText[0] == ')');
367 PipelineText = PipelineText.substr(1);
368
369 // Add the nested pass manager with the appropriate adaptor.
370 LPM.addPass(std::move(NestedLPM));
371 } else {
372 // Otherwise try to parse a pass name.
373 size_t End = PipelineText.find_first_of(",)");
374 if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
375 return false;
376 // TODO: Ideally, we would run a LoopVerifierPass() here in the
377 // VerifyEachPass case, but we don't have such a verifier yet.
378
379 PipelineText = PipelineText.substr(End);
380 }
381
382 if (PipelineText.empty() || PipelineText[0] == ')')
383 return true;
384
385 assert(PipelineText[0] == ',');
386 PipelineText = PipelineText.substr(1);
387 }
388}
389
Chandler Carruth1ff77242015-03-07 09:02:36 +0000390bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
391 StringRef &PipelineText,
392 bool VerifyEachPass,
393 bool DebugLogging) {
Chandler Carruthd8330982014-01-12 09:34:22 +0000394 for (;;) {
395 // Parse nested pass managers by recursing.
396 if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000397 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000398
399 // Parse the inner pipeline inte the nested manager.
400 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000401 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
402 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000403 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000404 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000405 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000406 PipelineText = PipelineText.substr(1);
407
408 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000409 FPM.addPass(std::move(NestedFPM));
Justin Bognereecc3c82016-02-25 07:23:08 +0000410 } else if (PipelineText.startswith("loop(")) {
411 LoopPassManager NestedLPM(DebugLogging);
412
413 // Parse the inner pipeline inte the nested manager.
414 PipelineText = PipelineText.substr(strlen("loop("));
415 if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
416 DebugLogging) ||
417 PipelineText.empty())
418 return false;
419 assert(PipelineText[0] == ')');
420 PipelineText = PipelineText.substr(1);
421
422 // Add the nested pass manager with the appropriate adaptor.
423 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000424 } else {
425 // Otherwise try to parse a pass name.
426 size_t End = PipelineText.find_first_of(",)");
427 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
428 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000429 if (VerifyEachPass)
430 FPM.addPass(VerifierPass());
Chandler Carruthd8330982014-01-12 09:34:22 +0000431
432 PipelineText = PipelineText.substr(End);
433 }
434
435 if (PipelineText.empty() || PipelineText[0] == ')')
436 return true;
437
438 assert(PipelineText[0] == ',');
439 PipelineText = PipelineText.substr(1);
440 }
441}
442
Chandler Carruth1ff77242015-03-07 09:02:36 +0000443bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
444 StringRef &PipelineText,
445 bool VerifyEachPass,
446 bool DebugLogging) {
Chandler Carruth572e3402014-04-21 11:12:00 +0000447 for (;;) {
448 // Parse nested pass managers by recursing.
449 if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000450 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000451
452 // Parse the inner pipeline into the nested manager.
453 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000454 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
455 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000456 PipelineText.empty())
457 return false;
458 assert(PipelineText[0] == ')');
459 PipelineText = PipelineText.substr(1);
460
461 // Add the nested pass manager with the appropriate adaptor.
462 CGPM.addPass(std::move(NestedCGPM));
463 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000464 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000465
466 // Parse the inner pipeline inte the nested manager.
467 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000468 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
469 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000470 PipelineText.empty())
471 return false;
472 assert(PipelineText[0] == ')');
473 PipelineText = PipelineText.substr(1);
474
475 // Add the nested pass manager with the appropriate adaptor.
476 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
477 } else {
478 // Otherwise try to parse a pass name.
479 size_t End = PipelineText.find_first_of(",)");
480 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
481 return false;
482 // FIXME: No verifier support for CGSCC passes!
483
484 PipelineText = PipelineText.substr(End);
485 }
486
487 if (PipelineText.empty() || PipelineText[0] == ')')
488 return true;
489
490 assert(PipelineText[0] == ',');
491 PipelineText = PipelineText.substr(1);
492 }
493}
494
Chandler Carruth1ff77242015-03-07 09:02:36 +0000495bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
496 StringRef &PipelineText,
497 bool VerifyEachPass,
498 bool DebugLogging) {
Chandler Carruth66445382014-01-11 08:16:35 +0000499 for (;;) {
500 // Parse nested pass managers by recursing.
501 if (PipelineText.startswith("module(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000502 ModulePassManager NestedMPM(DebugLogging);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000503
504 // Parse the inner pipeline into the nested manager.
Chandler Carruth66445382014-01-11 08:16:35 +0000505 PipelineText = PipelineText.substr(strlen("module("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000506 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
507 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000508 PipelineText.empty())
Chandler Carruth66445382014-01-11 08:16:35 +0000509 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000510 assert(PipelineText[0] == ')');
Chandler Carruth66445382014-01-11 08:16:35 +0000511 PipelineText = PipelineText.substr(1);
Chandler Carruth258dbb32014-01-11 12:06:47 +0000512
513 // Now add the nested manager as a module pass.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000514 MPM.addPass(std::move(NestedMPM));
Chandler Carruth572e3402014-04-21 11:12:00 +0000515 } else if (PipelineText.startswith("cgscc(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000516 CGSCCPassManager NestedCGPM(DebugLogging);
Chandler Carruth572e3402014-04-21 11:12:00 +0000517
518 // Parse the inner pipeline inte the nested manager.
519 PipelineText = PipelineText.substr(strlen("cgscc("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000520 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
521 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000522 PipelineText.empty())
523 return false;
524 assert(PipelineText[0] == ')');
525 PipelineText = PipelineText.substr(1);
526
527 // Add the nested pass manager with the appropriate adaptor.
528 MPM.addPass(
529 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000530 } else if (PipelineText.startswith("function(")) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000531 FunctionPassManager NestedFPM(DebugLogging);
Chandler Carruthd8330982014-01-12 09:34:22 +0000532
533 // Parse the inner pipeline inte the nested manager.
534 PipelineText = PipelineText.substr(strlen("function("));
Chandler Carruth14a759e2015-01-13 22:42:38 +0000535 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
536 DebugLogging) ||
Chandler Carruth6546cb62014-01-12 10:02:02 +0000537 PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000538 return false;
Chandler Carruth6546cb62014-01-12 10:02:02 +0000539 assert(PipelineText[0] == ')');
Chandler Carruthd8330982014-01-12 09:34:22 +0000540 PipelineText = PipelineText.substr(1);
541
542 // Add the nested pass manager with the appropriate adaptor.
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000543 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
Chandler Carruth66445382014-01-11 08:16:35 +0000544 } else {
545 // Otherwise try to parse a pass name.
546 size_t End = PipelineText.find_first_of(",)");
Chandler Carruth8b5a74192016-02-28 22:16:03 +0000547 if (!parseModulePassName(MPM, PipelineText.substr(0, End), DebugLogging))
Chandler Carruth66445382014-01-11 08:16:35 +0000548 return false;
Chandler Carruth4d356312014-01-20 11:34:08 +0000549 if (VerifyEachPass)
550 MPM.addPass(VerifierPass());
Chandler Carruth66445382014-01-11 08:16:35 +0000551
552 PipelineText = PipelineText.substr(End);
553 }
554
555 if (PipelineText.empty() || PipelineText[0] == ')')
556 return true;
557
558 assert(PipelineText[0] == ',');
559 PipelineText = PipelineText.substr(1);
560 }
561}
562
563// Primary pass pipeline description parsing routine.
564// FIXME: Should this routine accept a TargetMachine or require the caller to
565// pre-populate the analysis managers with target-specific stuff?
Chandler Carruth1ff77242015-03-07 09:02:36 +0000566bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
567 StringRef PipelineText, bool VerifyEachPass,
568 bool DebugLogging) {
Chandler Carruthea368f12015-01-06 08:37:58 +0000569 // By default, try to parse the pipeline as-if it were within an implicit
570 // 'module(...)' pass pipeline. If this will parse at all, it needs to
571 // consume the entire string.
Chandler Carruth14a759e2015-01-13 22:42:38 +0000572 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
Chandler Carruthea368f12015-01-06 08:37:58 +0000573 return PipelineText.empty();
Chandler Carruth66445382014-01-11 08:16:35 +0000574
Chandler Carruthea368f12015-01-06 08:37:58 +0000575 // This isn't parsable as a module pipeline, look for the end of a pass name
576 // and directly drop down to that layer.
Chandler Carruth6546cb62014-01-12 10:02:02 +0000577 StringRef FirstName =
578 PipelineText.substr(0, PipelineText.find_first_of(",)"));
Chandler Carruthea368f12015-01-06 08:37:58 +0000579 assert(!isModulePassName(FirstName) &&
580 "Already handled all module pipeline options.");
Chandler Carruth66445382014-01-11 08:16:35 +0000581
Chandler Carruthea368f12015-01-06 08:37:58 +0000582 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
583 // pipeline.
Justin Bognereecc3c82016-02-25 07:23:08 +0000584 if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000585 CGSCCPassManager CGPM(DebugLogging);
586 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
587 DebugLogging) ||
Chandler Carruth572e3402014-04-21 11:12:00 +0000588 !PipelineText.empty())
589 return false;
590 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
591 return true;
592 }
593
Chandler Carruthea368f12015-01-06 08:37:58 +0000594 // Similarly, if this looks like a Function pass, parse the whole thing as
595 // a Function pipelien.
Justin Bognereecc3c82016-02-25 07:23:08 +0000596 if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
Chandler Carruth14a759e2015-01-13 22:42:38 +0000597 FunctionPassManager FPM(DebugLogging);
598 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
599 DebugLogging) ||
Chandler Carruth4d356312014-01-20 11:34:08 +0000600 !PipelineText.empty())
Chandler Carruthd8330982014-01-12 09:34:22 +0000601 return false;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000602 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthd8330982014-01-12 09:34:22 +0000603 return true;
604 }
Chandler Carruth66445382014-01-11 08:16:35 +0000605
Justin Bognereecc3c82016-02-25 07:23:08 +0000606 // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
607 if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
608 LoopPassManager LPM(DebugLogging);
609 if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
610 DebugLogging) ||
611 !PipelineText.empty())
612 return false;
613 FunctionPassManager FPM(DebugLogging);
614 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
615 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
616 return true;
617 }
618
619
Chandler Carruth66445382014-01-11 08:16:35 +0000620 return false;
621}
Chandler Carruthedf59962016-02-18 09:45:17 +0000622
623bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
624 while (!PipelineText.empty()) {
625 StringRef Name;
626 std::tie(Name, PipelineText) = PipelineText.split(',');
627 if (!parseAAPassName(AA, Name))
628 return false;
629 }
630
631 return true;
632}