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