xref: /llvm-project/polly/lib/Support/RegisterPasses.cpp (revision 42cd38c01e5b76357e77b8c0f4f32d77a97d153f)
1 //===------ RegisterPasses.cpp - Add the Polly Passes to default passes  --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file composes the individual LLVM-IR passes provided by Polly to a
10 // functional polyhedral optimizer. The polyhedral optimizer is automatically
11 // made available to LLVM based compilers by loading the Polly shared library
12 // into such a compiler.
13 //
14 // The Polly optimizer is made available by executing a static constructor that
15 // registers the individual Polly passes in the LLVM pass manager builder. The
16 // passes are registered such that the default behaviour of the compiler is not
17 // changed, but that the flag '-polly' provided at optimization level '-O3'
18 // enables additional polyhedral optimizations.
19 //===----------------------------------------------------------------------===//
20 
21 #include "polly/RegisterPasses.h"
22 #include "polly/Canonicalization.h"
23 #include "polly/CodeGen/CodeGeneration.h"
24 #include "polly/CodeGen/IslAst.h"
25 #include "polly/CodePreparation.h"
26 #include "polly/DeLICM.h"
27 #include "polly/DeadCodeElimination.h"
28 #include "polly/DependenceInfo.h"
29 #include "polly/ForwardOpTree.h"
30 #include "polly/JSONExporter.h"
31 #include "polly/LinkAllPasses.h"
32 #include "polly/MaximalStaticExpansion.h"
33 #include "polly/PolyhedralInfo.h"
34 #include "polly/PruneUnprofitable.h"
35 #include "polly/ScheduleOptimizer.h"
36 #include "polly/ScopDetection.h"
37 #include "polly/ScopGraphPrinter.h"
38 #include "polly/ScopInfo.h"
39 #include "polly/Simplify.h"
40 #include "polly/Support/DumpFunctionPass.h"
41 #include "polly/Support/DumpModulePass.h"
42 #include "llvm/Analysis/CFGPrinter.h"
43 #include "llvm/IR/LegacyPassManager.h"
44 #include "llvm/IR/PassManager.h"
45 #include "llvm/IR/Verifier.h"
46 #include "llvm/Passes/PassBuilder.h"
47 #include "llvm/Passes/PassPlugin.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/TargetSelect.h"
50 #include "llvm/Transforms/IPO.h"
51 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
52 
53 namespace cl = llvm::cl;
54 
55 using llvm::FunctionPassManager;
56 using llvm::OptimizationLevel;
57 using llvm::PassBuilder;
58 using llvm::PassInstrumentationCallbacks;
59 
60 cl::OptionCategory PollyCategory("Polly Options",
61                                  "Configure the polly loop optimizer");
62 
63 namespace polly {
64 static cl::opt<bool>
65     PollyEnabled("polly",
66                  cl::desc("Enable the polly optimizer (with -O1, -O2 or -O3)"),
67                  cl::cat(PollyCategory));
68 
69 static cl::opt<bool> PollyDetectOnly(
70     "polly-only-scop-detection",
71     cl::desc("Only run scop detection, but no other optimizations"),
72     cl::cat(PollyCategory));
73 
74 enum PassPositionChoice { POSITION_EARLY, POSITION_BEFORE_VECTORIZER };
75 
76 enum OptimizerChoice { OPTIMIZER_NONE, OPTIMIZER_ISL };
77 
78 static cl::opt<PassPositionChoice> PassPosition(
79     "polly-position", cl::desc("Where to run polly in the pass pipeline"),
80     cl::values(clEnumValN(POSITION_EARLY, "early", "Before everything"),
81                clEnumValN(POSITION_BEFORE_VECTORIZER, "before-vectorizer",
82                           "Right before the vectorizer")),
83     cl::Hidden, cl::init(POSITION_BEFORE_VECTORIZER), cl::cat(PollyCategory));
84 
85 static cl::opt<OptimizerChoice>
86     Optimizer("polly-optimizer", cl::desc("Select the scheduling optimizer"),
87               cl::values(clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),
88                          clEnumValN(OPTIMIZER_ISL, "isl",
89                                     "The isl scheduling optimizer")),
90               cl::Hidden, cl::init(OPTIMIZER_ISL), cl::cat(PollyCategory));
91 
92 enum CodeGenChoice { CODEGEN_FULL, CODEGEN_AST, CODEGEN_NONE };
93 static cl::opt<CodeGenChoice> CodeGeneration(
94     "polly-code-generation", cl::desc("How much code-generation to perform"),
95     cl::values(clEnumValN(CODEGEN_FULL, "full", "AST and IR generation"),
96                clEnumValN(CODEGEN_AST, "ast", "Only AST generation"),
97                clEnumValN(CODEGEN_NONE, "none", "No code generation")),
98     cl::Hidden, cl::init(CODEGEN_FULL), cl::cat(PollyCategory));
99 
100 VectorizerChoice PollyVectorizerChoice;
101 
102 static cl::opt<VectorizerChoice, true> Vectorizer(
103     "polly-vectorizer", cl::desc("Select the vectorization strategy"),
104     cl::values(
105         clEnumValN(VECTORIZER_NONE, "none", "No Vectorization"),
106         clEnumValN(
107             VECTORIZER_STRIPMINE, "stripmine",
108             "Strip-mine outer loops for the loop-vectorizer to trigger")),
109     cl::location(PollyVectorizerChoice), cl::init(VECTORIZER_NONE),
110     cl::cat(PollyCategory));
111 
112 static cl::opt<bool> ImportJScop(
113     "polly-import",
114     cl::desc("Import the polyhedral description of the detected Scops"),
115     cl::Hidden, cl::cat(PollyCategory));
116 
117 static cl::opt<bool> FullyIndexedStaticExpansion(
118     "polly-enable-mse",
119     cl::desc("Fully expand the memory accesses of the detected Scops"),
120     cl::Hidden, cl::cat(PollyCategory));
121 
122 static cl::opt<bool> ExportJScop(
123     "polly-export",
124     cl::desc("Export the polyhedral description of the detected Scops"),
125     cl::Hidden, cl::cat(PollyCategory));
126 
127 static cl::opt<bool> DeadCodeElim("polly-run-dce",
128                                   cl::desc("Run the dead code elimination"),
129                                   cl::Hidden, cl::cat(PollyCategory));
130 
131 static cl::opt<bool> PollyViewer(
132     "polly-show",
133     cl::desc("Highlight the code regions that will be optimized in a "
134              "(CFG BBs and LLVM-IR instructions)"),
135     cl::cat(PollyCategory));
136 
137 static cl::opt<bool> PollyOnlyViewer(
138     "polly-show-only",
139     cl::desc("Highlight the code regions that will be optimized in "
140              "a (CFG only BBs)"),
141     cl::init(false), cl::cat(PollyCategory));
142 
143 static cl::opt<bool>
144     PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"),
145                  cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"),
146                  cl::init(false), cl::cat(PollyCategory));
147 
148 static cl::opt<bool> PollyOnlyPrinter(
149     "polly-dot-only",
150     cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden,
151     cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"),
152     cl::init(false), cl::cat(PollyCategory));
153 
154 static cl::opt<bool>
155     CFGPrinter("polly-view-cfg",
156                cl::desc("Show the Polly CFG right after code generation"),
157                cl::Hidden, cl::init(false), cl::cat(PollyCategory));
158 
159 static cl::opt<bool>
160     EnableForwardOpTree("polly-enable-optree",
161                         cl::desc("Enable operand tree forwarding"), cl::Hidden,
162                         cl::init(true), cl::cat(PollyCategory));
163 
164 static cl::opt<bool>
165     DumpBefore("polly-dump-before",
166                cl::desc("Dump module before Polly transformations into a file "
167                         "suffixed with \"-before\""),
168                cl::init(false), cl::cat(PollyCategory));
169 
170 static cl::list<std::string> DumpBeforeFile(
171     "polly-dump-before-file",
172     cl::desc("Dump module before Polly transformations to the given file"),
173     cl::cat(PollyCategory));
174 
175 static cl::opt<bool>
176     DumpAfter("polly-dump-after",
177               cl::desc("Dump module after Polly transformations into a file "
178                        "suffixed with \"-after\""),
179               cl::init(false), cl::cat(PollyCategory));
180 
181 static cl::list<std::string> DumpAfterFile(
182     "polly-dump-after-file",
183     cl::desc("Dump module after Polly transformations to the given file"),
184     cl::cat(PollyCategory));
185 
186 static cl::opt<bool>
187     EnableDeLICM("polly-enable-delicm",
188                  cl::desc("Eliminate scalar loop carried dependences"),
189                  cl::Hidden, cl::init(true), cl::cat(PollyCategory));
190 
191 static cl::opt<bool>
192     EnableSimplify("polly-enable-simplify",
193                    cl::desc("Simplify SCoP after optimizations"),
194                    cl::init(true), cl::cat(PollyCategory));
195 
196 static cl::opt<bool> EnablePruneUnprofitable(
197     "polly-enable-prune-unprofitable",
198     cl::desc("Bail out on unprofitable SCoPs before rescheduling"), cl::Hidden,
199     cl::init(true), cl::cat(PollyCategory));
200 
201 namespace {
202 
203 /// Initialize Polly passes when library is loaded.
204 ///
205 /// We use the constructor of a statically declared object to initialize the
206 /// different Polly passes right after the Polly library is loaded. This ensures
207 /// that the Polly passes are available e.g. in the 'opt' tool.
208 struct StaticInitializer {
209   StaticInitializer() {
210     llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
211     polly::initializePollyPasses(Registry);
212   }
213 };
214 static StaticInitializer InitializeEverything;
215 } // end of anonymous namespace.
216 
217 void initializePollyPasses(llvm::PassRegistry &Registry) {
218   initializeCodeGenerationPass(Registry);
219 
220 #ifdef GPU_CODEGEN
221   initializePPCGCodeGenerationPass(Registry);
222   initializeManagedMemoryRewritePassPass(Registry);
223   LLVMInitializeNVPTXTarget();
224   LLVMInitializeNVPTXTargetInfo();
225   LLVMInitializeNVPTXTargetMC();
226   LLVMInitializeNVPTXAsmPrinter();
227 #endif
228   initializeCodePreparationPass(Registry);
229   initializeDeadCodeElimWrapperPassPass(Registry);
230   initializeDependenceInfoPass(Registry);
231   initializeDependenceInfoPrinterLegacyPassPass(Registry);
232   initializeDependenceInfoWrapperPassPass(Registry);
233   initializeDependenceInfoPrinterLegacyFunctionPassPass(Registry);
234   initializeJSONExporterPass(Registry);
235   initializeJSONImporterPass(Registry);
236   initializeJSONImporterPrinterLegacyPassPass(Registry);
237   initializeMaximalStaticExpanderWrapperPassPass(Registry);
238   initializeIslAstInfoWrapperPassPass(Registry);
239   initializeIslAstInfoPrinterLegacyPassPass(Registry);
240   initializeIslScheduleOptimizerWrapperPassPass(Registry);
241   initializeIslScheduleOptimizerPrinterLegacyPassPass(Registry);
242   initializePollyCanonicalizePass(Registry);
243   initializePolyhedralInfoPass(Registry);
244   initializePolyhedralInfoPrinterLegacyPassPass(Registry);
245   initializeScopDetectionWrapperPassPass(Registry);
246   initializeScopDetectionPrinterLegacyPassPass(Registry);
247   initializeScopInlinerPass(Registry);
248   initializeScopInfoRegionPassPass(Registry);
249   initializeScopInfoPrinterLegacyRegionPassPass(Registry);
250   initializeScopInfoWrapperPassPass(Registry);
251   initializeScopInfoPrinterLegacyFunctionPassPass(Registry);
252   initializeFlattenSchedulePass(Registry);
253   initializeFlattenSchedulePrinterLegacyPassPass(Registry);
254   initializeForwardOpTreeWrapperPassPass(Registry);
255   initializeForwardOpTreePrinterLegacyPassPass(Registry);
256   initializeDeLICMWrapperPassPass(Registry);
257   initializeDeLICMPrinterLegacyPassPass(Registry);
258   initializeSimplifyWrapperPassPass(Registry);
259   initializeSimplifyPrinterLegacyPassPass(Registry);
260   initializeDumpModuleWrapperPassPass(Registry);
261   initializePruneUnprofitableWrapperPassPass(Registry);
262 }
263 
264 static bool shouldEnablePollyForOptimization() { return PollyEnabled; }
265 
266 static bool shouldEnablePollyForDiagnostic() {
267   // FIXME: PollyTrackFailures is user-controlled, should not be set
268   // programmatically.
269   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)
270     PollyTrackFailures = true;
271 
272   return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
273          ExportJScop;
274 }
275 
276 /// Register Polly passes such that they form a polyhedral optimizer.
277 ///
278 /// The individual Polly passes are registered in the pass manager such that
279 /// they form a full polyhedral optimizer. The flow of the optimizer starts with
280 /// a set of preparing transformations that canonicalize the LLVM-IR such that
281 /// the LLVM-IR is easier for us to understand and to optimizes. On the
282 /// canonicalized LLVM-IR we first run the ScopDetection pass, which detects
283 /// static control flow regions. Those regions are then translated by the
284 /// ScopInfo pass into a polyhedral representation. As a next step, a scheduling
285 /// optimizer is run on the polyhedral representation and finally the optimized
286 /// polyhedral representation is code generated back to LLVM-IR.
287 ///
288 /// Besides this core functionality, we optionally schedule passes that provide
289 /// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that
290 /// allow the export/import of the polyhedral representation
291 /// (JSCON[Exporter|Importer]) or that show the cfg after code generation.
292 ///
293 /// For certain parts of the Polly optimizer, several alternatives are provided:
294 ///
295 /// As scheduling optimizer we support the isl scheduling optimizer
296 /// (http://freecode.com/projects/isl).
297 /// It is also possible to run Polly with no optimizer. This mode is mainly
298 /// provided to analyze the run and compile time changes caused by the
299 /// scheduling optimizer.
300 ///
301 /// Polly supports the isl internal code generator.
302 
303 /// Add the pass sequence required for Polly to the New Pass Manager.
304 ///
305 /// @param PM           The pass manager itself.
306 /// @param Level        The optimization level. Used for the cleanup of Polly's
307 ///                     output.
308 /// @param EnableForOpt Whether to add Polly IR transformations. If False, only
309 ///                     the analysis passes are added, skipping Polly itself.
310 ///                     The IR may still be modified.
311 static void buildCommonPollyPipeline(FunctionPassManager &PM,
312                                      OptimizationLevel Level,
313                                      bool EnableForOpt) {
314   PassBuilder PB;
315   ScopPassManager SPM;
316 
317   PM.addPass(CodePreparationPass());
318 
319   // TODO add utility passes for the various command line options, once they're
320   // ported
321 
322   if (PollyDetectOnly) {
323     // Don't add more passes other than the ScopPassManager's detection passes.
324     PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
325     return;
326   }
327 
328   if (PollyViewer)
329     PM.addPass(ScopViewer());
330   if (PollyOnlyViewer)
331     PM.addPass(ScopOnlyViewer());
332   if (PollyPrinter)
333     PM.addPass(ScopPrinter());
334   if (PollyOnlyPrinter)
335     PM.addPass(ScopOnlyPrinter());
336   if (EnableSimplify)
337     SPM.addPass(SimplifyPass(0));
338   if (EnableForwardOpTree)
339     SPM.addPass(ForwardOpTreePass());
340   if (EnableDeLICM)
341     SPM.addPass(DeLICMPass());
342   if (EnableSimplify)
343     SPM.addPass(SimplifyPass(1));
344 
345   if (ImportJScop)
346     SPM.addPass(JSONImportPass());
347 
348   if (DeadCodeElim)
349     SPM.addPass(DeadCodeElimPass());
350 
351   if (FullyIndexedStaticExpansion)
352     SPM.addPass(MaximalStaticExpansionPass());
353 
354   if (EnablePruneUnprofitable)
355     SPM.addPass(PruneUnprofitablePass());
356 
357   switch (Optimizer) {
358   case OPTIMIZER_NONE:
359     break; /* Do nothing */
360   case OPTIMIZER_ISL:
361     SPM.addPass(IslScheduleOptimizerPass());
362     break;
363   }
364 
365   if (ExportJScop)
366     SPM.addPass(JSONExportPass());
367 
368   if (!EnableForOpt)
369     return;
370 
371   switch (CodeGeneration) {
372   case CODEGEN_AST:
373     SPM.addPass(
374         llvm::RequireAnalysisPass<IslAstAnalysis, Scop, ScopAnalysisManager,
375                                   ScopStandardAnalysisResults &,
376                                   SPMUpdater &>());
377     break;
378   case CODEGEN_FULL:
379     SPM.addPass(CodeGenerationPass());
380     break;
381   case CODEGEN_NONE:
382     break;
383   }
384 
385   PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
386   PM.addPass(PB.buildFunctionSimplificationPipeline(
387       Level, llvm::ThinOrFullLTOPhase::None)); // Cleanup
388 
389   if (CFGPrinter)
390     PM.addPass(llvm::CFGPrinterPass());
391 }
392 
393 static void buildEarlyPollyPipeline(llvm::ModulePassManager &MPM,
394                                     llvm::OptimizationLevel Level) {
395   bool EnableForOpt =
396       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
397   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
398     return;
399 
400   FunctionPassManager FPM = buildCanonicalicationPassesForNPM(MPM, Level);
401 
402   if (DumpBefore || !DumpBeforeFile.empty()) {
403     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
404 
405     if (DumpBefore)
406       MPM.addPass(DumpModulePass("-before", true));
407     for (auto &Filename : DumpBeforeFile)
408       MPM.addPass(DumpModulePass(Filename, false));
409 
410     FPM = FunctionPassManager();
411   }
412 
413   buildCommonPollyPipeline(FPM, Level, EnableForOpt);
414   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
415 
416   if (DumpAfter)
417     MPM.addPass(DumpModulePass("-after", true));
418   for (auto &Filename : DumpAfterFile)
419     MPM.addPass(DumpModulePass(Filename, false));
420 }
421 
422 static void buildLatePollyPipeline(FunctionPassManager &PM,
423                                    llvm::OptimizationLevel Level) {
424   bool EnableForOpt =
425       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
426   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
427     return;
428 
429   if (DumpBefore)
430     PM.addPass(DumpFunctionPass("-before"));
431   if (!DumpBeforeFile.empty())
432     llvm::report_fatal_error(
433         "Option -polly-dump-before-file at -polly-position=late "
434         "not supported with NPM",
435         false);
436 
437   buildCommonPollyPipeline(PM, Level, EnableForOpt);
438 
439   if (DumpAfter)
440     PM.addPass(DumpFunctionPass("-after"));
441   if (!DumpAfterFile.empty())
442     llvm::report_fatal_error(
443         "Option -polly-dump-after-file at -polly-position=late "
444         "not supported with NPM",
445         false);
446 }
447 
448 static OwningScopAnalysisManagerFunctionProxy
449 createScopAnalyses(FunctionAnalysisManager &FAM,
450                    PassInstrumentationCallbacks *PIC) {
451   OwningScopAnalysisManagerFunctionProxy Proxy;
452 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
453   Proxy.getManager().registerPass([PIC] {                                      \
454     (void)PIC;                                                                 \
455     return CREATE_PASS;                                                        \
456   });
457 #include "PollyPasses.def"
458 
459   Proxy.getManager().registerPass(
460       [&FAM] { return FunctionAnalysisManagerScopProxy(FAM); });
461   return Proxy;
462 }
463 
464 static void registerFunctionAnalyses(FunctionAnalysisManager &FAM,
465                                      PassInstrumentationCallbacks *PIC) {
466 
467 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
468   FAM.registerPass([] { return CREATE_PASS; });
469 
470 #include "PollyPasses.def"
471 
472   FAM.registerPass([&FAM, PIC] { return createScopAnalyses(FAM, PIC); });
473 }
474 
475 static bool
476 parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
477                       ArrayRef<PassBuilder::PipelineElement> Pipeline) {
478   if (llvm::parseAnalysisUtilityPasses<OwningScopAnalysisManagerFunctionProxy>(
479           "polly-scop-analyses", Name, FPM))
480     return true;
481 
482 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
483   if (llvm::parseAnalysisUtilityPasses<                                        \
484           std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name,      \
485                                                               FPM))            \
486     return true;
487 
488 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
489   if (Name == NAME) {                                                          \
490     FPM.addPass(CREATE_PASS);                                                  \
491     return true;                                                               \
492   }
493 
494 #include "PollyPasses.def"
495   return false;
496 }
497 
498 static bool parseScopPass(StringRef Name, ScopPassManager &SPM,
499                           PassInstrumentationCallbacks *PIC) {
500 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
501   if (llvm::parseAnalysisUtilityPasses<                                        \
502           std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name,      \
503                                                               SPM))            \
504     return true;
505 
506 #define SCOP_PASS(NAME, CREATE_PASS)                                           \
507   if (Name == NAME) {                                                          \
508     SPM.addPass(CREATE_PASS);                                                  \
509     return true;                                                               \
510   }
511 
512 #include "PollyPasses.def"
513 
514   return false;
515 }
516 
517 static bool parseScopPipeline(StringRef Name, FunctionPassManager &FPM,
518                               PassInstrumentationCallbacks *PIC,
519                               ArrayRef<PassBuilder::PipelineElement> Pipeline) {
520   if (Name != "scop")
521     return false;
522   if (!Pipeline.empty()) {
523     ScopPassManager SPM;
524     for (const auto &E : Pipeline)
525       if (!parseScopPass(E.Name, SPM, PIC))
526         return false;
527     FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
528   }
529   return true;
530 }
531 
532 static bool isScopPassName(StringRef Name) {
533 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
534   if (Name == "require<" NAME ">")                                             \
535     return true;                                                               \
536   if (Name == "invalidate<" NAME ">")                                          \
537     return true;
538 
539 #define SCOP_PASS(NAME, CREATE_PASS)                                           \
540   if (Name == NAME)                                                            \
541     return true;
542 
543 #include "PollyPasses.def"
544 
545   return false;
546 }
547 
548 static bool
549 parseTopLevelPipeline(llvm::ModulePassManager &MPM,
550                       PassInstrumentationCallbacks *PIC,
551                       ArrayRef<PassBuilder::PipelineElement> Pipeline) {
552   std::vector<PassBuilder::PipelineElement> FullPipeline;
553   StringRef FirstName = Pipeline.front().Name;
554 
555   if (!isScopPassName(FirstName))
556     return false;
557 
558   FunctionPassManager FPM;
559   ScopPassManager SPM;
560 
561   for (auto &Element : Pipeline) {
562     auto &Name = Element.Name;
563     auto &InnerPipeline = Element.InnerPipeline;
564     if (!InnerPipeline.empty()) // Scop passes don't have inner pipelines
565       return false;
566     if (!parseScopPass(Name, SPM, PIC))
567       return false;
568   }
569 
570   FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
571   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
572 
573   return true;
574 }
575 
576 /// Register Polly to be available as an optimizer
577 ///
578 ///
579 /// We can currently run Polly at two different points int the pass manager.
580 /// a) very early, b) right before the vectorizer.
581 ///
582 /// The default is currently a), to register Polly such that it runs as early as
583 /// possible. This has several implications:
584 ///
585 ///   1) We need to schedule more canonicalization passes
586 ///
587 ///   As nothing is run before Polly, it is necessary to run a set of preparing
588 ///   transformations before Polly to canonicalize the LLVM-IR and to allow
589 ///   Polly to detect and understand the code.
590 ///
591 ///   2) We get the full -O3 optimization sequence after Polly
592 ///
593 ///   The LLVM-IR that is generated by Polly has been optimized on a high level,
594 ///   but it may be rather inefficient on the lower/scalar level. By scheduling
595 ///   Polly before all other passes, we have the full sequence of -O3
596 ///   optimizations behind us, such that inefficiencies on the low level can
597 ///   be optimized away.
598 ///
599 /// We are currently evaluating the benefit or running Polly at b). b) is nice
600 /// as everything is fully inlined and canonicalized, but we need to be able to
601 /// handle LICMed code to make it useful.
602 void registerPollyPasses(PassBuilder &PB) {
603   PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
604   PB.registerAnalysisRegistrationCallback([PIC](FunctionAnalysisManager &FAM) {
605     registerFunctionAnalyses(FAM, PIC);
606   });
607   PB.registerPipelineParsingCallback(parseFunctionPipeline);
608   PB.registerPipelineParsingCallback(
609       [PIC](StringRef Name, FunctionPassManager &FPM,
610             ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
611         return parseScopPipeline(Name, FPM, PIC, Pipeline);
612       });
613   PB.registerParseTopLevelPipelineCallback(
614       [PIC](llvm::ModulePassManager &MPM,
615             ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
616         return parseTopLevelPipeline(MPM, PIC, Pipeline);
617       });
618 
619   switch (PassPosition) {
620   case POSITION_EARLY:
621     PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline);
622     break;
623   case POSITION_BEFORE_VECTORIZER:
624     PB.registerVectorizerStartEPCallback(buildLatePollyPipeline);
625     break;
626   }
627 }
628 } // namespace polly
629 
630 llvm::PassPluginLibraryInfo getPollyPluginInfo() {
631   return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING,
632           polly::registerPollyPasses};
633 }
634