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