1 //===- Parsing, selection, and construction of pass pipelines -------------===//
2 //
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 ///
11 /// 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.
15 ///
16 //===----------------------------------------------------------------------===//
17 
18 #include "llvm/Passes/PassBuilder.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/Analysis/AliasAnalysis.h"
21 #include "llvm/Analysis/AliasAnalysisEvaluator.h"
22 #include "llvm/Analysis/AssumptionCache.h"
23 #include "llvm/Analysis/BasicAliasAnalysis.h"
24 #include "llvm/Analysis/BlockFrequencyInfo.h"
25 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
26 #include "llvm/Analysis/BranchProbabilityInfo.h"
27 #include "llvm/Analysis/CFLAliasAnalysis.h"
28 #include "llvm/Analysis/CGSCCPassManager.h"
29 #include "llvm/Analysis/CallGraph.h"
30 #include "llvm/Analysis/DemandedBits.h"
31 #include "llvm/Analysis/DependenceAnalysis.h"
32 #include "llvm/Analysis/DominanceFrontier.h"
33 #include "llvm/Analysis/GlobalsModRef.h"
34 #include "llvm/Analysis/LazyCallGraph.h"
35 #include "llvm/Analysis/LazyValueInfo.h"
36 #include "llvm/Analysis/LoopInfo.h"
37 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
38 #include "llvm/Analysis/PostDominators.h"
39 #include "llvm/Analysis/ProfileSummaryInfo.h"
40 #include "llvm/Analysis/RegionInfo.h"
41 #include "llvm/Analysis/ScalarEvolution.h"
42 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
43 #include "llvm/Analysis/ScopedNoAliasAA.h"
44 #include "llvm/Analysis/TargetLibraryInfo.h"
45 #include "llvm/Analysis/TargetTransformInfo.h"
46 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
47 #include "llvm/CodeGen/PreISelIntrinsicLowering.h"
48 #include "llvm/IR/Dominators.h"
49 #include "llvm/IR/IRPrintingPasses.h"
50 #include "llvm/IR/PassManager.h"
51 #include "llvm/IR/Verifier.h"
52 #include "llvm/Support/Debug.h"
53 #include "llvm/Support/Regex.h"
54 #include "llvm/Target/TargetMachine.h"
55 #include "llvm/Transforms/GCOVProfiler.h"
56 #include "llvm/Transforms/IPO/ConstantMerge.h"
57 #include "llvm/Transforms/IPO/DeadArgumentElimination.h"
58 #include "llvm/Transforms/IPO/ElimAvailExtern.h"
59 #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
60 #include "llvm/Transforms/IPO/FunctionAttrs.h"
61 #include "llvm/Transforms/IPO/GlobalDCE.h"
62 #include "llvm/Transforms/IPO/GlobalOpt.h"
63 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
64 #include "llvm/Transforms/IPO/Internalize.h"
65 #include "llvm/Transforms/IPO/PartialInlining.h"
66 #include "llvm/Transforms/IPO/SCCP.h"
67 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
68 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
69 #include "llvm/Transforms/InstCombine/InstCombine.h"
70 #include "llvm/Transforms/InstrProfiling.h"
71 #include "llvm/Transforms/PGOInstrumentation.h"
72 #include "llvm/Transforms/SampleProfile.h"
73 #include "llvm/Transforms/Scalar/ADCE.h"
74 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
75 #include "llvm/Transforms/Scalar/BDCE.h"
76 #include "llvm/Transforms/Scalar/DCE.h"
77 #include "llvm/Transforms/Scalar/DeadStoreElimination.h"
78 #include "llvm/Transforms/Scalar/EarlyCSE.h"
79 #include "llvm/Transforms/Scalar/Float2Int.h"
80 #include "llvm/Transforms/Scalar/GVN.h"
81 #include "llvm/Transforms/Scalar/GuardWidening.h"
82 #include "llvm/Transforms/Scalar/IndVarSimplify.h"
83 #include "llvm/Transforms/Scalar/JumpThreading.h"
84 #include "llvm/Transforms/Scalar/LoopRotation.h"
85 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
86 #include "llvm/Transforms/Scalar/LowerAtomic.h"
87 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
88 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
89 #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
90 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
91 #include "llvm/Transforms/Scalar/Reassociate.h"
92 #include "llvm/Transforms/Scalar/SCCP.h"
93 #include "llvm/Transforms/Scalar/SLPVectorizer.h"
94 #include "llvm/Transforms/Scalar/SROA.h"
95 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
96 #include "llvm/Transforms/Scalar/Sink.h"
97 #include "llvm/Transforms/Utils/AddDiscriminators.h"
98 #include "llvm/Transforms/Utils/LCSSA.h"
99 #include "llvm/Transforms/Utils/Mem2Reg.h"
100 #include "llvm/Transforms/Utils/MemorySSA.h"
101 
102 #include <type_traits>
103 
104 using namespace llvm;
105 
106 static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$");
107 
108 namespace {
109 
110 /// \brief No-op module pass which does nothing.
111 struct NoOpModulePass {
112   PreservedAnalyses run(Module &M, AnalysisManager<Module> &) {
113     return PreservedAnalyses::all();
114   }
115   static StringRef name() { return "NoOpModulePass"; }
116 };
117 
118 /// \brief No-op module analysis.
119 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
120   friend AnalysisInfoMixin<NoOpModuleAnalysis>;
121   static char PassID;
122 
123 public:
124   struct Result {};
125   Result run(Module &, AnalysisManager<Module> &) { return Result(); }
126   static StringRef name() { return "NoOpModuleAnalysis"; }
127 };
128 
129 /// \brief No-op CGSCC pass which does nothing.
130 struct NoOpCGSCCPass {
131   PreservedAnalyses run(LazyCallGraph::SCC &C,
132                         AnalysisManager<LazyCallGraph::SCC> &) {
133     return PreservedAnalyses::all();
134   }
135   static StringRef name() { return "NoOpCGSCCPass"; }
136 };
137 
138 /// \brief No-op CGSCC analysis.
139 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
140   friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
141   static char PassID;
142 
143 public:
144   struct Result {};
145   Result run(LazyCallGraph::SCC &, AnalysisManager<LazyCallGraph::SCC> &) {
146     return Result();
147   }
148   static StringRef name() { return "NoOpCGSCCAnalysis"; }
149 };
150 
151 /// \brief No-op function pass which does nothing.
152 struct NoOpFunctionPass {
153   PreservedAnalyses run(Function &F, AnalysisManager<Function> &) {
154     return PreservedAnalyses::all();
155   }
156   static StringRef name() { return "NoOpFunctionPass"; }
157 };
158 
159 /// \brief No-op function analysis.
160 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
161   friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
162   static char PassID;
163 
164 public:
165   struct Result {};
166   Result run(Function &, AnalysisManager<Function> &) { return Result(); }
167   static StringRef name() { return "NoOpFunctionAnalysis"; }
168 };
169 
170 /// \brief No-op loop pass which does nothing.
171 struct NoOpLoopPass {
172   PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &) {
173     return PreservedAnalyses::all();
174   }
175   static StringRef name() { return "NoOpLoopPass"; }
176 };
177 
178 /// \brief No-op loop analysis.
179 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
180   friend AnalysisInfoMixin<NoOpLoopAnalysis>;
181   static char PassID;
182 
183 public:
184   struct Result {};
185   Result run(Loop &, AnalysisManager<Loop> &) { return Result(); }
186   static StringRef name() { return "NoOpLoopAnalysis"; }
187 };
188 
189 char NoOpModuleAnalysis::PassID;
190 char NoOpCGSCCAnalysis::PassID;
191 char NoOpFunctionAnalysis::PassID;
192 char NoOpLoopAnalysis::PassID;
193 
194 } // End anonymous namespace.
195 
196 void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
197 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
198   MAM.registerPass([&] { return CREATE_PASS; });
199 #include "PassRegistry.def"
200 }
201 
202 void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
203 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
204   CGAM.registerPass([&] { return CREATE_PASS; });
205 #include "PassRegistry.def"
206 }
207 
208 void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
209 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
210   FAM.registerPass([&] { return CREATE_PASS; });
211 #include "PassRegistry.def"
212 }
213 
214 void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
215 #define LOOP_ANALYSIS(NAME, CREATE_PASS)                                       \
216   LAM.registerPass([&] { return CREATE_PASS; });
217 #include "PassRegistry.def"
218 }
219 
220 void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM,
221                                               OptimizationLevel Level,
222                                               bool DebugLogging) {
223   // FIXME: Finish fleshing this out to match the legacy pipelines.
224   FunctionPassManager EarlyFPM(DebugLogging);
225   EarlyFPM.addPass(SimplifyCFGPass());
226   EarlyFPM.addPass(SROA());
227   EarlyFPM.addPass(EarlyCSEPass());
228   EarlyFPM.addPass(LowerExpectIntrinsicPass());
229 
230   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
231 }
232 
233 void PassBuilder::addLTOPreLinkDefaultPipeline(ModulePassManager &MPM,
234                                                OptimizationLevel Level,
235                                                bool DebugLogging) {
236   // FIXME: We should use a customized pre-link pipeline!
237   addPerModuleDefaultPipeline(MPM, Level, DebugLogging);
238 }
239 
240 void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM,
241                                         OptimizationLevel Level,
242                                         bool DebugLogging) {
243   // FIXME: Finish fleshing this out to match the legacy LTO pipelines.
244   FunctionPassManager LateFPM(DebugLogging);
245   LateFPM.addPass(InstCombinePass());
246   LateFPM.addPass(SimplifyCFGPass());
247 
248   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
249 }
250 
251 #ifndef NDEBUG
252 static bool isModulePassName(StringRef Name) {
253   // Manually handle aliases for pre-configured pipeline fragments.
254   if (Name.startswith("default") || Name.startswith("lto"))
255     return DefaultAliasRegex.match(Name);
256 
257 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
258   if (Name == NAME)                                                            \
259     return true;
260 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
261   if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
262     return true;
263 #include "PassRegistry.def"
264 
265   return false;
266 }
267 #endif
268 
269 static bool isCGSCCPassName(StringRef Name) {
270 #define CGSCC_PASS(NAME, CREATE_PASS)                                          \
271   if (Name == NAME)                                                            \
272     return true;
273 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
274   if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
275     return true;
276 #include "PassRegistry.def"
277 
278   return false;
279 }
280 
281 static bool isFunctionPassName(StringRef Name) {
282 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
283   if (Name == NAME)                                                            \
284     return true;
285 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
286   if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
287     return true;
288 #include "PassRegistry.def"
289 
290   return false;
291 }
292 
293 static bool isLoopPassName(StringRef Name) {
294 #define LOOP_PASS(NAME, CREATE_PASS)                                           \
295   if (Name == NAME)                                                            \
296     return true;
297 #define LOOP_ANALYSIS(NAME, CREATE_PASS)                                       \
298   if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
299     return true;
300 #include "PassRegistry.def"
301 
302   return false;
303 }
304 
305 bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name,
306                                       bool DebugLogging) {
307   // Manually handle aliases for pre-configured pipeline fragments.
308   if (Name.startswith("default") || Name.startswith("lto")) {
309     SmallVector<StringRef, 3> Matches;
310     if (!DefaultAliasRegex.match(Name, &Matches))
311       return false;
312     assert(Matches.size() == 3 && "Must capture two matched strings!");
313 
314     auto L = StringSwitch<OptimizationLevel>(Matches[2])
315                  .Case("O0", O0)
316                  .Case("O1", O1)
317                  .Case("O2", O2)
318                  .Case("O3", O3)
319                  .Case("Os", Os)
320                  .Case("Oz", Oz);
321 
322     if (Matches[1] == "default") {
323       addPerModuleDefaultPipeline(MPM, L, DebugLogging);
324     } else if (Matches[1] == "lto-pre-link") {
325       addLTOPreLinkDefaultPipeline(MPM, L, DebugLogging);
326     } else {
327       assert(Matches[1] == "lto" && "Not one of the matched options!");
328       addLTODefaultPipeline(MPM, L, DebugLogging);
329     }
330     return true;
331   }
332 
333 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
334   if (Name == NAME) {                                                          \
335     MPM.addPass(CREATE_PASS);                                                  \
336     return true;                                                               \
337   }
338 #define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
339   if (Name == "require<" NAME ">") {                                           \
340     MPM.addPass(RequireAnalysisPass<                                           \
341                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
342     return true;                                                               \
343   }                                                                            \
344   if (Name == "invalidate<" NAME ">") {                                        \
345     MPM.addPass(InvalidateAnalysisPass<                                        \
346                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
347     return true;                                                               \
348   }
349 #include "PassRegistry.def"
350 
351   return false;
352 }
353 
354 bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
355 #define CGSCC_PASS(NAME, CREATE_PASS)                                          \
356   if (Name == NAME) {                                                          \
357     CGPM.addPass(CREATE_PASS);                                                 \
358     return true;                                                               \
359   }
360 #define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
361   if (Name == "require<" NAME ">") {                                           \
362     CGPM.addPass(RequireAnalysisPass<                                          \
363                  std::remove_reference<decltype(CREATE_PASS)>::type>());       \
364     return true;                                                               \
365   }                                                                            \
366   if (Name == "invalidate<" NAME ">") {                                        \
367     CGPM.addPass(InvalidateAnalysisPass<                                       \
368                  std::remove_reference<decltype(CREATE_PASS)>::type>());       \
369     return true;                                                               \
370   }
371 #include "PassRegistry.def"
372 
373   return false;
374 }
375 
376 bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
377                                         StringRef Name) {
378 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
379   if (Name == NAME) {                                                          \
380     FPM.addPass(CREATE_PASS);                                                  \
381     return true;                                                               \
382   }
383 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
384   if (Name == "require<" NAME ">") {                                           \
385     FPM.addPass(RequireAnalysisPass<                                           \
386                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
387     return true;                                                               \
388   }                                                                            \
389   if (Name == "invalidate<" NAME ">") {                                        \
390     FPM.addPass(InvalidateAnalysisPass<                                        \
391                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
392     return true;                                                               \
393   }
394 #include "PassRegistry.def"
395 
396   return false;
397 }
398 
399 bool PassBuilder::parseLoopPassName(LoopPassManager &FPM, StringRef Name) {
400 #define LOOP_PASS(NAME, CREATE_PASS)                                           \
401   if (Name == NAME) {                                                          \
402     FPM.addPass(CREATE_PASS);                                                  \
403     return true;                                                               \
404   }
405 #define LOOP_ANALYSIS(NAME, CREATE_PASS)                                       \
406   if (Name == "require<" NAME ">") {                                           \
407     FPM.addPass(RequireAnalysisPass<                                           \
408                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
409     return true;                                                               \
410   }                                                                            \
411   if (Name == "invalidate<" NAME ">") {                                        \
412     FPM.addPass(InvalidateAnalysisPass<                                        \
413                 std::remove_reference<decltype(CREATE_PASS)>::type>());        \
414     return true;                                                               \
415   }
416 #include "PassRegistry.def"
417 
418   return false;
419 }
420 
421 bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
422 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS)                               \
423   if (Name == NAME) {                                                          \
424     AA.registerModuleAnalysis<                                                 \
425         std::remove_reference<decltype(CREATE_PASS)>::type>();                 \
426     return true;                                                               \
427   }
428 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS)                             \
429   if (Name == NAME) {                                                          \
430     AA.registerFunctionAnalysis<                                               \
431         std::remove_reference<decltype(CREATE_PASS)>::type>();                 \
432     return true;                                                               \
433   }
434 #include "PassRegistry.def"
435 
436   return false;
437 }
438 
439 bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
440                                         StringRef &PipelineText,
441                                         bool VerifyEachPass,
442                                         bool DebugLogging) {
443   for (;;) {
444     // Parse nested pass managers by recursing.
445     if (PipelineText.startswith("loop(")) {
446       LoopPassManager NestedLPM(DebugLogging);
447 
448       // Parse the inner pipeline inte the nested manager.
449       PipelineText = PipelineText.substr(strlen("loop("));
450       if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
451                                  DebugLogging) ||
452           PipelineText.empty())
453         return false;
454       assert(PipelineText[0] == ')');
455       PipelineText = PipelineText.substr(1);
456 
457       // Add the nested pass manager with the appropriate adaptor.
458       LPM.addPass(std::move(NestedLPM));
459     } else {
460       // Otherwise try to parse a pass name.
461       size_t End = PipelineText.find_first_of(",)");
462       if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
463         return false;
464       // TODO: Ideally, we would run a LoopVerifierPass() here in the
465       // VerifyEachPass case, but we don't have such a verifier yet.
466 
467       PipelineText = PipelineText.substr(End);
468     }
469 
470     if (PipelineText.empty() || PipelineText[0] == ')')
471       return true;
472 
473     assert(PipelineText[0] == ',');
474     PipelineText = PipelineText.substr(1);
475   }
476 }
477 
478 bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
479                                             StringRef &PipelineText,
480                                             bool VerifyEachPass,
481                                             bool DebugLogging) {
482   for (;;) {
483     // Parse nested pass managers by recursing.
484     if (PipelineText.startswith("function(")) {
485       FunctionPassManager NestedFPM(DebugLogging);
486 
487       // Parse the inner pipeline inte the nested manager.
488       PipelineText = PipelineText.substr(strlen("function("));
489       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
490                                      DebugLogging) ||
491           PipelineText.empty())
492         return false;
493       assert(PipelineText[0] == ')');
494       PipelineText = PipelineText.substr(1);
495 
496       // Add the nested pass manager with the appropriate adaptor.
497       FPM.addPass(std::move(NestedFPM));
498     } else if (PipelineText.startswith("loop(")) {
499       LoopPassManager NestedLPM(DebugLogging);
500 
501       // Parse the inner pipeline inte the nested manager.
502       PipelineText = PipelineText.substr(strlen("loop("));
503       if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
504                                  DebugLogging) ||
505           PipelineText.empty())
506         return false;
507       assert(PipelineText[0] == ')');
508       PipelineText = PipelineText.substr(1);
509 
510       // Add the nested pass manager with the appropriate adaptor.
511       FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
512     } else {
513       // Otherwise try to parse a pass name.
514       size_t End = PipelineText.find_first_of(",)");
515       if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
516         return false;
517       if (VerifyEachPass)
518         FPM.addPass(VerifierPass());
519 
520       PipelineText = PipelineText.substr(End);
521     }
522 
523     if (PipelineText.empty() || PipelineText[0] == ')')
524       return true;
525 
526     assert(PipelineText[0] == ',');
527     PipelineText = PipelineText.substr(1);
528   }
529 }
530 
531 bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
532                                          StringRef &PipelineText,
533                                          bool VerifyEachPass,
534                                          bool DebugLogging) {
535   for (;;) {
536     // Parse nested pass managers by recursing.
537     if (PipelineText.startswith("cgscc(")) {
538       CGSCCPassManager NestedCGPM(DebugLogging);
539 
540       // Parse the inner pipeline into the nested manager.
541       PipelineText = PipelineText.substr(strlen("cgscc("));
542       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
543                                   DebugLogging) ||
544           PipelineText.empty())
545         return false;
546       assert(PipelineText[0] == ')');
547       PipelineText = PipelineText.substr(1);
548 
549       // Add the nested pass manager with the appropriate adaptor.
550       CGPM.addPass(std::move(NestedCGPM));
551     } else if (PipelineText.startswith("function(")) {
552       FunctionPassManager NestedFPM(DebugLogging);
553 
554       // Parse the inner pipeline inte the nested manager.
555       PipelineText = PipelineText.substr(strlen("function("));
556       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
557                                      DebugLogging) ||
558           PipelineText.empty())
559         return false;
560       assert(PipelineText[0] == ')');
561       PipelineText = PipelineText.substr(1);
562 
563       // Add the nested pass manager with the appropriate adaptor.
564       CGPM.addPass(
565           createCGSCCToFunctionPassAdaptor(std::move(NestedFPM), DebugLogging));
566     } else {
567       // Otherwise try to parse a pass name.
568       size_t End = PipelineText.find_first_of(",)");
569       if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
570         return false;
571       // FIXME: No verifier support for CGSCC passes!
572 
573       PipelineText = PipelineText.substr(End);
574     }
575 
576     if (PipelineText.empty() || PipelineText[0] == ')')
577       return true;
578 
579     assert(PipelineText[0] == ',');
580     PipelineText = PipelineText.substr(1);
581   }
582 }
583 
584 void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM,
585                                        FunctionAnalysisManager &FAM,
586                                        CGSCCAnalysisManager &CGAM,
587                                        ModuleAnalysisManager &MAM) {
588   MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
589   MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
590   CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(FAM); });
591   CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
592   FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
593   FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
594   FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
595   LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
596 }
597 
598 bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
599                                           StringRef &PipelineText,
600                                           bool VerifyEachPass,
601                                           bool DebugLogging) {
602   for (;;) {
603     // Parse nested pass managers by recursing.
604     if (PipelineText.startswith("module(")) {
605       ModulePassManager NestedMPM(DebugLogging);
606 
607       // Parse the inner pipeline into the nested manager.
608       PipelineText = PipelineText.substr(strlen("module("));
609       if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
610                                    DebugLogging) ||
611           PipelineText.empty())
612         return false;
613       assert(PipelineText[0] == ')');
614       PipelineText = PipelineText.substr(1);
615 
616       // Now add the nested manager as a module pass.
617       MPM.addPass(std::move(NestedMPM));
618     } else if (PipelineText.startswith("cgscc(")) {
619       CGSCCPassManager NestedCGPM(DebugLogging);
620 
621       // Parse the inner pipeline inte the nested manager.
622       PipelineText = PipelineText.substr(strlen("cgscc("));
623       if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
624                                   DebugLogging) ||
625           PipelineText.empty())
626         return false;
627       assert(PipelineText[0] == ')');
628       PipelineText = PipelineText.substr(1);
629 
630       // Add the nested pass manager with the appropriate adaptor.
631       MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM),
632                                                           DebugLogging));
633     } else if (PipelineText.startswith("function(")) {
634       FunctionPassManager NestedFPM(DebugLogging);
635 
636       // Parse the inner pipeline inte the nested manager.
637       PipelineText = PipelineText.substr(strlen("function("));
638       if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
639                                      DebugLogging) ||
640           PipelineText.empty())
641         return false;
642       assert(PipelineText[0] == ')');
643       PipelineText = PipelineText.substr(1);
644 
645       // Add the nested pass manager with the appropriate adaptor.
646       MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
647     } else {
648       // Otherwise try to parse a pass name.
649       size_t End = PipelineText.find_first_of(",)");
650       if (!parseModulePassName(MPM, PipelineText.substr(0, End), DebugLogging))
651         return false;
652       if (VerifyEachPass)
653         MPM.addPass(VerifierPass());
654 
655       PipelineText = PipelineText.substr(End);
656     }
657 
658     if (PipelineText.empty() || PipelineText[0] == ')')
659       return true;
660 
661     assert(PipelineText[0] == ',');
662     PipelineText = PipelineText.substr(1);
663   }
664 }
665 
666 // Primary pass pipeline description parsing routine.
667 // FIXME: Should this routine accept a TargetMachine or require the caller to
668 // pre-populate the analysis managers with target-specific stuff?
669 bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
670                                     StringRef PipelineText, bool VerifyEachPass,
671                                     bool DebugLogging) {
672   // By default, try to parse the pipeline as-if it were within an implicit
673   // 'module(...)' pass pipeline. If this will parse at all, it needs to
674   // consume the entire string.
675   if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
676     return PipelineText.empty();
677 
678   // This isn't parsable as a module pipeline, look for the end of a pass name
679   // and directly drop down to that layer.
680   StringRef FirstName =
681       PipelineText.substr(0, PipelineText.find_first_of(",)"));
682   assert(!isModulePassName(FirstName) &&
683          "Already handled all module pipeline options.");
684 
685   // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
686   // pipeline.
687   if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
688     CGSCCPassManager CGPM(DebugLogging);
689     if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
690                                 DebugLogging) ||
691         !PipelineText.empty())
692       return false;
693     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM), DebugLogging));
694     return true;
695   }
696 
697   // Similarly, if this looks like a Function pass, parse the whole thing as
698   // a Function pipelien.
699   if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
700     FunctionPassManager FPM(DebugLogging);
701     if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
702                                    DebugLogging) ||
703         !PipelineText.empty())
704       return false;
705     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
706     return true;
707   }
708 
709   // If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
710   if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
711     LoopPassManager LPM(DebugLogging);
712     if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
713                                DebugLogging) ||
714         !PipelineText.empty())
715       return false;
716     FunctionPassManager FPM(DebugLogging);
717     FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
718     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
719     return true;
720   }
721 
722   return false;
723 }
724 
725 bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
726   while (!PipelineText.empty()) {
727     StringRef Name;
728     std::tie(Name, PipelineText) = PipelineText.split(',');
729     if (!parseAAPassName(AA, Name))
730       return false;
731   }
732 
733   return true;
734 }
735