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/CodegenCleanup.h"
25 #include "polly/CodeGen/IslAst.h"
26 #include "polly/CodePreparation.h"
27 #include "polly/DeLICM.h"
28 #include "polly/DeadCodeElimination.h"
29 #include "polly/DependenceInfo.h"
30 #include "polly/ForwardOpTree.h"
31 #include "polly/JSONExporter.h"
32 #include "polly/LinkAllPasses.h"
33 #include "polly/PolyhedralInfo.h"
34 #include "polly/PruneUnprofitable.h"
35 #include "polly/ScheduleOptimizer.h"
36 #include "polly/ScopDetection.h"
37 #include "polly/ScopInfo.h"
38 #include "polly/Simplify.h"
39 #include "polly/Support/DumpFunctionPass.h"
40 #include "polly/Support/DumpModulePass.h"
41 #include "llvm/Analysis/CFGPrinter.h"
42 #include "llvm/IR/LegacyPassManager.h"
43 #include "llvm/IR/Verifier.h"
44 #include "llvm/Passes/PassBuilder.h"
45 #include "llvm/Passes/PassPlugin.h"
46 #include "llvm/Support/CommandLine.h"
47 #include "llvm/Support/TargetSelect.h"
48 #include "llvm/Transforms/IPO.h"
49 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
50 
51 using namespace llvm;
52 using namespace polly;
53 
54 cl::OptionCategory PollyCategory("Polly Options",
55                                  "Configure the polly loop optimizer");
56 
57 static cl::opt<bool>
58     PollyEnabled("polly",
59                  cl::desc("Enable the polly optimizer (with -O1, -O2 or -O3)"),
60                  cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
61 
62 static cl::opt<bool> PollyDetectOnly(
63     "polly-only-scop-detection",
64     cl::desc("Only run scop detection, but no other optimizations"),
65     cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
66 
67 enum PassPositionChoice {
68   POSITION_EARLY,
69   POSITION_AFTER_LOOPOPT,
70   POSITION_BEFORE_VECTORIZER
71 };
72 
73 enum OptimizerChoice { OPTIMIZER_NONE, OPTIMIZER_ISL };
74 
75 static cl::opt<PassPositionChoice> PassPosition(
76     "polly-position", cl::desc("Where to run polly in the pass pipeline"),
77     cl::values(
78         clEnumValN(POSITION_EARLY, "early", "Before everything"),
79         clEnumValN(POSITION_AFTER_LOOPOPT, "after-loopopt",
80                    "After the loop optimizer (but within the inline cycle)"),
81         clEnumValN(POSITION_BEFORE_VECTORIZER, "before-vectorizer",
82                    "Right before the vectorizer")),
83     cl::Hidden, cl::init(POSITION_BEFORE_VECTORIZER), cl::ZeroOrMore,
84     cl::cat(PollyCategory));
85 
86 static cl::opt<OptimizerChoice>
87     Optimizer("polly-optimizer", cl::desc("Select the scheduling optimizer"),
88               cl::values(clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),
89                          clEnumValN(OPTIMIZER_ISL, "isl",
90                                     "The isl scheduling optimizer")),
91               cl::Hidden, cl::init(OPTIMIZER_ISL), cl::ZeroOrMore,
92               cl::cat(PollyCategory));
93 
94 enum CodeGenChoice { CODEGEN_FULL, CODEGEN_AST, CODEGEN_NONE };
95 static cl::opt<CodeGenChoice> CodeGeneration(
96     "polly-code-generation", cl::desc("How much code-generation to perform"),
97     cl::values(clEnumValN(CODEGEN_FULL, "full", "AST and IR generation"),
98                clEnumValN(CODEGEN_AST, "ast", "Only AST generation"),
99                clEnumValN(CODEGEN_NONE, "none", "No code generation")),
100     cl::Hidden, cl::init(CODEGEN_FULL), cl::ZeroOrMore, cl::cat(PollyCategory));
101 
102 enum TargetChoice { TARGET_CPU, TARGET_GPU, TARGET_HYBRID };
103 static cl::opt<TargetChoice>
104     Target("polly-target", cl::desc("The hardware to target"),
105            cl::values(clEnumValN(TARGET_CPU, "cpu", "generate CPU code")
106 #ifdef GPU_CODEGEN
107                           ,
108                       clEnumValN(TARGET_GPU, "gpu", "generate GPU code"),
109                       clEnumValN(TARGET_HYBRID, "hybrid",
110                                  "generate GPU code (preferably) or CPU code")
111 #endif
112                           ),
113            cl::init(TARGET_CPU), cl::ZeroOrMore, cl::cat(PollyCategory));
114 
115 VectorizerChoice polly::PollyVectorizerChoice;
116 static cl::opt<polly::VectorizerChoice, true> Vectorizer(
117     "polly-vectorizer", cl::desc("Select the vectorization strategy"),
118     cl::values(
119         clEnumValN(polly::VECTORIZER_NONE, "none", "No Vectorization"),
120         clEnumValN(polly::VECTORIZER_POLLY, "polly",
121                    "Polly internal vectorizer"),
122         clEnumValN(
123             polly::VECTORIZER_STRIPMINE, "stripmine",
124             "Strip-mine outer loops for the loop-vectorizer to trigger")),
125     cl::location(PollyVectorizerChoice), cl::init(polly::VECTORIZER_NONE),
126     cl::ZeroOrMore, cl::cat(PollyCategory));
127 
128 static cl::opt<bool> ImportJScop(
129     "polly-import",
130     cl::desc("Import the polyhedral description of the detected Scops"),
131     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
132 
133 static cl::opt<bool> FullyIndexedStaticExpansion(
134     "polly-enable-mse",
135     cl::desc("Fully expand the memory accesses of the detected Scops"),
136     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
137 
138 static cl::opt<bool> ExportJScop(
139     "polly-export",
140     cl::desc("Export the polyhedral description of the detected Scops"),
141     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
142 
143 static cl::opt<bool> DeadCodeElim("polly-run-dce",
144                                   cl::desc("Run the dead code elimination"),
145                                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
146                                   cl::cat(PollyCategory));
147 
148 static cl::opt<bool> PollyViewer(
149     "polly-show",
150     cl::desc("Highlight the code regions that will be optimized in a "
151              "(CFG BBs and LLVM-IR instructions)"),
152     cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
153 
154 static cl::opt<bool> PollyOnlyViewer(
155     "polly-show-only",
156     cl::desc("Highlight the code regions that will be optimized in "
157              "a (CFG only BBs)"),
158     cl::init(false), cl::cat(PollyCategory));
159 
160 static cl::opt<bool>
161     PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"),
162                  cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"),
163                  cl::init(false), cl::cat(PollyCategory));
164 
165 static cl::opt<bool> PollyOnlyPrinter(
166     "polly-dot-only",
167     cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden,
168     cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"),
169     cl::init(false), cl::cat(PollyCategory));
170 
171 static cl::opt<bool>
172     CFGPrinter("polly-view-cfg",
173                cl::desc("Show the Polly CFG right after code generation"),
174                cl::Hidden, cl::init(false), cl::cat(PollyCategory));
175 
176 static cl::opt<bool>
177     EnablePolyhedralInfo("polly-enable-polyhedralinfo",
178                          cl::desc("Enable polyhedral interface of Polly"),
179                          cl::Hidden, cl::init(false), cl::cat(PollyCategory));
180 
181 static cl::opt<bool>
182     EnableForwardOpTree("polly-enable-optree",
183                         cl::desc("Enable operand tree forwarding"), cl::Hidden,
184                         cl::init(true), cl::cat(PollyCategory));
185 
186 static cl::opt<bool>
187     DumpBefore("polly-dump-before",
188                cl::desc("Dump module before Polly transformations into a file "
189                         "suffixed with \"-before\""),
190                cl::init(false), cl::cat(PollyCategory));
191 
192 static cl::list<std::string> DumpBeforeFile(
193     "polly-dump-before-file",
194     cl::desc("Dump module before Polly transformations to the given file"),
195     cl::cat(PollyCategory));
196 
197 static cl::opt<bool>
198     DumpAfter("polly-dump-after",
199               cl::desc("Dump module after Polly transformations into a file "
200                        "suffixed with \"-after\""),
201               cl::init(false), cl::cat(PollyCategory));
202 
203 static cl::list<std::string> DumpAfterFile(
204     "polly-dump-after-file",
205     cl::desc("Dump module after Polly transformations to the given file"),
206     cl::ZeroOrMore, cl::cat(PollyCategory));
207 
208 static cl::opt<bool>
209     EnableDeLICM("polly-enable-delicm",
210                  cl::desc("Eliminate scalar loop carried dependences"),
211                  cl::Hidden, cl::init(true), cl::cat(PollyCategory));
212 
213 static cl::opt<bool>
214     EnableSimplify("polly-enable-simplify",
215                    cl::desc("Simplify SCoP after optimizations"),
216                    cl::init(true), cl::cat(PollyCategory));
217 
218 static cl::opt<bool> EnablePruneUnprofitable(
219     "polly-enable-prune-unprofitable",
220     cl::desc("Bail out on unprofitable SCoPs before rescheduling"), cl::Hidden,
221     cl::init(true), cl::cat(PollyCategory));
222 
223 namespace {
224 
225 /// Initialize Polly passes when library is loaded.
226 ///
227 /// We use the constructor of a statically declared object to initialize the
228 /// different Polly passes right after the Polly library is loaded. This ensures
229 /// that the Polly passes are available e.g. in the 'opt' tool.
230 class StaticInitializer {
231 public:
232   StaticInitializer() {
233     llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
234     polly::initializePollyPasses(Registry);
235   }
236 };
237 static StaticInitializer InitializeEverything;
238 } // end of anonymous namespace.
239 
240 namespace polly {
241 void initializePollyPasses(PassRegistry &Registry) {
242   initializeCodeGenerationPass(Registry);
243 
244 #ifdef GPU_CODEGEN
245   initializePPCGCodeGenerationPass(Registry);
246   initializeManagedMemoryRewritePassPass(Registry);
247   LLVMInitializeNVPTXTarget();
248   LLVMInitializeNVPTXTargetInfo();
249   LLVMInitializeNVPTXTargetMC();
250   LLVMInitializeNVPTXAsmPrinter();
251 #endif
252   initializeCodePreparationPass(Registry);
253   initializeDeadCodeElimWrapperPassPass(Registry);
254   initializeDependenceInfoPass(Registry);
255   initializeDependenceInfoWrapperPassPass(Registry);
256   initializeJSONExporterPass(Registry);
257   initializeJSONImporterPass(Registry);
258   initializeMaximalStaticExpanderPass(Registry);
259   initializeIslAstInfoWrapperPassPass(Registry);
260   initializeIslScheduleOptimizerWrapperPassPass(Registry);
261   initializePollyCanonicalizePass(Registry);
262   initializePolyhedralInfoPass(Registry);
263   initializeScopDetectionWrapperPassPass(Registry);
264   initializeScopInlinerPass(Registry);
265   initializeScopInfoRegionPassPass(Registry);
266   initializeScopInfoWrapperPassPass(Registry);
267   initializeCodegenCleanupPass(Registry);
268   initializeFlattenSchedulePass(Registry);
269   initializeForwardOpTreeWrapperPassPass(Registry);
270   initializeDeLICMWrapperPassPass(Registry);
271   initializeSimplifyWrapperPassPass(Registry);
272   initializeDumpModuleWrapperPassPass(Registry);
273   initializePruneUnprofitableWrapperPassPass(Registry);
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 static void registerPollyPasses(llvm::legacy::PassManagerBase &PM,
303                                 bool EnableForOpt) {
304   if (DumpBefore)
305     PM.add(polly::createDumpModuleWrapperPass("-before", true));
306   for (auto &Filename : DumpBeforeFile)
307     PM.add(polly::createDumpModuleWrapperPass(Filename, false));
308 
309   PM.add(polly::createCodePreparationPass());
310   PM.add(polly::createScopDetectionWrapperPassPass());
311 
312   if (PollyDetectOnly)
313     return;
314 
315   if (PollyViewer)
316     PM.add(polly::createDOTViewerPass());
317   if (PollyOnlyViewer)
318     PM.add(polly::createDOTOnlyViewerPass());
319   if (PollyPrinter)
320     PM.add(polly::createDOTPrinterPass());
321   if (PollyOnlyPrinter)
322     PM.add(polly::createDOTOnlyPrinterPass());
323 
324   PM.add(polly::createScopInfoRegionPassPass());
325   if (EnablePolyhedralInfo)
326     PM.add(polly::createPolyhedralInfoPass());
327 
328   if (EnableSimplify)
329     PM.add(polly::createSimplifyWrapperPass(0));
330   if (EnableForwardOpTree)
331     PM.add(polly::createForwardOpTreeWrapperPass());
332   if (EnableDeLICM)
333     PM.add(polly::createDeLICMWrapperPass());
334   if (EnableSimplify)
335     PM.add(polly::createSimplifyWrapperPass(1));
336 
337   if (ImportJScop)
338     PM.add(polly::createJSONImporterPass());
339 
340   if (DeadCodeElim)
341     PM.add(polly::createDeadCodeElimWrapperPass());
342 
343   if (FullyIndexedStaticExpansion)
344     PM.add(polly::createMaximalStaticExpansionPass());
345 
346   if (EnablePruneUnprofitable)
347     PM.add(polly::createPruneUnprofitableWrapperPass());
348 
349 #ifdef GPU_CODEGEN
350   if (Target == TARGET_HYBRID)
351     PM.add(
352         polly::createPPCGCodeGenerationPass(GPUArchChoice, GPURuntimeChoice));
353 #endif
354   if (Target == TARGET_CPU || Target == TARGET_HYBRID)
355     switch (Optimizer) {
356     case OPTIMIZER_NONE:
357       break; /* Do nothing */
358 
359     case OPTIMIZER_ISL:
360       PM.add(polly::createIslScheduleOptimizerWrapperPass());
361       break;
362     }
363 
364   if (ExportJScop)
365     PM.add(polly::createJSONExporterPass());
366 
367   if (!EnableForOpt)
368     return;
369 
370   if (Target == TARGET_CPU || Target == TARGET_HYBRID)
371     switch (CodeGeneration) {
372     case CODEGEN_AST:
373       PM.add(polly::createIslAstInfoWrapperPassPass());
374       break;
375     case CODEGEN_FULL:
376       PM.add(polly::createCodeGenerationPass());
377       break;
378     case CODEGEN_NONE:
379       break;
380     }
381 #ifdef GPU_CODEGEN
382   else {
383     PM.add(
384         polly::createPPCGCodeGenerationPass(GPUArchChoice, GPURuntimeChoice));
385     PM.add(polly::createManagedMemoryRewritePassPass());
386   }
387 #endif
388 
389 #ifdef GPU_CODEGEN
390   if (Target == TARGET_HYBRID)
391     PM.add(polly::createManagedMemoryRewritePassPass(GPUArchChoice,
392                                                      GPURuntimeChoice));
393 #endif
394 
395   // FIXME: This dummy ModulePass keeps some programs from miscompiling,
396   // probably some not correctly preserved analyses. It acts as a barrier to
397   // force all analysis results to be recomputed.
398   PM.add(createBarrierNoopPass());
399 
400   if (DumpAfter)
401     PM.add(polly::createDumpModuleWrapperPass("-after", true));
402   for (auto &Filename : DumpAfterFile)
403     PM.add(polly::createDumpModuleWrapperPass(Filename, false));
404 
405   if (CFGPrinter)
406     PM.add(llvm::createCFGPrinterLegacyPassPass());
407 }
408 
409 static bool shouldEnablePollyForOptimization() { return PollyEnabled; }
410 
411 static bool shouldEnablePollyForDiagnostic() {
412   // FIXME: PollyTrackFailures is user-controlled, should not be set
413   // programmatically.
414   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)
415     PollyTrackFailures = true;
416 
417   return PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
418          ExportJScop;
419 }
420 
421 static void
422 registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
423                                    llvm::legacy::PassManagerBase &PM) {
424   if (PassPosition != POSITION_EARLY)
425     return;
426 
427   bool EnableForOpt = shouldEnablePollyForOptimization() &&
428                       Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
429   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
430     return;
431 
432   registerCanonicalicationPasses(PM);
433   registerPollyPasses(PM, EnableForOpt);
434 }
435 
436 static void
437 registerPollyLoopOptimizerEndPasses(const llvm::PassManagerBuilder &Builder,
438                                     llvm::legacy::PassManagerBase &PM) {
439   if (PassPosition != POSITION_AFTER_LOOPOPT)
440     return;
441 
442   bool EnableForOpt = shouldEnablePollyForOptimization() &&
443                       Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
444   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
445     return;
446 
447   registerPollyPasses(PM, EnableForOpt);
448   if (EnableForOpt)
449     PM.add(createCodegenCleanupPass());
450 }
451 
452 static void
453 registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder,
454                                        llvm::legacy::PassManagerBase &PM) {
455   if (PassPosition != POSITION_BEFORE_VECTORIZER)
456     return;
457 
458   bool EnableForOpt = shouldEnablePollyForOptimization() &&
459                       Builder.OptLevel >= 1 && Builder.SizeLevel == 0;
460   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
461     return;
462 
463   polly::registerPollyPasses(PM, EnableForOpt);
464   if (EnableForOpt)
465     PM.add(createCodegenCleanupPass());
466 }
467 
468 /// Add the pass sequence required for Polly to the New Pass Manager.
469 ///
470 /// @param PM           The pass manager itself.
471 /// @param Level        The optimization level. Used for the cleanup of Polly's
472 ///                     output.
473 /// @param EnableForOpt Whether to add Polly IR transformations. If False, only
474 ///                     the analysis passes are added, skipping Polly itself.
475 ///                     The IR may still be modified.
476 static void buildCommonPollyPipeline(FunctionPassManager &PM,
477                                      OptimizationLevel Level,
478                                      bool EnableForOpt) {
479   PassBuilder PB;
480   ScopPassManager SPM;
481 
482   PM.addPass(CodePreparationPass());
483 
484   // TODO add utility passes for the various command line options, once they're
485   // ported
486 
487   if (PollyDetectOnly) {
488     // Don't add more passes other than the ScopPassManager's detection passes.
489     PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
490     return;
491   }
492 
493   if (PollyViewer)
494     report_fatal_error("Option -polly-show not supported with NPM", false);
495   if (PollyOnlyViewer)
496     report_fatal_error("Option -polly-show-only not supported with NPM", false);
497   if (PollyPrinter)
498     report_fatal_error("Option -polly-dot not supported with NPM", false);
499   if (PollyOnlyPrinter)
500     report_fatal_error("Option -polly-dot-only not supported with NPM", false);
501   if (EnablePolyhedralInfo)
502     report_fatal_error(
503         "Option -polly-enable-polyhedralinfo not supported with NPM", false);
504 
505   if (EnableSimplify)
506     SPM.addPass(SimplifyPass(0));
507   if (EnableForwardOpTree)
508     SPM.addPass(ForwardOpTreePass());
509   if (EnableDeLICM)
510     SPM.addPass(DeLICMPass());
511   if (EnableSimplify)
512     SPM.addPass(SimplifyPass(1));
513 
514   if (ImportJScop)
515     SPM.addPass(JSONImportPass());
516 
517   if (DeadCodeElim)
518     SPM.addPass(DeadCodeElimPass());
519 
520   if (FullyIndexedStaticExpansion)
521     report_fatal_error("Option -polly-enable-mse not supported with NPM",
522                        false);
523 
524   if (EnablePruneUnprofitable)
525     SPM.addPass(PruneUnprofitablePass());
526 
527   if (Target == TARGET_CPU || Target == TARGET_HYBRID) {
528     switch (Optimizer) {
529     case OPTIMIZER_NONE:
530       break; /* Do nothing */
531     case OPTIMIZER_ISL:
532       SPM.addPass(IslScheduleOptimizerPass());
533       break;
534     }
535   }
536 
537   if (ExportJScop)
538     report_fatal_error("Option -polly-export not supported with NPM", false);
539 
540   if (!EnableForOpt)
541     return;
542 
543   if (Target == TARGET_CPU || Target == TARGET_HYBRID) {
544     switch (CodeGeneration) {
545     case CODEGEN_AST:
546       SPM.addPass(
547           RequireAnalysisPass<IslAstAnalysis, Scop, ScopAnalysisManager,
548                               ScopStandardAnalysisResults &, SPMUpdater &>());
549       break;
550     case CODEGEN_FULL:
551       SPM.addPass(CodeGenerationPass());
552       break;
553     case CODEGEN_NONE:
554       break;
555     }
556   }
557 #ifdef GPU_CODEGEN
558   else
559     report_fatal_error("Option -polly-target=gpu not supported for NPM", false);
560 #endif
561 
562 #ifdef GPU_CODEGEN
563   if (Target == TARGET_HYBRID)
564     report_fatal_error("Option -polly-target=hybrid not supported for NPM",
565                        false);
566 #endif
567 
568   PM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
569   PM.addPass(PB.buildFunctionSimplificationPipeline(
570       Level, ThinOrFullLTOPhase::None)); // Cleanup
571 
572   if (CFGPrinter)
573     PM.addPass(llvm::CFGPrinterPass());
574 }
575 
576 static void buildEarlyPollyPipeline(ModulePassManager &MPM,
577                                     OptimizationLevel Level) {
578   bool EnableForOpt =
579       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
580   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
581     return;
582 
583   FunctionPassManager FPM = buildCanonicalicationPassesForNPM(MPM, Level);
584 
585   if (DumpBefore || !DumpBeforeFile.empty()) {
586     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
587 
588     if (DumpBefore)
589       MPM.addPass(DumpModulePass("-before", true));
590     for (auto &Filename : DumpBeforeFile)
591       MPM.addPass(DumpModulePass(Filename, false));
592 
593     FPM = FunctionPassManager();
594   }
595 
596   buildCommonPollyPipeline(FPM, Level, EnableForOpt);
597   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
598 
599   if (DumpAfter)
600     MPM.addPass(DumpModulePass("-after", true));
601   for (auto &Filename : DumpAfterFile)
602     MPM.addPass(DumpModulePass(Filename, false));
603 }
604 
605 static void buildLatePollyPipeline(FunctionPassManager &PM,
606                                    OptimizationLevel Level) {
607   bool EnableForOpt =
608       shouldEnablePollyForOptimization() && Level.isOptimizingForSpeed();
609   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
610     return;
611 
612   if (DumpBefore)
613     PM.addPass(DumpFunctionPass("-before"));
614   if (!DumpBeforeFile.empty())
615     report_fatal_error("Option -polly-dump-before-file at -polly-position=late "
616                        "not supported with NPM",
617                        false);
618 
619   buildCommonPollyPipeline(PM, Level, EnableForOpt);
620 
621   if (DumpAfter)
622     PM.addPass(DumpFunctionPass("-after"));
623   if (!DumpAfterFile.empty())
624     report_fatal_error("Option -polly-dump-after-file at -polly-position=late "
625                        "not supported with NPM",
626                        false);
627 }
628 
629 /// Register Polly to be available as an optimizer
630 ///
631 ///
632 /// We can currently run Polly at three different points int the pass manager.
633 /// a) very early, b) after the canonicalizing loop transformations and c) right
634 /// before the vectorizer.
635 ///
636 /// The default is currently a), to register Polly such that it runs as early as
637 /// possible. This has several implications:
638 ///
639 ///   1) We need to schedule more canonicalization passes
640 ///
641 ///   As nothing is run before Polly, it is necessary to run a set of preparing
642 ///   transformations before Polly to canonicalize the LLVM-IR and to allow
643 ///   Polly to detect and understand the code.
644 ///
645 ///   2) LICM and LoopIdiom pass have not yet been run
646 ///
647 ///   Loop invariant code motion as well as the loop idiom recognition pass make
648 ///   it more difficult for Polly to transform code. LICM may introduce
649 ///   additional data dependences that are hard to eliminate and the loop idiom
650 ///   recognition pass may introduce calls to memset that we currently do not
651 ///   understand. By running Polly early enough (meaning before these passes) we
652 ///   avoid difficulties that may be introduced by these passes.
653 ///
654 ///   3) We get the full -O3 optimization sequence after Polly
655 ///
656 ///   The LLVM-IR that is generated by Polly has been optimized on a high level,
657 ///   but it may be rather inefficient on the lower/scalar level. By scheduling
658 ///   Polly before all other passes, we have the full sequence of -O3
659 ///   optimizations behind us, such that inefficiencies on the low level can
660 ///   be optimized away.
661 ///
662 /// We are currently evaluating the benefit or running Polly at position b) or
663 /// c). b) is likely too early as it interacts with the inliner. c) is nice
664 /// as everything is fully inlined and canonicalized, but we need to be able
665 /// to handle LICMed code to make it useful.
666 static llvm::RegisterStandardPasses RegisterPollyOptimizerEarly(
667     llvm::PassManagerBuilder::EP_ModuleOptimizerEarly,
668     registerPollyEarlyAsPossiblePasses);
669 
670 static llvm::RegisterStandardPasses
671     RegisterPollyOptimizerLoopEnd(llvm::PassManagerBuilder::EP_LoopOptimizerEnd,
672                                   registerPollyLoopOptimizerEndPasses);
673 
674 static llvm::RegisterStandardPasses RegisterPollyOptimizerScalarLate(
675     llvm::PassManagerBuilder::EP_VectorizerStart,
676     registerPollyScalarOptimizerLatePasses);
677 
678 static OwningScopAnalysisManagerFunctionProxy
679 createScopAnalyses(FunctionAnalysisManager &FAM,
680                    PassInstrumentationCallbacks *PIC) {
681   OwningScopAnalysisManagerFunctionProxy Proxy;
682 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
683   Proxy.getManager().registerPass([PIC] {                                      \
684     (void)PIC;                                                                 \
685     return CREATE_PASS;                                                        \
686   });
687 #include "PollyPasses.def"
688 
689   Proxy.getManager().registerPass(
690       [&FAM] { return FunctionAnalysisManagerScopProxy(FAM); });
691   return Proxy;
692 }
693 
694 static void registerFunctionAnalyses(FunctionAnalysisManager &FAM,
695                                      PassInstrumentationCallbacks *PIC) {
696 
697 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
698   FAM.registerPass([] { return CREATE_PASS; });
699 
700 #include "PollyPasses.def"
701 
702   FAM.registerPass([&FAM, PIC] { return createScopAnalyses(FAM, PIC); });
703 }
704 
705 static bool
706 parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
707                       ArrayRef<PassBuilder::PipelineElement> Pipeline) {
708   if (parseAnalysisUtilityPasses<OwningScopAnalysisManagerFunctionProxy>(
709           "polly-scop-analyses", Name, FPM))
710     return true;
711 
712 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
713   if (parseAnalysisUtilityPasses<                                              \
714           std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name,      \
715                                                               FPM))            \
716     return true;
717 
718 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
719   if (Name == NAME) {                                                          \
720     FPM.addPass(CREATE_PASS);                                                  \
721     return true;                                                               \
722   }
723 
724 #include "PollyPasses.def"
725   return false;
726 }
727 
728 static bool parseScopPass(StringRef Name, ScopPassManager &SPM,
729                           PassInstrumentationCallbacks *PIC) {
730 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
731   if (parseAnalysisUtilityPasses<                                              \
732           std::remove_reference<decltype(CREATE_PASS)>::type>(NAME, Name,      \
733                                                               SPM))            \
734     return true;
735 
736 #define SCOP_PASS(NAME, CREATE_PASS)                                           \
737   if (Name == NAME) {                                                          \
738     SPM.addPass(CREATE_PASS);                                                  \
739     return true;                                                               \
740   }
741 
742 #include "PollyPasses.def"
743 
744   return false;
745 }
746 
747 static bool parseScopPipeline(StringRef Name, FunctionPassManager &FPM,
748                               PassInstrumentationCallbacks *PIC,
749                               ArrayRef<PassBuilder::PipelineElement> Pipeline) {
750   if (Name != "scop")
751     return false;
752   if (!Pipeline.empty()) {
753     ScopPassManager SPM;
754     for (const auto &E : Pipeline)
755       if (!parseScopPass(E.Name, SPM, PIC))
756         return false;
757     FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
758   }
759   return true;
760 }
761 
762 static bool isScopPassName(StringRef Name) {
763 #define SCOP_ANALYSIS(NAME, CREATE_PASS)                                       \
764   if (Name == "require<" NAME ">")                                             \
765     return true;                                                               \
766   if (Name == "invalidate<" NAME ">")                                          \
767     return true;
768 
769 #define SCOP_PASS(NAME, CREATE_PASS)                                           \
770   if (Name == NAME)                                                            \
771     return true;
772 
773 #include "PollyPasses.def"
774 
775   return false;
776 }
777 
778 static bool
779 parseTopLevelPipeline(ModulePassManager &MPM, PassInstrumentationCallbacks *PIC,
780                       ArrayRef<PassBuilder::PipelineElement> Pipeline) {
781   std::vector<PassBuilder::PipelineElement> FullPipeline;
782   StringRef FirstName = Pipeline.front().Name;
783 
784   if (!isScopPassName(FirstName))
785     return false;
786 
787   FunctionPassManager FPM;
788   ScopPassManager SPM;
789 
790   for (auto &Element : Pipeline) {
791     auto &Name = Element.Name;
792     auto &InnerPipeline = Element.InnerPipeline;
793     if (!InnerPipeline.empty()) // Scop passes don't have inner pipelines
794       return false;
795     if (!parseScopPass(Name, SPM, PIC))
796       return false;
797   }
798 
799   FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM)));
800   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
801 
802   return true;
803 }
804 
805 void registerPollyPasses(PassBuilder &PB) {
806   PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
807   PB.registerAnalysisRegistrationCallback([PIC](FunctionAnalysisManager &FAM) {
808     registerFunctionAnalyses(FAM, PIC);
809   });
810   PB.registerPipelineParsingCallback(parseFunctionPipeline);
811   PB.registerPipelineParsingCallback(
812       [PIC](StringRef Name, FunctionPassManager &FPM,
813             ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
814         return parseScopPipeline(Name, FPM, PIC, Pipeline);
815       });
816   PB.registerParseTopLevelPipelineCallback(
817       [PIC](ModulePassManager &MPM,
818             ArrayRef<PassBuilder::PipelineElement> Pipeline) -> bool {
819         return parseTopLevelPipeline(MPM, PIC, Pipeline);
820       });
821 
822   switch (PassPosition) {
823   case POSITION_EARLY:
824     PB.registerPipelineStartEPCallback(buildEarlyPollyPipeline);
825     break;
826   case POSITION_AFTER_LOOPOPT:
827     report_fatal_error(
828         "Option -polly-position=after-loopopt not supported with NPM", false);
829     break;
830   case POSITION_BEFORE_VECTORIZER:
831     PB.registerVectorizerStartEPCallback(buildLatePollyPipeline);
832     break;
833   }
834 }
835 } // namespace polly
836 
837 llvm::PassPluginLibraryInfo getPollyPluginInfo() {
838   return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING,
839           polly::registerPollyPasses};
840 }
841