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