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/BlockGenerators.h"
25 #include "polly/CodeGen/Cloog.h"
26 #include "polly/CodeGen/CodeGeneration.h"
27 #include "polly/Dependences.h"
28 #include "polly/LinkAllPasses.h"
29 #include "polly/Options.h"
30 #include "polly/ScopDetection.h"
31 #include "polly/ScopInfo.h"
32 #include "polly/TempScopInfo.h"
33 #include "llvm/Analysis/CFGPrinter.h"
34 #include "llvm/PassManager.h"
35 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
36 #include "llvm/Transforms/Scalar.h"
37 #include "llvm/Transforms/Vectorize.h"
38 
39 using namespace llvm;
40 using namespace polly;
41 
42 cl::OptionCategory PollyCategory("Polly Options",
43                                  "Configure the polly loop optimizer");
44 
45 static cl::opt<bool>
46 PollyEnabled("polly", cl::desc("Enable the polly optimizer (only at -O3)"),
47              cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
48 
49 enum OptimizerChoice {
50   OPTIMIZER_NONE,
51 #ifdef PLUTO_FOUND
52   OPTIMIZER_PLUTO,
53 #endif
54 #ifdef SCOPLIB_FOUND
55   OPTIMIZER_POCC,
56 #endif
57   OPTIMIZER_ISL
58 };
59 
60 static cl::opt<OptimizerChoice> Optimizer(
61     "polly-optimizer", cl::desc("Select the scheduling optimizer"),
62     cl::values(
63         clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),
64 #ifdef PLUTO_FOUND
65         clEnumValN(OPTIMIZER_PLUTO, "pluto", "The Pluto scheduling optimizer"),
66 #endif
67 #ifdef SCOPLIB_FOUND
68         clEnumValN(OPTIMIZER_POCC, "pocc", "The PoCC scheduling optimizer"),
69 #endif
70         clEnumValN(OPTIMIZER_ISL, "isl", "The isl scheduling optimizer"),
71         clEnumValEnd),
72     cl::Hidden, cl::init(OPTIMIZER_ISL), cl::ZeroOrMore,
73     cl::cat(PollyCategory));
74 
75 enum CodeGenChoice {
76 #ifdef CLOOG_FOUND
77   CODEGEN_CLOOG,
78 #endif
79   CODEGEN_ISL,
80   CODEGEN_NONE
81 };
82 
83 #ifdef CLOOG_FOUND
84 enum CodeGenChoice DefaultCodeGen = CODEGEN_CLOOG;
85 #else
86 enum CodeGenChoice DefaultCodeGen = CODEGEN_ISL;
87 #endif
88 
89 static cl::opt<CodeGenChoice> CodeGenerator(
90     "polly-code-generator", cl::desc("Select the code generator"),
91     cl::values(
92 #ifdef CLOOG_FOUND
93         clEnumValN(CODEGEN_CLOOG, "cloog", "CLooG"),
94 #endif
95         clEnumValN(CODEGEN_ISL, "isl", "isl code generator"),
96         clEnumValN(CODEGEN_NONE, "none", "no code generation"), clEnumValEnd),
97     cl::Hidden, cl::init(DefaultCodeGen), cl::ZeroOrMore,
98     cl::cat(PollyCategory));
99 
100 VectorizerChoice polly::PollyVectorizerChoice;
101 static cl::opt<polly::VectorizerChoice, true> Vectorizer(
102     "polly-vectorizer", cl::desc("Select the vectorization strategy"),
103     cl::values(clEnumValN(polly::VECTORIZER_NONE, "none", "No Vectorization"),
104                clEnumValN(polly::VECTORIZER_POLLY, "polly",
105                           "Polly internal vectorizer"),
106                clEnumValN(polly::VECTORIZER_UNROLL_ONLY, "unroll-only",
107                           "Only grouped unroll the vectorize candidate loops"),
108                clEnumValN(polly::VECTORIZER_BB, "bb",
109                           "The Basic Block vectorizer driven by Polly"),
110                clEnumValEnd),
111     cl::location(PollyVectorizerChoice), cl::init(polly::VECTORIZER_NONE),
112     cl::ZeroOrMore, cl::cat(PollyCategory));
113 
114 static cl::opt<bool>
115 ImportJScop("polly-import",
116             cl::desc("Export the polyhedral description of the detected Scops"),
117             cl::Hidden, cl::init(false), cl::ZeroOrMore,
118             cl::cat(PollyCategory));
119 
120 static cl::opt<bool>
121 ExportJScop("polly-export",
122             cl::desc("Export the polyhedral description of the detected Scops"),
123             cl::Hidden, cl::init(false), cl::ZeroOrMore,
124             cl::cat(PollyCategory));
125 
126 static cl::opt<bool> DeadCodeElim("polly-run-dce",
127                                   cl::desc("Run the dead code elimination"),
128                                   cl::Hidden, cl::init(true), cl::ZeroOrMore,
129                                   cl::cat(PollyCategory));
130 
131 static cl::opt<bool>
132 PollyViewer("polly-show",
133             cl::desc("Highlight the code regions that will be optimized in a "
134                      "(CFG BBs and LLVM-IR instructions)"),
135             cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
136 
137 static cl::opt<bool>
138 PollyOnlyViewer("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 namespace polly {
160 void initializePollyPasses(PassRegistry &Registry) {
161 #ifdef CLOOG_FOUND
162   initializeCloogInfoPass(Registry);
163   initializeCodeGenerationPass(Registry);
164 #endif
165   initializeIslCodeGenerationPass(Registry);
166   initializeCodePreparationPass(Registry);
167   initializeDeadCodeElimPass(Registry);
168   initializeDependencesPass(Registry);
169   initializeIndependentBlocksPass(Registry);
170   initializeJSONExporterPass(Registry);
171   initializeJSONImporterPass(Registry);
172   initializeIslAstInfoPass(Registry);
173   initializeIslScheduleOptimizerPass(Registry);
174 #ifdef SCOPLIB_FOUND
175   initializePoccPass(Registry);
176 #endif
177   initializePollyIndVarSimplifyPass(Registry);
178   initializePollyCanonicalizePass(Registry);
179   initializeScopDetectionPass(Registry);
180   initializeScopInfoPass(Registry);
181   initializeTempScopInfoPass(Registry);
182 }
183 
184 /// @brief Register Polly passes such that they form a polyhedral optimizer.
185 ///
186 /// The individual Polly passes are registered in the pass manager such that
187 /// they form a full polyhedral optimizer. The flow of the optimizer starts with
188 /// a set of preparing transformations that canonicalize the LLVM-IR such that
189 /// the LLVM-IR is easier for us to understand and to optimizes. On the
190 /// canonicalized LLVM-IR we first run the ScopDetection pass, which detects
191 /// static control flow regions. Those regions are then translated by the
192 /// ScopInfo pass into a polyhedral representation. As a next step, a scheduling
193 /// optimizer is run on the polyhedral representation and finally the optimized
194 /// polyhedral representation is code generated back to LLVM-IR.
195 ///
196 /// Besides this core functionality, we optionally schedule passes that provide
197 /// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that
198 /// allow the export/import of the polyhedral representation
199 /// (JSCON[Exporter|Importer]) or that show the cfg after code generation.
200 ///
201 /// For certain parts of the Polly optimizer, several alternatives are provided:
202 ///
203 /// As scheduling optimizer we support PoCC (http://pocc.sourceforge.net), PLUTO
204 /// (http://pluto-compiler.sourceforge.net) as well as the isl scheduling
205 /// optimizer (http://freecode.com/projects/isl). The isl optimizer is the
206 /// default optimizer.
207 /// It is also possible to run Polly with no optimizer. This mode is mainly
208 /// provided to analyze the run and compile time changes caused by the
209 /// scheduling optimizer.
210 ///
211 /// Polly supports both CLooG (http://www.cloog.org) as well as the isl internal
212 /// code generator. For the moment, the CLooG code generator is enabled by
213 /// default.
214 static void registerPollyPasses(llvm::PassManagerBase &PM) {
215   registerCanonicalicationPasses(PM, SCEVCodegen);
216 
217   PM.add(polly::createScopInfoPass());
218 
219   if (PollyViewer)
220     PM.add(polly::createDOTViewerPass());
221   if (PollyOnlyViewer)
222     PM.add(polly::createDOTOnlyViewerPass());
223   if (PollyPrinter)
224     PM.add(polly::createDOTPrinterPass());
225   if (PollyOnlyPrinter)
226     PM.add(polly::createDOTOnlyPrinterPass());
227 
228   if (ImportJScop)
229     PM.add(polly::createJSONImporterPass());
230 
231   if (DeadCodeElim)
232     PM.add(polly::createDeadCodeElimPass());
233 
234   switch (Optimizer) {
235   case OPTIMIZER_NONE:
236     break; /* Do nothing */
237 
238 #ifdef SCOPLIB_FOUND
239   case OPTIMIZER_POCC:
240     PM.add(polly::createPoccPass());
241     break;
242 #endif
243 
244 #ifdef PLUTO_FOUND
245   case OPTIMIZER_PLUTO:
246     PM.add(polly::createPlutoOptimizerPass());
247     break;
248 #endif
249 
250   case OPTIMIZER_ISL:
251     PM.add(polly::createIslScheduleOptimizerPass());
252     break;
253   }
254 
255   if (ExportJScop)
256     PM.add(polly::createJSONExporterPass());
257 
258   switch (CodeGenerator) {
259 #ifdef CLOOG_FOUND
260   case CODEGEN_CLOOG:
261     PM.add(polly::createCodeGenerationPass());
262     if (PollyVectorizerChoice == VECTORIZER_BB) {
263       VectorizeConfig C;
264       C.FastDep = true;
265       PM.add(createBBVectorizePass(C));
266     }
267     break;
268 #endif
269   case CODEGEN_ISL:
270     PM.add(polly::createIslCodeGenerationPass());
271     break;
272   case CODEGEN_NONE:
273     break;
274   }
275 
276   if (CFGPrinter)
277     PM.add(llvm::createCFGPrinterPass());
278 }
279 
280 static bool shouldEnablePolly() {
281   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)
282     PollyTrackFailures = true;
283 
284   if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
285       ExportJScop || ImportJScop)
286     PollyEnabled = true;
287 
288   return PollyEnabled;
289 }
290 
291 static void
292 registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
293                                    llvm::PassManagerBase &PM) {
294   if (!polly::shouldEnablePolly())
295     return;
296 
297   polly::registerPollyPasses(PM);
298 }
299 
300 /// @brief Register Polly to be available as an optimizer
301 ///
302 /// We currently register Polly such that it runs as early as possible. This has
303 /// several implications:
304 ///
305 ///   1) We need to schedule more canonicalization passes
306 ///
307 ///   As nothing is run before Polly, it is necessary to run a set of preparing
308 ///   transformations before Polly to canonicalize the LLVM-IR and to allow
309 ///   Polly to detect and understand the code.
310 ///
311 ///   2) LICM and LoopIdiom pass have not yet been run
312 ///
313 ///   Loop invariant code motion as well as the loop idiom recognition pass make
314 ///   it more difficult for Polly to transform code. LICM may introduce
315 ///   additional data dependences that are hard to eliminate and the loop idiom
316 ///   recognition pass may introduce calls to memset that we currently do not
317 ///   understand. By running Polly early enough (meaning before these passes) we
318 ///   avoid difficulties that may be introduced by these passes.
319 ///
320 ///   3) We get the full -O3 optimization sequence after Polly
321 ///
322 ///   The LLVM-IR that is generated by Polly has been optimized on a high level,
323 ///   but it may be rather inefficient on the lower/scalar level. By scheduling
324 ///   Polly before all other passes, we have the full sequence of -O3
325 ///   optimizations behind us, such that inefficiencies on the low level can
326 ///   be optimized away.
327 static llvm::RegisterStandardPasses
328 RegisterPollyOptimizer(llvm::PassManagerBuilder::EP_EarlyAsPossible,
329                        registerPollyEarlyAsPossiblePasses);
330 }
331