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