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/CodeGen/CodegenCleanup.h" 26 #include "polly/DependenceInfo.h" 27 #include "polly/FlattenSchedule.h" 28 #include "polly/LinkAllPasses.h" 29 #include "polly/Options.h" 30 #include "polly/PolyhedralInfo.h" 31 #include "polly/ScopDetection.h" 32 #include "polly/ScopInfo.h" 33 #include "llvm/Analysis/CFGPrinter.h" 34 #include "llvm/IR/LegacyPassManager.h" 35 #include "llvm/Transforms/IPO.h" 36 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 37 #include "llvm/Transforms/Scalar.h" 38 #include "llvm/Transforms/Vectorize.h" 39 40 using namespace llvm; 41 using namespace polly; 42 43 cl::OptionCategory PollyCategory("Polly Options", 44 "Configure the polly loop optimizer"); 45 46 static cl::opt<bool> 47 PollyEnabled("polly", cl::desc("Enable the polly optimizer (only at -O3)"), 48 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 49 50 static cl::opt<bool> PollyDetectOnly( 51 "polly-only-scop-detection", 52 cl::desc("Only run scop detection, but no other optimizations"), 53 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 54 55 enum PassPositionChoice { 56 POSITION_EARLY, 57 POSITION_AFTER_LOOPOPT, 58 POSITION_BEFORE_VECTORIZER 59 }; 60 61 enum OptimizerChoice { OPTIMIZER_NONE, OPTIMIZER_ISL }; 62 63 static cl::opt<PassPositionChoice> PassPosition( 64 "polly-position", cl::desc("Where to run polly in the pass pipeline"), 65 cl::values( 66 clEnumValN(POSITION_EARLY, "early", "Before everything"), 67 clEnumValN(POSITION_AFTER_LOOPOPT, "after-loopopt", 68 "After the loop optimizer (but within the inline cycle)"), 69 clEnumValN(POSITION_BEFORE_VECTORIZER, "before-vectorizer", 70 "Right before the vectorizer"), 71 clEnumValEnd), 72 cl::Hidden, cl::init(POSITION_EARLY), cl::ZeroOrMore, 73 cl::cat(PollyCategory)); 74 75 static cl::opt<OptimizerChoice> Optimizer( 76 "polly-optimizer", cl::desc("Select the scheduling optimizer"), 77 cl::values(clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"), 78 clEnumValN(OPTIMIZER_ISL, "isl", "The isl scheduling optimizer"), 79 clEnumValEnd), 80 cl::Hidden, cl::init(OPTIMIZER_ISL), cl::ZeroOrMore, 81 cl::cat(PollyCategory)); 82 83 enum CodeGenChoice { CODEGEN_FULL, CODEGEN_AST, CODEGEN_NONE }; 84 static cl::opt<CodeGenChoice> CodeGeneration( 85 "polly-code-generation", cl::desc("How much code-generation to perform"), 86 cl::values(clEnumValN(CODEGEN_FULL, "full", "AST and IR generation"), 87 clEnumValN(CODEGEN_AST, "ast", "Only AST generation"), 88 clEnumValN(CODEGEN_NONE, "none", "No code generation"), 89 clEnumValEnd), 90 cl::Hidden, cl::init(CODEGEN_FULL), cl::ZeroOrMore, cl::cat(PollyCategory)); 91 92 enum TargetChoice { TARGET_CPU, TARGET_GPU }; 93 static cl::opt<TargetChoice> 94 Target("polly-target", cl::desc("The hardware to target"), 95 cl::values(clEnumValN(TARGET_CPU, "cpu", "generate CPU code"), 96 #ifdef GPU_CODEGEN 97 clEnumValN(TARGET_GPU, "gpu", "generate GPU code"), 98 #endif 99 clEnumValEnd), 100 cl::init(TARGET_CPU), cl::ZeroOrMore, cl::cat(PollyCategory)); 101 102 VectorizerChoice polly::PollyVectorizerChoice; 103 static cl::opt<polly::VectorizerChoice, true> Vectorizer( 104 "polly-vectorizer", cl::desc("Select the vectorization strategy"), 105 cl::values( 106 clEnumValN(polly::VECTORIZER_NONE, "none", "No Vectorization"), 107 clEnumValN(polly::VECTORIZER_POLLY, "polly", 108 "Polly internal vectorizer"), 109 clEnumValN(polly::VECTORIZER_STRIPMINE, "stripmine", 110 "Strip-mine outer loops for the loop-vectorizer to trigger"), 111 clEnumValEnd), 112 cl::location(PollyVectorizerChoice), cl::init(polly::VECTORIZER_NONE), 113 cl::ZeroOrMore, cl::cat(PollyCategory)); 114 115 static cl::opt<bool> ImportJScop( 116 "polly-import", 117 cl::desc("Export the polyhedral description of the detected Scops"), 118 cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 119 120 static cl::opt<bool> ExportJScop( 121 "polly-export", 122 cl::desc("Export the polyhedral description of the detected Scops"), 123 cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 124 125 static cl::opt<bool> DeadCodeElim("polly-run-dce", 126 cl::desc("Run the dead code elimination"), 127 cl::Hidden, cl::init(false), cl::ZeroOrMore, 128 cl::cat(PollyCategory)); 129 130 static cl::opt<bool> PollyViewer( 131 "polly-show", 132 cl::desc("Highlight the code regions that will be optimized in a " 133 "(CFG BBs and LLVM-IR instructions)"), 134 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); 135 136 static cl::opt<bool> PollyOnlyViewer( 137 "polly-show-only", 138 cl::desc("Highlight the code regions that will be optimized in " 139 "a (CFG only BBs)"), 140 cl::init(false), cl::cat(PollyCategory)); 141 142 static cl::opt<bool> 143 PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"), 144 cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"), 145 cl::init(false), cl::cat(PollyCategory)); 146 147 static cl::opt<bool> PollyOnlyPrinter( 148 "polly-dot-only", 149 cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden, 150 cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"), 151 cl::init(false), cl::cat(PollyCategory)); 152 153 static cl::opt<bool> 154 CFGPrinter("polly-view-cfg", 155 cl::desc("Show the Polly CFG right after code generation"), 156 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 157 158 static cl::opt<bool> 159 EnablePolyhedralInfo("polly-enable-polyhedralinfo", 160 cl::desc("Enable polyhedral interface of Polly"), 161 cl::Hidden, cl::init(false), cl::cat(PollyCategory)); 162 163 namespace polly { 164 void initializePollyPasses(PassRegistry &Registry) { 165 initializeCodeGenerationPass(Registry); 166 167 #ifdef GPU_CODEGEN 168 initializePPCGCodeGenerationPass(Registry); 169 #endif 170 initializeCodePreparationPass(Registry); 171 initializeDeadCodeElimPass(Registry); 172 initializeDependenceInfoPass(Registry); 173 initializeDependenceInfoWrapperPassPass(Registry); 174 initializeJSONExporterPass(Registry); 175 initializeJSONImporterPass(Registry); 176 initializeIslAstInfoPass(Registry); 177 initializeIslScheduleOptimizerPass(Registry); 178 initializePollyCanonicalizePass(Registry); 179 initializePolyhedralInfoPass(Registry); 180 initializeScopDetectionPass(Registry); 181 initializeScopInfoRegionPassPass(Registry); 182 initializeScopInfoWrapperPassPass(Registry); 183 initializeCodegenCleanupPass(Registry); 184 initializeFlattenSchedulePass(Registry); 185 } 186 187 /// Register Polly passes such that they form a polyhedral optimizer. 188 /// 189 /// The individual Polly passes are registered in the pass manager such that 190 /// they form a full polyhedral optimizer. The flow of the optimizer starts with 191 /// a set of preparing transformations that canonicalize the LLVM-IR such that 192 /// the LLVM-IR is easier for us to understand and to optimizes. On the 193 /// canonicalized LLVM-IR we first run the ScopDetection pass, which detects 194 /// static control flow regions. Those regions are then translated by the 195 /// ScopInfo pass into a polyhedral representation. As a next step, a scheduling 196 /// optimizer is run on the polyhedral representation and finally the optimized 197 /// polyhedral representation is code generated back to LLVM-IR. 198 /// 199 /// Besides this core functionality, we optionally schedule passes that provide 200 /// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that 201 /// allow the export/import of the polyhedral representation 202 /// (JSCON[Exporter|Importer]) or that show the cfg after code generation. 203 /// 204 /// For certain parts of the Polly optimizer, several alternatives are provided: 205 /// 206 /// As scheduling optimizer we support the isl scheduling optimizer 207 /// (http://freecode.com/projects/isl). 208 /// It is also possible to run Polly with no optimizer. This mode is mainly 209 /// provided to analyze the run and compile time changes caused by the 210 /// scheduling optimizer. 211 /// 212 /// Polly supports the isl internal code generator. 213 void registerPollyPasses(llvm::legacy::PassManagerBase &PM) { 214 PM.add(polly::createScopDetectionPass()); 215 216 if (PollyDetectOnly) 217 return; 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 PM.add(polly::createScopInfoRegionPassPass()); 229 if (EnablePolyhedralInfo) 230 PM.add(polly::createPolyhedralInfoPass()); 231 232 if (ImportJScop) 233 PM.add(polly::createJSONImporterPass()); 234 235 if (DeadCodeElim) 236 PM.add(polly::createDeadCodeElimPass()); 237 238 if (Target == TARGET_GPU) { 239 // GPU generation provides its own scheduling optimization strategy. 240 } else { 241 switch (Optimizer) { 242 case OPTIMIZER_NONE: 243 break; /* Do nothing */ 244 245 case OPTIMIZER_ISL: 246 PM.add(polly::createIslScheduleOptimizerPass()); 247 break; 248 } 249 } 250 251 if (ExportJScop) 252 PM.add(polly::createJSONExporterPass()); 253 254 if (Target == TARGET_GPU) { 255 #ifdef GPU_CODEGEN 256 PM.add(polly::createPPCGCodeGenerationPass()); 257 #endif 258 } else { 259 switch (CodeGeneration) { 260 case CODEGEN_AST: 261 PM.add(polly::createIslAstInfoPass()); 262 break; 263 case CODEGEN_FULL: 264 PM.add(polly::createCodeGenerationPass()); 265 break; 266 case CODEGEN_NONE: 267 break; 268 } 269 } 270 271 // FIXME: This dummy ModulePass keeps some programs from miscompiling, 272 // probably some not correctly preserved analyses. It acts as a barrier to 273 // force all analysis results to be recomputed. 274 PM.add(createBarrierNoopPass()); 275 276 if (CFGPrinter) 277 PM.add(llvm::createCFGPrinterPass()); 278 279 if (Target == TARGET_GPU) { 280 // Invariant load hoisting not yet supported by GPU code generation. 281 PollyInvariantLoadHoisting = false; 282 } 283 } 284 285 static bool shouldEnablePolly() { 286 if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer) 287 PollyTrackFailures = true; 288 289 if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer || 290 ExportJScop || ImportJScop) 291 PollyEnabled = true; 292 293 return PollyEnabled; 294 } 295 296 static void 297 registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder, 298 llvm::legacy::PassManagerBase &PM) { 299 if (!polly::shouldEnablePolly()) 300 return; 301 302 if (PassPosition != POSITION_EARLY) 303 return; 304 305 registerCanonicalicationPasses(PM); 306 polly::registerPollyPasses(PM); 307 } 308 309 static void 310 registerPollyLoopOptimizerEndPasses(const llvm::PassManagerBuilder &Builder, 311 llvm::legacy::PassManagerBase &PM) { 312 if (!polly::shouldEnablePolly()) 313 return; 314 315 if (PassPosition != POSITION_AFTER_LOOPOPT) 316 return; 317 318 PM.add(polly::createCodePreparationPass()); 319 polly::registerPollyPasses(PM); 320 PM.add(createCodegenCleanupPass()); 321 } 322 323 static void 324 registerPollyScalarOptimizerLatePasses(const llvm::PassManagerBuilder &Builder, 325 llvm::legacy::PassManagerBase &PM) { 326 if (!polly::shouldEnablePolly()) 327 return; 328 329 if (PassPosition != POSITION_BEFORE_VECTORIZER) 330 return; 331 332 PM.add(polly::createCodePreparationPass()); 333 polly::registerPollyPasses(PM); 334 PM.add(createCodegenCleanupPass()); 335 } 336 337 /// Register Polly to be available as an optimizer 338 /// 339 /// 340 /// We can currently run Polly at three different points int the pass manager. 341 /// a) very early, b) after the canonicalizing loop transformations and c) right 342 /// before the vectorizer. 343 /// 344 /// The default is currently a), to register Polly such that it runs as early as 345 /// possible. This has several implications: 346 /// 347 /// 1) We need to schedule more canonicalization passes 348 /// 349 /// As nothing is run before Polly, it is necessary to run a set of preparing 350 /// transformations before Polly to canonicalize the LLVM-IR and to allow 351 /// Polly to detect and understand the code. 352 /// 353 /// 2) LICM and LoopIdiom pass have not yet been run 354 /// 355 /// Loop invariant code motion as well as the loop idiom recognition pass make 356 /// it more difficult for Polly to transform code. LICM may introduce 357 /// additional data dependences that are hard to eliminate and the loop idiom 358 /// recognition pass may introduce calls to memset that we currently do not 359 /// understand. By running Polly early enough (meaning before these passes) we 360 /// avoid difficulties that may be introduced by these passes. 361 /// 362 /// 3) We get the full -O3 optimization sequence after Polly 363 /// 364 /// The LLVM-IR that is generated by Polly has been optimized on a high level, 365 /// but it may be rather inefficient on the lower/scalar level. By scheduling 366 /// Polly before all other passes, we have the full sequence of -O3 367 /// optimizations behind us, such that inefficiencies on the low level can 368 /// be optimized away. 369 /// 370 /// We are currently evaluating the benefit or running Polly at position b) or 371 /// c). b) is likely to early as it interacts with the inliner. c) is nice 372 /// as everything is fully inlined and canonicalized, but we need to be able 373 /// to handle LICMed code to make it useful. 374 static llvm::RegisterStandardPasses RegisterPollyOptimizerEarly( 375 llvm::PassManagerBuilder::EP_ModuleOptimizerEarly, 376 registerPollyEarlyAsPossiblePasses); 377 378 static llvm::RegisterStandardPasses 379 RegisterPollyOptimizerLoopEnd(llvm::PassManagerBuilder::EP_LoopOptimizerEnd, 380 registerPollyLoopOptimizerEndPasses); 381 382 static llvm::RegisterStandardPasses RegisterPollyOptimizerScalarLate( 383 llvm::PassManagerBuilder::EP_VectorizerStart, 384 registerPollyScalarOptimizerLatePasses); 385 } // namespace polly 386