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