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 tool_output_file *Out, 172 tool_output_file *ThinLTOLinkOut, 173 tool_output_file *OptRemarkFile, 174 StringRef PassPipeline, OutputKind OK, 175 VerifierKind VK, 176 bool ShouldPreserveAssemblyUseListOrder, 177 bool ShouldPreserveBitcodeUseListOrder, 178 bool EmitSummaryIndex, bool EmitModuleHash) { 179 bool VerifyEachPass = VK == VK_VerifyEachPass; 180 181 Optional<PGOOptions> P; 182 switch (PGOKindFlag) { 183 case InstrGen: 184 P = PGOOptions(ProfileFile, "", "", true); 185 break; 186 case InstrUse: 187 P = PGOOptions("", ProfileFile, "", false); 188 break; 189 case SampleUse: 190 P = PGOOptions("", "", ProfileFile, false); 191 break; 192 case NoPGO: 193 if (DebugInfoForProfiling) 194 P = PGOOptions("", "", "", false, true); 195 else 196 P = None; 197 } 198 PassBuilder PB(TM, P); 199 registerEPCallbacks(PB, VerifyEachPass, DebugPM); 200 201 #ifdef LINK_POLLY_INTO_TOOLS 202 polly::RegisterPollyPasses(PB); 203 #endif 204 205 // Specially handle the alias analysis manager so that we can register 206 // a custom pipeline of AA passes with it. 207 AAManager AA; 208 if (!PB.parseAAPipeline(AA, AAPipeline)) { 209 errs() << Arg0 << ": unable to parse AA pipeline description.\n"; 210 return false; 211 } 212 213 LoopAnalysisManager LAM(DebugPM); 214 FunctionAnalysisManager FAM(DebugPM); 215 CGSCCAnalysisManager CGAM(DebugPM); 216 ModuleAnalysisManager MAM(DebugPM); 217 218 // Register the AA manager first so that our version is the one used. 219 FAM.registerPass([&] { return std::move(AA); }); 220 221 // Register all the basic analyses with the managers. 222 PB.registerModuleAnalyses(MAM); 223 PB.registerCGSCCAnalyses(CGAM); 224 PB.registerFunctionAnalyses(FAM); 225 PB.registerLoopAnalyses(LAM); 226 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 227 228 ModulePassManager MPM(DebugPM); 229 if (VK > VK_NoVerifier) 230 MPM.addPass(VerifierPass()); 231 232 if (!PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 233 errs() << Arg0 << ": unable to parse pass pipeline description.\n"; 234 return false; 235 } 236 237 if (VK > VK_NoVerifier) 238 MPM.addPass(VerifierPass()); 239 240 // Add any relevant output pass at the end of the pipeline. 241 switch (OK) { 242 case OK_NoOutput: 243 break; // No output pass needed. 244 case OK_OutputAssembly: 245 MPM.addPass( 246 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 247 break; 248 case OK_OutputBitcode: 249 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 250 EmitSummaryIndex, EmitModuleHash)); 251 break; 252 case OK_OutputThinLTOBitcode: 253 MPM.addPass(ThinLTOBitcodeWriterPass( 254 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 255 break; 256 } 257 258 // Before executing passes, print the final values of the LLVM options. 259 cl::PrintOptionValues(); 260 261 // Now that we have all of the passes ready, run them. 262 MPM.run(M, MAM); 263 264 // Declare success. 265 if (OK != OK_NoOutput) { 266 Out->keep(); 267 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 268 ThinLTOLinkOut->keep(); 269 } 270 271 if (OptRemarkFile) 272 OptRemarkFile->keep(); 273 274 return true; 275 } 276