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