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