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 /// @}} 85 86 template <typename PassManagerT> 87 bool tryParsePipelineText(PassBuilder &PB, StringRef PipelineText) { 88 if (PipelineText.empty()) 89 return false; 90 91 // Verify the pipeline is parseable: 92 PassManagerT PM; 93 if (PB.parsePassPipeline(PM, PipelineText)) 94 return true; 95 96 errs() << "Could not parse pipeline '" << PipelineText 97 << "'. I'm going to igore it.\n"; 98 return false; 99 } 100 101 /// If one of the EPPipeline command line options was given, register callbacks 102 /// for parsing and inserting the given pipeline 103 static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, 104 bool DebugLogging) { 105 if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 106 PB.registerPeepholeEPCallback([&PB, VerifyEachPass, DebugLogging]( 107 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 108 PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, 109 DebugLogging); 110 }); 111 if (tryParsePipelineText<LoopPassManager>(PB, 112 LateLoopOptimizationsEPPipeline)) 113 PB.registerLateLoopOptimizationsEPCallback( 114 [&PB, VerifyEachPass, DebugLogging]( 115 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 116 PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, 117 VerifyEachPass, DebugLogging); 118 }); 119 if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 120 PB.registerLoopOptimizerEndEPCallback([&PB, VerifyEachPass, DebugLogging]( 121 LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 122 PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, VerifyEachPass, 123 DebugLogging); 124 }); 125 if (tryParsePipelineText<FunctionPassManager>(PB, 126 ScalarOptimizerLateEPPipeline)) 127 PB.registerScalarOptimizerLateEPCallback( 128 [&PB, VerifyEachPass, DebugLogging]( 129 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 130 PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, 131 VerifyEachPass, DebugLogging); 132 }); 133 if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 134 PB.registerCGSCCOptimizerLateEPCallback([&PB, VerifyEachPass, DebugLogging]( 135 CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 136 PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, VerifyEachPass, 137 DebugLogging); 138 }); 139 if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 140 PB.registerVectorizerStartEPCallback([&PB, VerifyEachPass, DebugLogging]( 141 FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 142 PB.parsePassPipeline(PM, VectorizerStartEPPipeline, VerifyEachPass, 143 DebugLogging); 144 }); 145 } 146 147 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 148 tool_output_file *Out, 149 tool_output_file *ThinLTOLinkOut, 150 StringRef PassPipeline, OutputKind OK, 151 VerifierKind VK, 152 bool ShouldPreserveAssemblyUseListOrder, 153 bool ShouldPreserveBitcodeUseListOrder, 154 bool EmitSummaryIndex, bool EmitModuleHash) { 155 bool VerifyEachPass = VK == VK_VerifyEachPass; 156 PassBuilder PB(TM); 157 registerEPCallbacks(PB, VerifyEachPass, DebugPM); 158 159 // Specially handle the alias analysis manager so that we can register 160 // a custom pipeline of AA passes with it. 161 AAManager AA; 162 if (!PB.parseAAPipeline(AA, AAPipeline)) { 163 errs() << Arg0 << ": unable to parse AA pipeline description.\n"; 164 return false; 165 } 166 167 LoopAnalysisManager LAM(DebugPM); 168 FunctionAnalysisManager FAM(DebugPM); 169 CGSCCAnalysisManager CGAM(DebugPM); 170 ModuleAnalysisManager MAM(DebugPM); 171 172 // Register the AA manager first so that our version is the one used. 173 FAM.registerPass([&] { return std::move(AA); }); 174 175 // Register all the basic analyses with the managers. 176 PB.registerModuleAnalyses(MAM); 177 PB.registerCGSCCAnalyses(CGAM); 178 PB.registerFunctionAnalyses(FAM); 179 PB.registerLoopAnalyses(LAM); 180 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 181 182 ModulePassManager MPM(DebugPM); 183 if (VK > VK_NoVerifier) 184 MPM.addPass(VerifierPass()); 185 186 if (!PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 187 errs() << Arg0 << ": unable to parse pass pipeline description.\n"; 188 return false; 189 } 190 191 if (VK > VK_NoVerifier) 192 MPM.addPass(VerifierPass()); 193 194 // Add any relevant output pass at the end of the pipeline. 195 switch (OK) { 196 case OK_NoOutput: 197 break; // No output pass needed. 198 case OK_OutputAssembly: 199 MPM.addPass( 200 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 201 break; 202 case OK_OutputBitcode: 203 MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 204 EmitSummaryIndex, EmitModuleHash)); 205 break; 206 case OK_OutputThinLTOBitcode: 207 MPM.addPass(ThinLTOBitcodeWriterPass( 208 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 209 break; 210 } 211 212 // Before executing passes, print the final values of the LLVM options. 213 cl::PrintOptionValues(); 214 215 // Now that we have all of the passes ready, run them. 216 MPM.run(M, MAM); 217 218 // Declare success. 219 if (OK != OK_NoOutput) { 220 Out->keep(); 221 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 222 ThinLTOLinkOut->keep(); 223 } 224 return true; 225 } 226