1 //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// 11 /// This file is just a split of the code that logically belongs in opt.cpp but 12 /// that includes the new pass manager headers. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "Debugify.h" 17 #include "NewPMDriver.h" 18 #include "PassPrinters.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Analysis/AliasAnalysis.h" 21 #include "llvm/Analysis/CGSCCPassManager.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/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/Scalar/LoopPassManager.h" 38 39 using namespace llvm; 40 using namespace opt_tool; 41 42 static cl::opt<bool> 43 DebugPM("debug-pass-manager", cl::Hidden, 44 cl::desc("Print pass management debugging information")); 45 46 static cl::list<std::string> 47 PassPlugins("load-pass-plugin", 48 cl::desc("Load passes from plugin library")); 49 50 // This flag specifies a textual description of the alias analysis pipeline to 51 // use when querying for aliasing information. It only works in concert with 52 // the "passes" flag above. 53 static cl::opt<std::string> 54 AAPipeline("aa-pipeline", 55 cl::desc("A textual description of the alias analysis " 56 "pipeline for handling managed aliasing queries"), 57 cl::Hidden); 58 59 /// {{@ These options accept textual pipeline descriptions which will be 60 /// inserted into default pipelines at the respective extension points 61 static cl::opt<std::string> PeepholeEPPipeline( 62 "passes-ep-peephole", 63 cl::desc("A textual description of the function pass pipeline inserted at " 64 "the Peephole extension points into default pipelines"), 65 cl::Hidden); 66 static cl::opt<std::string> LateLoopOptimizationsEPPipeline( 67 "passes-ep-late-loop-optimizations", 68 cl::desc( 69 "A textual description of the loop pass pipeline inserted at " 70 "the LateLoopOptimizations extension point into default pipelines"), 71 cl::Hidden); 72 static cl::opt<std::string> LoopOptimizerEndEPPipeline( 73 "passes-ep-loop-optimizer-end", 74 cl::desc("A textual description of the loop pass pipeline inserted at " 75 "the LoopOptimizerEnd extension point into default pipelines"), 76 cl::Hidden); 77 static cl::opt<std::string> ScalarOptimizerLateEPPipeline( 78 "passes-ep-scalar-optimizer-late", 79 cl::desc("A textual description of the function pass pipeline inserted at " 80 "the ScalarOptimizerLate extension point into default pipelines"), 81 cl::Hidden); 82 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline( 83 "passes-ep-cgscc-optimizer-late", 84 cl::desc("A textual description of the cgscc pass pipeline inserted at " 85 "the CGSCCOptimizerLate extension point into default pipelines"), 86 cl::Hidden); 87 static cl::opt<std::string> VectorizerStartEPPipeline( 88 "passes-ep-vectorizer-start", 89 cl::desc("A textual description of the function pass pipeline inserted at " 90 "the VectorizerStart extension point into default pipelines"), 91 cl::Hidden); 92 static cl::opt<std::string> PipelineStartEPPipeline( 93 "passes-ep-pipeline-start", 94 cl::desc("A textual description of the function pass pipeline inserted at " 95 "the PipelineStart extension point into default pipelines"), 96 cl::Hidden); 97 enum PGOKind { NoPGO, InstrGen, InstrUse, SampleUse }; 98 static cl::opt<PGOKind> PGOKindFlag( 99 "pgo-kind", cl::init(NoPGO), cl::Hidden, 100 cl::desc("The kind of profile guided optimization"), 101 cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."), 102 clEnumValN(InstrGen, "new-pm-pgo-instr-gen-pipeline", 103 "Instrument the IR to generate profile."), 104 clEnumValN(InstrUse, "new-pm-pgo-instr-use-pipeline", 105 "Use instrumented profile to guide PGO."), 106 clEnumValN(SampleUse, "new-pm-pgo-sample-use-pipeline", 107 "Use sampled profile to guide PGO."))); 108 static cl::opt<std::string> ProfileFile( 109 "profile-file", cl::desc("Path to the profile."), cl::Hidden); 110 static cl::opt<bool> DebugInfoForProfiling( 111 "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, 112 cl::desc("Emit special debug info to enable PGO profile generation.")); 113 /// @}} 114 115 template <typename PassManagerT> 116 bool tryParsePipelineText(PassBuilder &PB, StringRef PipelineText) { 117 if (PipelineText.empty()) 118 return false; 119 120 // Verify the pipeline is parseable: 121 PassManagerT PM; 122 if (PB.parsePassPipeline(PM, PipelineText)) 123 return true; 124 125 errs() << "Could not parse pipeline '" << PipelineText 126 << "'. I'm going to igore it.\n"; 127 return false; 128 } 129 130 /// If one of the EPPipeline command line options was given, register callbacks 131 /// for parsing and inserting the given pipeline 132 static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, 133 bool DebugLogging) { 134 if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 135 PB.registerPeepholeEPCallback([&PB, VerifyEachPass, DebugLogging]( 136 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 137 PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, 138 DebugLogging); 139 }); 140 if (tryParsePipelineText<LoopPassManager>(PB, 141 LateLoopOptimizationsEPPipeline)) 142 PB.registerLateLoopOptimizationsEPCallback( 143 [&PB, VerifyEachPass, DebugLogging]( 144 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 145 PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, 146 VerifyEachPass, DebugLogging); 147 }); 148 if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 149 PB.registerLoopOptimizerEndEPCallback([&PB, VerifyEachPass, DebugLogging]( 150 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 151 PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, VerifyEachPass, 152 DebugLogging); 153 }); 154 if (tryParsePipelineText<FunctionPassManager>(PB, 155 ScalarOptimizerLateEPPipeline)) 156 PB.registerScalarOptimizerLateEPCallback( 157 [&PB, VerifyEachPass, DebugLogging]( 158 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 159 PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, 160 VerifyEachPass, DebugLogging); 161 }); 162 if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 163 PB.registerCGSCCOptimizerLateEPCallback([&PB, VerifyEachPass, DebugLogging]( 164 CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 165 PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, VerifyEachPass, 166 DebugLogging); 167 }); 168 if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 169 PB.registerVectorizerStartEPCallback([&PB, VerifyEachPass, DebugLogging]( 170 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 171 PB.parsePassPipeline(PM, VectorizerStartEPPipeline, VerifyEachPass, 172 DebugLogging); 173 }); 174 if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) 175 PB.registerPipelineStartEPCallback( 176 [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) { 177 PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass, 178 DebugLogging); 179 }); 180 } 181 182 #ifdef LINK_POLLY_INTO_TOOLS 183 namespace polly { 184 void RegisterPollyPasses(PassBuilder &); 185 } 186 #endif 187 188 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 189 ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, 190 ToolOutputFile *OptRemarkFile, 191 StringRef PassPipeline, OutputKind OK, 192 VerifierKind VK, 193 bool ShouldPreserveAssemblyUseListOrder, 194 bool ShouldPreserveBitcodeUseListOrder, 195 bool EmitSummaryIndex, bool EmitModuleHash, 196 bool EnableDebugify) { 197 bool VerifyEachPass = VK == VK_VerifyEachPass; 198 199 Optional<PGOOptions> P; 200 switch (PGOKindFlag) { 201 case InstrGen: 202 P = PGOOptions(ProfileFile, "", "", true); 203 break; 204 case InstrUse: 205 P = PGOOptions("", ProfileFile, "", false); 206 break; 207 case SampleUse: 208 P = PGOOptions("", "", ProfileFile, false); 209 break; 210 case NoPGO: 211 if (DebugInfoForProfiling) 212 P = PGOOptions("", "", "", false, true); 213 else 214 P = None; 215 } 216 PassBuilder PB(TM, P); 217 registerEPCallbacks(PB, VerifyEachPass, DebugPM); 218 219 // Load requested pass plugins and let them register pass builder callbacks 220 for (auto &PluginFN : PassPlugins) { 221 auto PassPlugin = PassPlugin::Load(PluginFN); 222 if (!PassPlugin) { 223 errs() << "Failed to load passes from '" << PluginFN 224 << "'. Request ignored.\n"; 225 continue; 226 } 227 228 PassPlugin->registerPassBuilderCallbacks(PB); 229 } 230 231 // Register a callback that creates the debugify passes as needed. 232 PB.registerPipelineParsingCallback( 233 [](StringRef Name, ModulePassManager &MPM, 234 ArrayRef<PassBuilder::PipelineElement>) { 235 if (Name == "debugify") { 236 MPM.addPass(NewPMDebugifyPass()); 237 return true; 238 } else if (Name == "check-debugify") { 239 MPM.addPass(NewPMCheckDebugifyPass()); 240 return true; 241 } 242 return false; 243 }); 244 245 #ifdef LINK_POLLY_INTO_TOOLS 246 polly::RegisterPollyPasses(PB); 247 #endif 248 249 // Specially handle the alias analysis manager so that we can register 250 // a custom pipeline of AA passes with it. 251 AAManager AA; 252 if (!PB.parseAAPipeline(AA, AAPipeline)) { 253 errs() << Arg0 << ": unable to parse AA pipeline description.\n"; 254 return false; 255 } 256 257 LoopAnalysisManager LAM(DebugPM); 258 FunctionAnalysisManager FAM(DebugPM); 259 CGSCCAnalysisManager CGAM(DebugPM); 260 ModuleAnalysisManager MAM(DebugPM); 261 262 // Register the AA manager first so that our version is the one used. 263 FAM.registerPass([&] { return std::move(AA); }); 264 265 // Register all the basic analyses with the managers. 266 PB.registerModuleAnalyses(MAM); 267 PB.registerCGSCCAnalyses(CGAM); 268 PB.registerFunctionAnalyses(FAM); 269 PB.registerLoopAnalyses(LAM); 270 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 271 272 ModulePassManager MPM(DebugPM); 273 if (VK > VK_NoVerifier) 274 MPM.addPass(VerifierPass()); 275 if (EnableDebugify) 276 MPM.addPass(NewPMDebugifyPass()); 277 278 if (!PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 279 errs() << Arg0 << ": unable to parse pass pipeline description.\n"; 280 return false; 281 } 282 283 if (VK > VK_NoVerifier) 284 MPM.addPass(VerifierPass()); 285 if (EnableDebugify) 286 MPM.addPass(NewPMCheckDebugifyPass()); 287 288 // Add any relevant output pass at the end of the pipeline. 289 switch (OK) { 290 case OK_NoOutput: 291 break; // No output pass needed. 292 case OK_OutputAssembly: 293 MPM.addPass( 294 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 295 break; 296 case OK_OutputBitcode: 297 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 298 EmitSummaryIndex, EmitModuleHash)); 299 break; 300 case OK_OutputThinLTOBitcode: 301 MPM.addPass(ThinLTOBitcodeWriterPass( 302 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 303 break; 304 } 305 306 // Before executing passes, print the final values of the LLVM options. 307 cl::PrintOptionValues(); 308 309 // Now that we have all of the passes ready, run them. 310 MPM.run(M, MAM); 311 312 // Declare success. 313 if (OK != OK_NoOutput) { 314 Out->keep(); 315 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 316 ThinLTOLinkOut->keep(); 317 } 318 319 if (OptRemarkFile) 320 OptRemarkFile->keep(); 321 322 return true; 323 } 324