1 //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file is just a split of the code that logically belongs in opt.cpp but 11 /// that includes the new pass manager headers. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "NewPMDriver.h" 16 #include "PassPrinters.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Analysis/AliasAnalysis.h" 20 #include "llvm/Analysis/CGSCCPassManager.h" 21 #include "llvm/Bitcode/BitcodeWriterPass.h" 22 #include "llvm/Config/llvm-config.h" 23 #include "llvm/IR/Dominators.h" 24 #include "llvm/IR/IRPrintingPasses.h" 25 #include "llvm/IR/LLVMContext.h" 26 #include "llvm/IR/Module.h" 27 #include "llvm/IR/PassManager.h" 28 #include "llvm/IR/Verifier.h" 29 #include "llvm/Passes/PassBuilder.h" 30 #include "llvm/Passes/PassPlugin.h" 31 #include "llvm/Passes/StandardInstrumentations.h" 32 #include "llvm/Support/CommandLine.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/ToolOutputFile.h" 35 #include "llvm/Target/TargetMachine.h" 36 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 37 #include "llvm/Transforms/Scalar/LoopPassManager.h" 38 #include "llvm/Transforms/Utils/Debugify.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 // Individual pipeline tuning options. 105 static cl::opt<bool> DisableLoopUnrolling( 106 "new-pm-disable-loop-unrolling", 107 cl::desc("Disable loop unrolling in all relevant passes"), cl::init(false)); 108 109 extern cl::opt<PGOKind> PGOKindFlag; 110 extern cl::opt<std::string> ProfileFile; 111 extern cl::opt<CSPGOKind> CSPGOKindFlag; 112 extern cl::opt<std::string> CSProfileGenFile; 113 114 static cl::opt<std::string> 115 ProfileRemappingFile("profile-remapping-file", 116 cl::desc("Path to the profile remapping file."), 117 cl::Hidden); 118 static cl::opt<bool> DebugInfoForProfiling( 119 "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, 120 cl::desc("Emit special debug info to enable PGO profile generation.")); 121 /// @}} 122 123 template <typename PassManagerT> 124 bool tryParsePipelineText(PassBuilder &PB, 125 const cl::opt<std::string> &PipelineOpt) { 126 if (PipelineOpt.empty()) 127 return false; 128 129 // Verify the pipeline is parseable: 130 PassManagerT PM; 131 if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) { 132 errs() << "Could not parse -" << PipelineOpt.ArgStr 133 << " pipeline: " << toString(std::move(Err)) 134 << "... I'm going to ignore it.\n"; 135 return false; 136 } 137 return true; 138 } 139 140 /// If one of the EPPipeline command line options was given, register callbacks 141 /// for parsing and inserting the given pipeline 142 static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, 143 bool DebugLogging) { 144 if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 145 PB.registerPeepholeEPCallback( 146 [&PB, VerifyEachPass, DebugLogging]( 147 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 148 ExitOnError Err("Unable to parse PeepholeEP pipeline: "); 149 Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, 150 DebugLogging)); 151 }); 152 if (tryParsePipelineText<LoopPassManager>(PB, 153 LateLoopOptimizationsEPPipeline)) 154 PB.registerLateLoopOptimizationsEPCallback( 155 [&PB, VerifyEachPass, DebugLogging]( 156 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 157 ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); 158 Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, 159 VerifyEachPass, DebugLogging)); 160 }); 161 if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 162 PB.registerLoopOptimizerEndEPCallback( 163 [&PB, VerifyEachPass, DebugLogging]( 164 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 165 ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); 166 Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, 167 VerifyEachPass, DebugLogging)); 168 }); 169 if (tryParsePipelineText<FunctionPassManager>(PB, 170 ScalarOptimizerLateEPPipeline)) 171 PB.registerScalarOptimizerLateEPCallback( 172 [&PB, VerifyEachPass, DebugLogging]( 173 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 174 ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); 175 Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, 176 VerifyEachPass, DebugLogging)); 177 }); 178 if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 179 PB.registerCGSCCOptimizerLateEPCallback( 180 [&PB, VerifyEachPass, DebugLogging]( 181 CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 182 ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); 183 Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, 184 VerifyEachPass, DebugLogging)); 185 }); 186 if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 187 PB.registerVectorizerStartEPCallback( 188 [&PB, VerifyEachPass, DebugLogging]( 189 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 190 ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); 191 Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline, 192 VerifyEachPass, DebugLogging)); 193 }); 194 if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) 195 PB.registerPipelineStartEPCallback( 196 [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) { 197 ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); 198 Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass, 199 DebugLogging)); 200 }); 201 if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline)) 202 PB.registerOptimizerLastEPCallback( 203 [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM, 204 PassBuilder::OptimizationLevel) { 205 ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); 206 Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass, 207 DebugLogging)); 208 }); 209 } 210 211 #define HANDLE_EXTENSION(Ext) \ 212 llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); 213 #include "llvm/Support/Extension.def" 214 215 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 216 ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, 217 ToolOutputFile *OptRemarkFile, 218 StringRef PassPipeline, ArrayRef<StringRef> Passes, 219 OutputKind OK, VerifierKind VK, 220 bool ShouldPreserveAssemblyUseListOrder, 221 bool ShouldPreserveBitcodeUseListOrder, 222 bool EmitSummaryIndex, bool EmitModuleHash, 223 bool EnableDebugify, bool Coroutines) { 224 bool VerifyEachPass = VK == VK_VerifyEachPass; 225 226 Optional<PGOOptions> P; 227 switch (PGOKindFlag) { 228 case InstrGen: 229 P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr); 230 break; 231 case InstrUse: 232 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse); 233 break; 234 case SampleUse: 235 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, 236 PGOOptions::SampleUse); 237 break; 238 case NoPGO: 239 if (DebugInfoForProfiling) 240 P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction, 241 true); 242 else 243 P = None; 244 } 245 if (CSPGOKindFlag != NoCSPGO) { 246 if (P && (P->Action == PGOOptions::IRInstr || 247 P->Action == PGOOptions::SampleUse)) 248 errs() << "CSPGOKind cannot be used with IRInstr or SampleUse"; 249 if (CSPGOKindFlag == CSInstrGen) { 250 if (CSProfileGenFile.empty()) 251 errs() << "CSInstrGen needs to specify CSProfileGenFile"; 252 if (P) { 253 P->CSAction = PGOOptions::CSIRInstr; 254 P->CSProfileGenFile = CSProfileGenFile; 255 } else 256 P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile, 257 PGOOptions::NoAction, PGOOptions::CSIRInstr); 258 } else /* CSPGOKindFlag == CSInstrUse */ { 259 if (!P) 260 errs() << "CSInstrUse needs to be together with InstrUse"; 261 P->CSAction = PGOOptions::CSIRUse; 262 } 263 } 264 PassInstrumentationCallbacks PIC; 265 StandardInstrumentations SI; 266 SI.registerCallbacks(PIC); 267 268 PipelineTuningOptions PTO; 269 // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized 270 // to false above so we shouldn't necessarily need to check whether or not the 271 // option has been enabled. 272 PTO.LoopUnrolling = !DisableLoopUnrolling; 273 PTO.Coroutines = Coroutines; 274 PassBuilder PB(TM, PTO, P, &PIC); 275 registerEPCallbacks(PB, VerifyEachPass, DebugPM); 276 277 // Load requested pass plugins and let them register pass builder callbacks 278 for (auto &PluginFN : PassPlugins) { 279 auto PassPlugin = PassPlugin::Load(PluginFN); 280 if (!PassPlugin) { 281 errs() << "Failed to load passes from '" << PluginFN 282 << "'. Request ignored.\n"; 283 continue; 284 } 285 286 PassPlugin->registerPassBuilderCallbacks(PB); 287 } 288 289 // Register a callback that creates the debugify passes as needed. 290 PB.registerPipelineParsingCallback( 291 [](StringRef Name, ModulePassManager &MPM, 292 ArrayRef<PassBuilder::PipelineElement>) { 293 if (Name == "debugify") { 294 MPM.addPass(NewPMDebugifyPass()); 295 return true; 296 } else if (Name == "check-debugify") { 297 MPM.addPass(NewPMCheckDebugifyPass()); 298 return true; 299 } 300 return false; 301 }); 302 303 #define HANDLE_EXTENSION(Ext) \ 304 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); 305 #include "llvm/Support/Extension.def" 306 307 // Specially handle the alias analysis manager so that we can register 308 // a custom pipeline of AA passes with it. 309 AAManager AA; 310 if (!AAPipeline.empty()) { 311 assert(Passes.empty() && 312 "--aa-pipeline and -foo-pass should not both be specified"); 313 if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) { 314 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 315 return false; 316 } 317 } 318 // For compatibility with legacy pass manager. 319 // Alias analyses are not specially specified when using the legacy PM. 320 SmallVector<StringRef, 4> NonAAPasses; 321 for (auto PassName : Passes) { 322 if (PB.isAAPassName(PassName)) { 323 if (auto Err = PB.parseAAPipeline(AA, PassName)) { 324 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 325 return false; 326 } 327 } else { 328 NonAAPasses.push_back(PassName); 329 } 330 } 331 332 LoopAnalysisManager LAM(DebugPM); 333 FunctionAnalysisManager FAM(DebugPM); 334 CGSCCAnalysisManager CGAM(DebugPM); 335 ModuleAnalysisManager MAM(DebugPM); 336 337 // Register the AA manager first so that our version is the one used. 338 FAM.registerPass([&] { return std::move(AA); }); 339 340 // Register all the basic analyses with the managers. 341 PB.registerModuleAnalyses(MAM); 342 PB.registerCGSCCAnalyses(CGAM); 343 PB.registerFunctionAnalyses(FAM); 344 PB.registerLoopAnalyses(LAM); 345 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 346 347 ModulePassManager MPM(DebugPM); 348 if (VK > VK_NoVerifier) 349 MPM.addPass(VerifierPass()); 350 if (EnableDebugify) 351 MPM.addPass(NewPMDebugifyPass()); 352 353 if (!PassPipeline.empty()) { 354 assert(Passes.empty() && 355 "PassPipeline and Passes should not both contain passes"); 356 if (auto Err = 357 PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 358 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 359 return false; 360 } 361 } 362 for (auto PassName : NonAAPasses) { 363 if (auto Err = 364 PB.parsePassPipeline(MPM, PassName, VerifyEachPass, DebugPM)) { 365 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 366 return false; 367 } 368 } 369 370 if (VK > VK_NoVerifier) 371 MPM.addPass(VerifierPass()); 372 if (EnableDebugify) 373 MPM.addPass(NewPMCheckDebugifyPass()); 374 375 // Add any relevant output pass at the end of the pipeline. 376 switch (OK) { 377 case OK_NoOutput: 378 break; // No output pass needed. 379 case OK_OutputAssembly: 380 MPM.addPass( 381 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 382 break; 383 case OK_OutputBitcode: 384 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 385 EmitSummaryIndex, EmitModuleHash)); 386 break; 387 case OK_OutputThinLTOBitcode: 388 MPM.addPass(ThinLTOBitcodeWriterPass( 389 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 390 break; 391 } 392 393 // Before executing passes, print the final values of the LLVM options. 394 cl::PrintOptionValues(); 395 396 // Now that we have all of the passes ready, run them. 397 MPM.run(M, MAM); 398 399 // Declare success. 400 if (OK != OK_NoOutput) { 401 Out->keep(); 402 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 403 ThinLTOLinkOut->keep(); 404 } 405 406 if (OptRemarkFile) 407 OptRemarkFile->keep(); 408 409 return true; 410 } 411