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