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