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