1 //===------ RegisterPasses.cpp - Add the Polly Passes to default passes  --===//
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 //
10 // This file composes the individual LLVM-IR passes provided by Polly to a
11 // functional polyhedral optimizer. The polyhedral optimizer is automatically
12 // made available to LLVM based compilers by loading the Polly shared library
13 // into such a compiler.
14 //
15 // The Polly optimizer is made available by executing a static constructor that
16 // registers the individual Polly passes in the LLVM pass manager builder. The
17 // passes are registered such that the default behaviour of the compiler is not
18 // changed, but that the flag '-polly' provided at optimization level '-O3'
19 // enables additional polyhedral optimizations.
20 //===----------------------------------------------------------------------===//
21 
22 #include "polly/RegisterPasses.h"
23 #include "polly/Canonicalization.h"
24 #include "polly/CodeGen/CodeGeneration.h"
25 #include "polly/Dependences.h"
26 #include "polly/LinkAllPasses.h"
27 #include "polly/Options.h"
28 #include "polly/ScopDetection.h"
29 #include "polly/ScopInfo.h"
30 #include "polly/TempScopInfo.h"
31 #include "llvm/Analysis/CFGPrinter.h"
32 #include "llvm/IR/LegacyPassManager.h"
33 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
34 #include "llvm/Transforms/Scalar.h"
35 #include "llvm/Transforms/Vectorize.h"
36 
37 using namespace llvm;
38 using namespace polly;
39 
40 cl::OptionCategory PollyCategory("Polly Options",
41                                  "Configure the polly loop optimizer");
42 
43 static cl::opt<bool>
44     PollyEnabled("polly", cl::desc("Enable the polly optimizer (only at -O3)"),
45                  cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
46 
47 enum OptimizerChoice {
48   OPTIMIZER_NONE,
49 #ifdef PLUTO_FOUND
50   OPTIMIZER_PLUTO,
51 #endif
52   OPTIMIZER_ISL
53 };
54 
55 static cl::opt<OptimizerChoice> Optimizer(
56     "polly-optimizer", cl::desc("Select the scheduling optimizer"),
57     cl::values(clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),
58 #ifdef PLUTO_FOUND
59                clEnumValN(OPTIMIZER_PLUTO, "pluto",
60                           "The Pluto scheduling optimizer"),
61 #endif
62                clEnumValN(OPTIMIZER_ISL, "isl", "The isl scheduling optimizer"),
63                clEnumValEnd),
64     cl::Hidden, cl::init(OPTIMIZER_ISL), cl::ZeroOrMore,
65     cl::cat(PollyCategory));
66 
67 CodeGenChoice polly::PollyCodeGenChoice;
68 static cl::opt<CodeGenChoice, true> XCodeGenerator(
69     "polly-code-generator", cl::desc("Select the code generator"),
70     cl::values(clEnumValN(CODEGEN_ISL, "isl", "isl code generator"),
71                clEnumValN(CODEGEN_NONE, "none", "no code generation"),
72                clEnumValEnd),
73     cl::Hidden, cl::location(PollyCodeGenChoice), cl::init(CODEGEN_ISL),
74     cl::ZeroOrMore, cl::cat(PollyCategory));
75 
76 VectorizerChoice polly::PollyVectorizerChoice;
77 static cl::opt<polly::VectorizerChoice, true> Vectorizer(
78     "polly-vectorizer", cl::desc("Select the vectorization strategy"),
79     cl::values(clEnumValN(polly::VECTORIZER_NONE, "none", "No Vectorization"),
80                clEnumValN(polly::VECTORIZER_POLLY, "polly",
81                           "Polly internal vectorizer"),
82                clEnumValN(polly::VECTORIZER_UNROLL_ONLY, "unroll-only",
83                           "Only grouped unroll the vectorize candidate loops"),
84                clEnumValN(polly::VECTORIZER_BB, "bb",
85                           "The Basic Block vectorizer driven by Polly"),
86                clEnumValEnd),
87     cl::location(PollyVectorizerChoice), cl::init(polly::VECTORIZER_NONE),
88     cl::ZeroOrMore, cl::cat(PollyCategory));
89 
90 static cl::opt<bool> ImportJScop(
91     "polly-import",
92     cl::desc("Export the polyhedral description of the detected Scops"),
93     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
94 
95 static cl::opt<bool> ExportJScop(
96     "polly-export",
97     cl::desc("Export the polyhedral description of the detected Scops"),
98     cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
99 
100 static cl::opt<bool> DeadCodeElim("polly-run-dce",
101                                   cl::desc("Run the dead code elimination"),
102                                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
103                                   cl::cat(PollyCategory));
104 
105 static cl::opt<bool> PollyViewer(
106     "polly-show",
107     cl::desc("Highlight the code regions that will be optimized in a "
108              "(CFG BBs and LLVM-IR instructions)"),
109     cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
110 
111 static cl::opt<bool> PollyOnlyViewer(
112     "polly-show-only",
113     cl::desc("Highlight the code regions that will be optimized in "
114              "a (CFG only BBs)"),
115     cl::init(false), cl::cat(PollyCategory));
116 
117 static cl::opt<bool>
118     PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"),
119                  cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"),
120                  cl::init(false), cl::cat(PollyCategory));
121 
122 static cl::opt<bool> PollyOnlyPrinter(
123     "polly-dot-only",
124     cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden,
125     cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"),
126     cl::init(false), cl::cat(PollyCategory));
127 
128 static cl::opt<bool>
129     CFGPrinter("polly-view-cfg",
130                cl::desc("Show the Polly CFG right after code generation"),
131                cl::Hidden, cl::init(false), cl::cat(PollyCategory));
132 
133 bool polly::PollyAnnotateAliasScopes;
134 static cl::opt<bool, true> XPollyAnnotateAliasScopes(
135     "polly-annotate-alias-scopes",
136     cl::desc("Annotate memory instructions with alias scopes"),
137     cl::location(PollyAnnotateAliasScopes), cl::init(true), cl::ZeroOrMore,
138     cl::cat(PollyCategory));
139 
140 namespace polly {
141 void initializePollyPasses(PassRegistry &Registry) {
142   initializeIslCodeGenerationPass(Registry);
143   initializeCodePreparationPass(Registry);
144   initializeDeadCodeElimPass(Registry);
145   initializeDependencesPass(Registry);
146   initializeIndependentBlocksPass(Registry);
147   initializeJSONExporterPass(Registry);
148   initializeJSONImporterPass(Registry);
149   initializeIslAstInfoPass(Registry);
150   initializeIslScheduleOptimizerPass(Registry);
151   initializePollyCanonicalizePass(Registry);
152   initializeScopDetectionPass(Registry);
153   initializeScopInfoPass(Registry);
154   initializeTempScopInfoPass(Registry);
155 }
156 
157 /// @brief Register Polly passes such that they form a polyhedral optimizer.
158 ///
159 /// The individual Polly passes are registered in the pass manager such that
160 /// they form a full polyhedral optimizer. The flow of the optimizer starts with
161 /// a set of preparing transformations that canonicalize the LLVM-IR such that
162 /// the LLVM-IR is easier for us to understand and to optimizes. On the
163 /// canonicalized LLVM-IR we first run the ScopDetection pass, which detects
164 /// static control flow regions. Those regions are then translated by the
165 /// ScopInfo pass into a polyhedral representation. As a next step, a scheduling
166 /// optimizer is run on the polyhedral representation and finally the optimized
167 /// polyhedral representation is code generated back to LLVM-IR.
168 ///
169 /// Besides this core functionality, we optionally schedule passes that provide
170 /// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that
171 /// allow the export/import of the polyhedral representation
172 /// (JSCON[Exporter|Importer]) or that show the cfg after code generation.
173 ///
174 /// For certain parts of the Polly optimizer, several alternatives are provided:
175 ///
176 /// As scheduling optimizer we support PLUTO
177 /// (http://pluto-compiler.sourceforge.net) as well as the isl scheduling
178 /// optimizer (http://freecode.com/projects/isl). The isl optimizer is the
179 /// default optimizer.
180 /// It is also possible to run Polly with no optimizer. This mode is mainly
181 /// provided to analyze the run and compile time changes caused by the
182 /// scheduling optimizer.
183 ///
184 /// Polly supports the isl internal code generator.
185 void registerPollyPasses(llvm::legacy::PassManagerBase &PM) {
186   registerCanonicalicationPasses(PM);
187 
188   PM.add(polly::createScopInfoPass());
189 
190   if (PollyViewer)
191     PM.add(polly::createDOTViewerPass());
192   if (PollyOnlyViewer)
193     PM.add(polly::createDOTOnlyViewerPass());
194   if (PollyPrinter)
195     PM.add(polly::createDOTPrinterPass());
196   if (PollyOnlyPrinter)
197     PM.add(polly::createDOTOnlyPrinterPass());
198 
199   if (ImportJScop)
200     PM.add(polly::createJSONImporterPass());
201 
202   if (DeadCodeElim)
203     PM.add(polly::createDeadCodeElimPass());
204 
205   switch (Optimizer) {
206   case OPTIMIZER_NONE:
207     break; /* Do nothing */
208 
209 #ifdef PLUTO_FOUND
210   case OPTIMIZER_PLUTO:
211     PM.add(polly::createPlutoOptimizerPass());
212     break;
213 #endif
214 
215   case OPTIMIZER_ISL:
216     PM.add(polly::createIslScheduleOptimizerPass());
217     break;
218   }
219 
220   if (ExportJScop)
221     PM.add(polly::createJSONExporterPass());
222 
223   switch (PollyCodeGenChoice) {
224   case CODEGEN_ISL:
225     PM.add(polly::createIslCodeGenerationPass());
226     break;
227   case CODEGEN_NONE:
228     break;
229   }
230 
231   if (CFGPrinter)
232     PM.add(llvm::createCFGPrinterPass());
233 }
234 
235 static bool shouldEnablePolly() {
236   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)
237     PollyTrackFailures = true;
238 
239   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
240       ExportJScop || ImportJScop)
241     PollyEnabled = true;
242 
243   return PollyEnabled;
244 }
245 
246 static void
247 registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
248                                    llvm::legacy::PassManagerBase &PM) {
249   if (!polly::shouldEnablePolly())
250     return;
251 
252   polly::registerPollyPasses(PM);
253 }
254 
255 /// @brief Register Polly to be available as an optimizer
256 ///
257 /// We currently register Polly such that it runs as early as possible. This has
258 /// several implications:
259 ///
260 ///   1) We need to schedule more canonicalization passes
261 ///
262 ///   As nothing is run before Polly, it is necessary to run a set of preparing
263 ///   transformations before Polly to canonicalize the LLVM-IR and to allow
264 ///   Polly to detect and understand the code.
265 ///
266 ///   2) LICM and LoopIdiom pass have not yet been run
267 ///
268 ///   Loop invariant code motion as well as the loop idiom recognition pass make
269 ///   it more difficult for Polly to transform code. LICM may introduce
270 ///   additional data dependences that are hard to eliminate and the loop idiom
271 ///   recognition pass may introduce calls to memset that we currently do not
272 ///   understand. By running Polly early enough (meaning before these passes) we
273 ///   avoid difficulties that may be introduced by these passes.
274 ///
275 ///   3) We get the full -O3 optimization sequence after Polly
276 ///
277 ///   The LLVM-IR that is generated by Polly has been optimized on a high level,
278 ///   but it may be rather inefficient on the lower/scalar level. By scheduling
279 ///   Polly before all other passes, we have the full sequence of -O3
280 ///   optimizations behind us, such that inefficiencies on the low level can
281 ///   be optimized away.
282 static llvm::RegisterStandardPasses
283     RegisterPollyOptimizer(llvm::PassManagerBuilder::EP_EarlyAsPossible,
284                            registerPollyEarlyAsPossiblePasses);
285 }
286