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