1 //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// 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 /// \file 10 /// 11 /// This file is just a split of the code that logically belongs in opt.cpp but 12 /// that includes the new pass manager headers. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "NewPMDriver.h" 17 #include "Debugify.h" 18 #include "PassPrinters.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Analysis/AliasAnalysis.h" 21 #include "llvm/Analysis/CGSCCPassManager.h" 22 #include "llvm/Bitcode/BitcodeWriterPass.h" 23 #include "llvm/Config/llvm-config.h" 24 #include "llvm/IR/Dominators.h" 25 #include "llvm/IR/IRPrintingPasses.h" 26 #include "llvm/IR/LLVMContext.h" 27 #include "llvm/IR/Module.h" 28 #include "llvm/IR/PassManager.h" 29 #include "llvm/IR/Verifier.h" 30 #include "llvm/Passes/PassBuilder.h" 31 #include "llvm/Passes/PassPlugin.h" 32 #include "llvm/Passes/StandardInstrumentations.h" 33 #include "llvm/Support/CommandLine.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/ToolOutputFile.h" 36 #include "llvm/Target/TargetMachine.h" 37 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 38 #include "llvm/Transforms/Scalar/LoopPassManager.h" 39 40 using namespace llvm; 41 using namespace opt_tool; 42 43 static cl::opt<bool> 44 DebugPM("debug-pass-manager", cl::Hidden, 45 cl::desc("Print pass management debugging information")); 46 47 static cl::list<std::string> 48 PassPlugins("load-pass-plugin", 49 cl::desc("Load passes from plugin library")); 50 51 // This flag specifies a textual description of the alias analysis pipeline to 52 // use when querying for aliasing information. It only works in concert with 53 // the "passes" flag above. 54 static cl::opt<std::string> 55 AAPipeline("aa-pipeline", 56 cl::desc("A textual description of the alias analysis " 57 "pipeline for handling managed aliasing queries"), 58 cl::Hidden); 59 60 /// {{@ These options accept textual pipeline descriptions which will be 61 /// inserted into default pipelines at the respective extension points 62 static cl::opt<std::string> PeepholeEPPipeline( 63 "passes-ep-peephole", 64 cl::desc("A textual description of the function pass pipeline inserted at " 65 "the Peephole extension points into default pipelines"), 66 cl::Hidden); 67 static cl::opt<std::string> LateLoopOptimizationsEPPipeline( 68 "passes-ep-late-loop-optimizations", 69 cl::desc( 70 "A textual description of the loop pass pipeline inserted at " 71 "the LateLoopOptimizations extension point into default pipelines"), 72 cl::Hidden); 73 static cl::opt<std::string> LoopOptimizerEndEPPipeline( 74 "passes-ep-loop-optimizer-end", 75 cl::desc("A textual description of the loop pass pipeline inserted at " 76 "the LoopOptimizerEnd extension point into default pipelines"), 77 cl::Hidden); 78 static cl::opt<std::string> ScalarOptimizerLateEPPipeline( 79 "passes-ep-scalar-optimizer-late", 80 cl::desc("A textual description of the function pass pipeline inserted at " 81 "the ScalarOptimizerLate extension point into default pipelines"), 82 cl::Hidden); 83 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline( 84 "passes-ep-cgscc-optimizer-late", 85 cl::desc("A textual description of the cgscc pass pipeline inserted at " 86 "the CGSCCOptimizerLate extension point into default pipelines"), 87 cl::Hidden); 88 static cl::opt<std::string> VectorizerStartEPPipeline( 89 "passes-ep-vectorizer-start", 90 cl::desc("A textual description of the function pass pipeline inserted at " 91 "the VectorizerStart extension point into default pipelines"), 92 cl::Hidden); 93 static cl::opt<std::string> PipelineStartEPPipeline( 94 "passes-ep-pipeline-start", 95 cl::desc("A textual description of the function pass pipeline inserted at " 96 "the PipelineStart extension point into default pipelines"), 97 cl::Hidden); 98 static cl::opt<std::string> OptimizerLastEPPipeline( 99 "passes-ep-optimizer-last", 100 cl::desc("A textual description of the function pass pipeline inserted at " 101 "the OptimizerLast extension point into default pipelines"), 102 cl::Hidden); 103 104 enum PGOKind { NoPGO, InstrGen, InstrUse, SampleUse }; 105 static cl::opt<PGOKind> PGOKindFlag( 106 "pgo-kind", cl::init(NoPGO), cl::Hidden, 107 cl::desc("The kind of profile guided optimization"), 108 cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."), 109 clEnumValN(InstrGen, "new-pm-pgo-instr-gen-pipeline", 110 "Instrument the IR to generate profile."), 111 clEnumValN(InstrUse, "new-pm-pgo-instr-use-pipeline", 112 "Use instrumented profile to guide PGO."), 113 clEnumValN(SampleUse, "new-pm-pgo-sample-use-pipeline", 114 "Use sampled profile to guide PGO."))); 115 static cl::opt<std::string> ProfileFile( 116 "profile-file", cl::desc("Path to the profile."), cl::Hidden); 117 static cl::opt<std::string> 118 ProfileRemappingFile("profile-remapping-file", 119 cl::desc("Path to the profile remapping file."), 120 cl::Hidden); 121 static cl::opt<bool> DebugInfoForProfiling( 122 "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, 123 cl::desc("Emit special debug info to enable PGO profile generation.")); 124 /// @}} 125 126 template <typename PassManagerT> 127 bool tryParsePipelineText(PassBuilder &PB, 128 const cl::opt<std::string> &PipelineOpt) { 129 if (PipelineOpt.empty()) 130 return false; 131 132 // Verify the pipeline is parseable: 133 PassManagerT PM; 134 if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) { 135 errs() << "Could not parse -" << PipelineOpt.ArgStr 136 << " pipeline: " << toString(std::move(Err)) 137 << "... I'm going to ignore it.\n"; 138 return false; 139 } 140 return true; 141 } 142 143 /// If one of the EPPipeline command line options was given, register callbacks 144 /// for parsing and inserting the given pipeline 145 static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, 146 bool DebugLogging) { 147 if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 148 PB.registerPeepholeEPCallback( 149 [&PB, VerifyEachPass, DebugLogging]( 150 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 151 ExitOnError Err("Unable to parse PeepholeEP pipeline: "); 152 Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, 153 DebugLogging)); 154 }); 155 if (tryParsePipelineText<LoopPassManager>(PB, 156 LateLoopOptimizationsEPPipeline)) 157 PB.registerLateLoopOptimizationsEPCallback( 158 [&PB, VerifyEachPass, DebugLogging]( 159 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 160 ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); 161 Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, 162 VerifyEachPass, DebugLogging)); 163 }); 164 if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 165 PB.registerLoopOptimizerEndEPCallback( 166 [&PB, VerifyEachPass, DebugLogging]( 167 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 168 ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); 169 Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, 170 VerifyEachPass, DebugLogging)); 171 }); 172 if (tryParsePipelineText<FunctionPassManager>(PB, 173 ScalarOptimizerLateEPPipeline)) 174 PB.registerScalarOptimizerLateEPCallback( 175 [&PB, VerifyEachPass, DebugLogging]( 176 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 177 ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); 178 Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, 179 VerifyEachPass, DebugLogging)); 180 }); 181 if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 182 PB.registerCGSCCOptimizerLateEPCallback( 183 [&PB, VerifyEachPass, DebugLogging]( 184 CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 185 ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); 186 Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, 187 VerifyEachPass, DebugLogging)); 188 }); 189 if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 190 PB.registerVectorizerStartEPCallback( 191 [&PB, VerifyEachPass, DebugLogging]( 192 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 193 ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); 194 Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline, 195 VerifyEachPass, DebugLogging)); 196 }); 197 if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) 198 PB.registerPipelineStartEPCallback( 199 [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) { 200 ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); 201 Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass, 202 DebugLogging)); 203 }); 204 if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline)) 205 PB.registerOptimizerLastEPCallback( 206 [&PB, VerifyEachPass, DebugLogging](FunctionPassManager &PM, 207 PassBuilder::OptimizationLevel) { 208 ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); 209 Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass, 210 DebugLogging)); 211 }); 212 } 213 214 #ifdef LINK_POLLY_INTO_TOOLS 215 namespace polly { 216 void RegisterPollyPasses(PassBuilder &); 217 } 218 #endif 219 220 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 221 ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, 222 ToolOutputFile *OptRemarkFile, 223 StringRef PassPipeline, OutputKind OK, 224 VerifierKind VK, 225 bool ShouldPreserveAssemblyUseListOrder, 226 bool ShouldPreserveBitcodeUseListOrder, 227 bool EmitSummaryIndex, bool EmitModuleHash, 228 bool EnableDebugify) { 229 bool VerifyEachPass = VK == VK_VerifyEachPass; 230 231 Optional<PGOOptions> P; 232 switch (PGOKindFlag) { 233 case InstrGen: 234 P = PGOOptions(ProfileFile, "", "", "", true); 235 break; 236 case InstrUse: 237 P = PGOOptions("", ProfileFile, "", ProfileRemappingFile, false); 238 break; 239 case SampleUse: 240 P = PGOOptions("", "", ProfileFile, ProfileRemappingFile, false); 241 break; 242 case NoPGO: 243 if (DebugInfoForProfiling) 244 P = PGOOptions("", "", "", "", false, true); 245 else 246 P = None; 247 } 248 PassInstrumentationCallbacks PIC; 249 StandardInstrumentations SI; 250 SI.registerCallbacks(PIC); 251 252 PassBuilder PB(TM, P, &PIC); 253 registerEPCallbacks(PB, VerifyEachPass, DebugPM); 254 255 // Load requested pass plugins and let them register pass builder callbacks 256 for (auto &PluginFN : PassPlugins) { 257 auto PassPlugin = PassPlugin::Load(PluginFN); 258 if (!PassPlugin) { 259 errs() << "Failed to load passes from '" << PluginFN 260 << "'. Request ignored.\n"; 261 continue; 262 } 263 264 PassPlugin->registerPassBuilderCallbacks(PB); 265 } 266 267 // Register a callback that creates the debugify passes as needed. 268 PB.registerPipelineParsingCallback( 269 [](StringRef Name, ModulePassManager &MPM, 270 ArrayRef<PassBuilder::PipelineElement>) { 271 if (Name == "debugify") { 272 MPM.addPass(NewPMDebugifyPass()); 273 return true; 274 } else if (Name == "check-debugify") { 275 MPM.addPass(NewPMCheckDebugifyPass()); 276 return true; 277 } 278 return false; 279 }); 280 281 #ifdef LINK_POLLY_INTO_TOOLS 282 polly::RegisterPollyPasses(PB); 283 #endif 284 285 // Specially handle the alias analysis manager so that we can register 286 // a custom pipeline of AA passes with it. 287 AAManager AA; 288 if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) { 289 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 290 return false; 291 } 292 293 LoopAnalysisManager LAM(DebugPM); 294 FunctionAnalysisManager FAM(DebugPM); 295 CGSCCAnalysisManager CGAM(DebugPM); 296 ModuleAnalysisManager MAM(DebugPM); 297 298 // Register the AA manager first so that our version is the one used. 299 FAM.registerPass([&] { return std::move(AA); }); 300 301 // Register all the basic analyses with the managers. 302 PB.registerModuleAnalyses(MAM); 303 PB.registerCGSCCAnalyses(CGAM); 304 PB.registerFunctionAnalyses(FAM); 305 PB.registerLoopAnalyses(LAM); 306 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 307 308 ModulePassManager MPM(DebugPM); 309 if (VK > VK_NoVerifier) 310 MPM.addPass(VerifierPass()); 311 if (EnableDebugify) 312 MPM.addPass(NewPMDebugifyPass()); 313 314 if (auto Err = 315 PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 316 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 317 return false; 318 } 319 320 if (VK > VK_NoVerifier) 321 MPM.addPass(VerifierPass()); 322 if (EnableDebugify) 323 MPM.addPass(NewPMCheckDebugifyPass()); 324 325 // Add any relevant output pass at the end of the pipeline. 326 switch (OK) { 327 case OK_NoOutput: 328 break; // No output pass needed. 329 case OK_OutputAssembly: 330 MPM.addPass( 331 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 332 break; 333 case OK_OutputBitcode: 334 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 335 EmitSummaryIndex, EmitModuleHash)); 336 break; 337 case OK_OutputThinLTOBitcode: 338 MPM.addPass(ThinLTOBitcodeWriterPass( 339 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 340 break; 341 } 342 343 // Before executing passes, print the final values of the LLVM options. 344 cl::PrintOptionValues(); 345 346 // Now that we have all of the passes ready, run them. 347 MPM.run(M, MAM); 348 349 // Declare success. 350 if (OK != OK_NoOutput) { 351 Out->keep(); 352 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 353 ThinLTOLinkOut->keep(); 354 } 355 356 if (OptRemarkFile) 357 OptRemarkFile->keep(); 358 359 return true; 360 } 361