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