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/Analysis/TargetLibraryInfo.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/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/Instrumentation/AddressSanitizer.h" 38 #include "llvm/Transforms/Scalar/LoopPassManager.h" 39 #include "llvm/Transforms/Utils/Debugify.h" 40 41 using namespace llvm; 42 using namespace opt_tool; 43 44 namespace llvm { 45 cl::opt<bool> DebugifyEach( 46 "debugify-each", 47 cl::desc("Start each pass with debugify and end it with check-debugify")); 48 49 cl::opt<std::string> 50 DebugifyExport("debugify-export", 51 cl::desc("Export per-pass debugify statistics to this file"), 52 cl::value_desc("filename")); 53 } // namespace llvm 54 55 static cl::opt<bool> 56 DebugPM("debug-pass-manager", cl::Hidden, 57 cl::desc("Print pass management debugging information")); 58 59 static cl::list<std::string> 60 PassPlugins("load-pass-plugin", 61 cl::desc("Load passes from plugin library")); 62 63 // This flag specifies a textual description of the alias analysis pipeline to 64 // use when querying for aliasing information. It only works in concert with 65 // the "passes" flag above. 66 static cl::opt<std::string> 67 AAPipeline("aa-pipeline", 68 cl::desc("A textual description of the alias analysis " 69 "pipeline for handling managed aliasing queries"), 70 cl::Hidden, cl::init("default")); 71 72 /// {{@ These options accept textual pipeline descriptions which will be 73 /// inserted into default pipelines at the respective extension points 74 static cl::opt<std::string> PeepholeEPPipeline( 75 "passes-ep-peephole", 76 cl::desc("A textual description of the function pass pipeline inserted at " 77 "the Peephole extension points into default pipelines"), 78 cl::Hidden); 79 static cl::opt<std::string> LateLoopOptimizationsEPPipeline( 80 "passes-ep-late-loop-optimizations", 81 cl::desc( 82 "A textual description of the loop pass pipeline inserted at " 83 "the LateLoopOptimizations extension point into default pipelines"), 84 cl::Hidden); 85 static cl::opt<std::string> LoopOptimizerEndEPPipeline( 86 "passes-ep-loop-optimizer-end", 87 cl::desc("A textual description of the loop pass pipeline inserted at " 88 "the LoopOptimizerEnd extension point into default pipelines"), 89 cl::Hidden); 90 static cl::opt<std::string> ScalarOptimizerLateEPPipeline( 91 "passes-ep-scalar-optimizer-late", 92 cl::desc("A textual description of the function pass pipeline inserted at " 93 "the ScalarOptimizerLate extension point into default pipelines"), 94 cl::Hidden); 95 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline( 96 "passes-ep-cgscc-optimizer-late", 97 cl::desc("A textual description of the cgscc pass pipeline inserted at " 98 "the CGSCCOptimizerLate extension point into default pipelines"), 99 cl::Hidden); 100 static cl::opt<std::string> VectorizerStartEPPipeline( 101 "passes-ep-vectorizer-start", 102 cl::desc("A textual description of the function pass pipeline inserted at " 103 "the VectorizerStart extension point into default pipelines"), 104 cl::Hidden); 105 static cl::opt<std::string> PipelineStartEPPipeline( 106 "passes-ep-pipeline-start", 107 cl::desc("A textual description of the module pass pipeline inserted at " 108 "the PipelineStart extension point into default pipelines"), 109 cl::Hidden); 110 static cl::opt<std::string> PipelineEarlySimplificationEPPipeline( 111 "passes-ep-pipeline-early-simplification", 112 cl::desc("A textual description of the module pass pipeline inserted at " 113 "the EarlySimplification extension point into default pipelines"), 114 cl::Hidden); 115 static cl::opt<std::string> OptimizerLastEPPipeline( 116 "passes-ep-optimizer-last", 117 cl::desc("A textual description of the module pass pipeline inserted at " 118 "the OptimizerLast extension point into default pipelines"), 119 cl::Hidden); 120 121 // Individual pipeline tuning options. 122 extern cl::opt<bool> DisableLoopUnrolling; 123 124 namespace llvm { 125 extern cl::opt<PGOKind> PGOKindFlag; 126 extern cl::opt<std::string> ProfileFile; 127 extern cl::opt<CSPGOKind> CSPGOKindFlag; 128 extern cl::opt<std::string> CSProfileGenFile; 129 extern cl::opt<bool> DisableBasicAA; 130 } // namespace llvm 131 132 static cl::opt<std::string> 133 ProfileRemappingFile("profile-remapping-file", 134 cl::desc("Path to the profile remapping file."), 135 cl::Hidden); 136 static cl::opt<bool> DebugInfoForProfiling( 137 "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, 138 cl::desc("Emit special debug info to enable PGO profile generation.")); 139 static cl::opt<bool> PseudoProbeForProfiling( 140 "new-pm-pseudo-probe-for-profiling", cl::init(false), cl::Hidden, 141 cl::desc("Emit pseudo probes to enable PGO profile generation.")); 142 /// @}} 143 144 template <typename PassManagerT> 145 bool tryParsePipelineText(PassBuilder &PB, 146 const cl::opt<std::string> &PipelineOpt) { 147 if (PipelineOpt.empty()) 148 return false; 149 150 // Verify the pipeline is parseable: 151 PassManagerT PM; 152 if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) { 153 errs() << "Could not parse -" << PipelineOpt.ArgStr 154 << " pipeline: " << toString(std::move(Err)) 155 << "... I'm going to ignore it.\n"; 156 return false; 157 } 158 return true; 159 } 160 161 /// If one of the EPPipeline command line options was given, register callbacks 162 /// for parsing and inserting the given pipeline 163 static void registerEPCallbacks(PassBuilder &PB) { 164 if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 165 PB.registerPeepholeEPCallback( 166 [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 167 ExitOnError Err("Unable to parse PeepholeEP pipeline: "); 168 Err(PB.parsePassPipeline(PM, PeepholeEPPipeline)); 169 }); 170 if (tryParsePipelineText<LoopPassManager>(PB, 171 LateLoopOptimizationsEPPipeline)) 172 PB.registerLateLoopOptimizationsEPCallback( 173 [&PB](LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 174 ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); 175 Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline)); 176 }); 177 if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 178 PB.registerLoopOptimizerEndEPCallback( 179 [&PB](LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 180 ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); 181 Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline)); 182 }); 183 if (tryParsePipelineText<FunctionPassManager>(PB, 184 ScalarOptimizerLateEPPipeline)) 185 PB.registerScalarOptimizerLateEPCallback( 186 [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 187 ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); 188 Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline)); 189 }); 190 if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 191 PB.registerCGSCCOptimizerLateEPCallback( 192 [&PB](CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 193 ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); 194 Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline)); 195 }); 196 if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 197 PB.registerVectorizerStartEPCallback( 198 [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 199 ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); 200 Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline)); 201 }); 202 if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) 203 PB.registerPipelineStartEPCallback( 204 [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) { 205 ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); 206 Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline)); 207 }); 208 if (tryParsePipelineText<ModulePassManager>( 209 PB, PipelineEarlySimplificationEPPipeline)) 210 PB.registerPipelineEarlySimplificationEPCallback( 211 [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) { 212 ExitOnError Err("Unable to parse EarlySimplification pipeline: "); 213 Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline)); 214 }); 215 if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline)) 216 PB.registerOptimizerLastEPCallback( 217 [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) { 218 ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); 219 Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline)); 220 }); 221 } 222 223 #define HANDLE_EXTENSION(Ext) \ 224 llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); 225 #include "llvm/Support/Extension.def" 226 227 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 228 TargetLibraryInfoImpl *TLII, ToolOutputFile *Out, 229 ToolOutputFile *ThinLTOLinkOut, 230 ToolOutputFile *OptRemarkFile, 231 StringRef PassPipeline, ArrayRef<StringRef> Passes, 232 OutputKind OK, VerifierKind VK, 233 bool ShouldPreserveAssemblyUseListOrder, 234 bool ShouldPreserveBitcodeUseListOrder, 235 bool EmitSummaryIndex, bool EmitModuleHash, 236 bool EnableDebugify, bool Coroutines) { 237 bool VerifyEachPass = VK == VK_VerifyEachPass; 238 239 Optional<PGOOptions> P; 240 switch (PGOKindFlag) { 241 case InstrGen: 242 P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr); 243 break; 244 case InstrUse: 245 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse); 246 break; 247 case SampleUse: 248 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, 249 PGOOptions::SampleUse); 250 break; 251 case NoPGO: 252 if (DebugInfoForProfiling) 253 P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction, 254 true); 255 else if (PseudoProbeForProfiling) 256 P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction, 257 false, true); 258 else 259 P = None; 260 } 261 if (CSPGOKindFlag != NoCSPGO) { 262 if (P && (P->Action == PGOOptions::IRInstr || 263 P->Action == PGOOptions::SampleUse)) 264 errs() << "CSPGOKind cannot be used with IRInstr or SampleUse"; 265 if (CSPGOKindFlag == CSInstrGen) { 266 if (CSProfileGenFile.empty()) 267 errs() << "CSInstrGen needs to specify CSProfileGenFile"; 268 if (P) { 269 P->CSAction = PGOOptions::CSIRInstr; 270 P->CSProfileGenFile = CSProfileGenFile; 271 } else 272 P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile, 273 PGOOptions::NoAction, PGOOptions::CSIRInstr); 274 } else /* CSPGOKindFlag == CSInstrUse */ { 275 if (!P) 276 errs() << "CSInstrUse needs to be together with InstrUse"; 277 P->CSAction = PGOOptions::CSIRUse; 278 } 279 } 280 LoopAnalysisManager LAM; 281 FunctionAnalysisManager FAM; 282 CGSCCAnalysisManager CGAM; 283 ModuleAnalysisManager MAM; 284 285 PassInstrumentationCallbacks PIC; 286 StandardInstrumentations SI(DebugPM, VerifyEachPass); 287 SI.registerCallbacks(PIC, &FAM); 288 DebugifyEachInstrumentation Debugify; 289 if (DebugifyEach) 290 Debugify.registerCallbacks(PIC); 291 292 PipelineTuningOptions PTO; 293 // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized 294 // to false above so we shouldn't necessarily need to check whether or not the 295 // option has been enabled. 296 PTO.LoopUnrolling = !DisableLoopUnrolling; 297 PTO.Coroutines = Coroutines; 298 PassBuilder PB(TM, PTO, P, &PIC); 299 registerEPCallbacks(PB); 300 301 // Load requested pass plugins and let them register pass builder callbacks 302 for (auto &PluginFN : PassPlugins) { 303 auto PassPlugin = PassPlugin::Load(PluginFN); 304 if (!PassPlugin) { 305 errs() << "Failed to load passes from '" << PluginFN 306 << "'. Request ignored.\n"; 307 continue; 308 } 309 310 PassPlugin->registerPassBuilderCallbacks(PB); 311 } 312 313 // Register a callback that creates the debugify passes as needed. 314 PB.registerPipelineParsingCallback( 315 [](StringRef Name, ModulePassManager &MPM, 316 ArrayRef<PassBuilder::PipelineElement>) { 317 if (Name == "debugify") { 318 MPM.addPass(NewPMDebugifyPass()); 319 return true; 320 } else if (Name == "check-debugify") { 321 MPM.addPass(NewPMCheckDebugifyPass()); 322 return true; 323 } 324 return false; 325 }); 326 PB.registerPipelineParsingCallback( 327 [](StringRef Name, ModulePassManager &MPM, 328 ArrayRef<PassBuilder::PipelineElement>) { 329 if (Name == "asan-pipeline") { 330 MPM.addPass( 331 RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); 332 MPM.addPass( 333 createModuleToFunctionPassAdaptor(AddressSanitizerPass())); 334 MPM.addPass(ModuleAddressSanitizerPass()); 335 return true; 336 } else if (Name == "asan-function-pipeline") { 337 MPM.addPass( 338 RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); 339 MPM.addPass( 340 createModuleToFunctionPassAdaptor(AddressSanitizerPass())); 341 return true; 342 } 343 return false; 344 }); 345 346 #define HANDLE_EXTENSION(Ext) \ 347 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); 348 #include "llvm/Support/Extension.def" 349 350 // Specially handle the alias analysis manager so that we can register 351 // a custom pipeline of AA passes with it. 352 AAManager AA; 353 if (Passes.empty()) { 354 if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) { 355 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 356 return false; 357 } 358 } 359 360 // For compatibility with the legacy PM AA pipeline. 361 // AAResultsWrapperPass by default provides basic-aa in the legacy PM 362 // unless -disable-basic-aa is specified. 363 // TODO: remove this once tests implicitly requiring basic-aa use -passes= and 364 // -aa-pipeline=basic-aa. 365 if (!Passes.empty() && !DisableBasicAA) { 366 if (auto Err = PB.parseAAPipeline(AA, "basic-aa")) { 367 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 368 return false; 369 } 370 } 371 372 // For compatibility with legacy pass manager. 373 // Alias analyses are not specially specified when using the legacy PM. 374 for (auto PassName : Passes) { 375 if (PB.isAAPassName(PassName)) { 376 if (auto Err = PB.parseAAPipeline(AA, PassName)) { 377 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 378 return false; 379 } 380 } 381 } 382 383 // Register the AA manager first so that our version is the one used. 384 FAM.registerPass([&] { return std::move(AA); }); 385 // Register our TargetLibraryInfoImpl. 386 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); 387 388 // Register all the basic analyses with the managers. 389 PB.registerModuleAnalyses(MAM); 390 PB.registerCGSCCAnalyses(CGAM); 391 PB.registerFunctionAnalyses(FAM); 392 PB.registerLoopAnalyses(LAM); 393 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 394 395 ModulePassManager MPM; 396 if (VK > VK_NoVerifier) 397 MPM.addPass(VerifierPass()); 398 if (EnableDebugify) 399 MPM.addPass(NewPMDebugifyPass()); 400 401 if (!PassPipeline.empty()) { 402 assert(Passes.empty() && 403 "PassPipeline and Passes should not both contain passes"); 404 if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) { 405 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 406 return false; 407 } 408 } 409 for (auto PassName : Passes) { 410 std::string ModifiedPassName(PassName.begin(), PassName.end()); 411 if (PB.isAnalysisPassName(PassName)) 412 ModifiedPassName = "require<" + ModifiedPassName + ">"; 413 if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName)) { 414 errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 415 return false; 416 } 417 } 418 419 if (VK > VK_NoVerifier) 420 MPM.addPass(VerifierPass()); 421 if (EnableDebugify) 422 MPM.addPass(NewPMCheckDebugifyPass()); 423 424 // Add any relevant output pass at the end of the pipeline. 425 switch (OK) { 426 case OK_NoOutput: 427 break; // No output pass needed. 428 case OK_OutputAssembly: 429 MPM.addPass( 430 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 431 break; 432 case OK_OutputBitcode: 433 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 434 EmitSummaryIndex, EmitModuleHash)); 435 break; 436 case OK_OutputThinLTOBitcode: 437 MPM.addPass(ThinLTOBitcodeWriterPass( 438 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 439 break; 440 } 441 442 // Before executing passes, print the final values of the LLVM options. 443 cl::PrintOptionValues(); 444 445 // Now that we have all of the passes ready, run them. 446 MPM.run(M, MAM); 447 448 // Declare success. 449 if (OK != OK_NoOutput) { 450 Out->keep(); 451 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 452 ThinLTOLinkOut->keep(); 453 } 454 455 if (OptRemarkFile) 456 OptRemarkFile->keep(); 457 458 if (DebugifyEach && !DebugifyExport.empty()) 459 exportDebugifyStats(DebugifyExport, Debugify.StatsMap); 460 461 return true; 462 } 463 464 void llvm::printPasses(raw_ostream &OS) { 465 PassBuilder PB; 466 PB.printPassNames(OS); 467 } 468