1//===- Passes.cpp - Parsing, selection, and running of passes -------------===// 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 provides the infrastructure to parse and build a custom pass 12/// manager based on a commandline flag. It also provides helpers to aid in 13/// analyzing, debugging, and testing pass structures. 14/// 15//===----------------------------------------------------------------------===// 16 17#include "Passes.h" 18#include "llvm/Analysis/CGSCCPassManager.h" 19#include "llvm/Analysis/LazyCallGraph.h" 20#include "llvm/IR/IRPrintingPasses.h" 21#include "llvm/IR/PassManager.h" 22#include "llvm/IR/Verifier.h" 23#include "llvm/Support/Debug.h" 24 25using namespace llvm; 26 27namespace { 28 29/// \brief No-op module pass which does nothing. 30struct NoOpModulePass { 31 PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); } 32 static StringRef name() { return "NoOpModulePass"; } 33}; 34 35/// \brief No-op CGSCC pass which does nothing. 36struct NoOpCGSCCPass { 37 PreservedAnalyses run(LazyCallGraph::SCC *C) { 38 return PreservedAnalyses::all(); 39 } 40 static StringRef name() { return "NoOpCGSCCPass"; } 41}; 42 43/// \brief No-op function pass which does nothing. 44struct NoOpFunctionPass { 45 PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } 46 static StringRef name() { return "NoOpFunctionPass"; } 47}; 48 49} // End anonymous namespace. 50 51static bool isModulePassName(StringRef Name) { 52 if (Name == "no-op-module") return true; 53 54#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; 55#include "PassRegistry.def" 56 57 return false; 58} 59 60static bool isCGSCCPassName(StringRef Name) { 61 if (Name == "no-op-cgscc") return true; 62 63#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; 64#include "PassRegistry.def" 65 66 return false; 67} 68 69static bool isFunctionPassName(StringRef Name) { 70 if (Name == "no-op-function") return true; 71 72#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; 73#include "PassRegistry.def" 74 75 return false; 76} 77 78static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { 79 if (Name == "no-op-module") { 80 MPM.addPass(NoOpModulePass()); 81 return true; 82 } 83 84#define MODULE_PASS(NAME, CREATE_PASS) \ 85 if (Name == NAME) { \ 86 MPM.addPass(CREATE_PASS); \ 87 return true; \ 88 } 89#include "PassRegistry.def" 90 91 return false; 92} 93 94static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { 95 if (Name == "no-op-cgscc") { 96 CGPM.addPass(NoOpCGSCCPass()); 97 return true; 98 } 99 100#define CGSCC_PASS(NAME, CREATE_PASS) \ 101 if (Name == NAME) { \ 102 CGPM.addPass(CREATE_PASS); \ 103 return true; \ 104 } 105#include "PassRegistry.def" 106 107 return false; 108} 109 110static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { 111 if (Name == "no-op-function") { 112 FPM.addPass(NoOpFunctionPass()); 113 return true; 114 } 115 116#define FUNCTION_PASS(NAME, CREATE_PASS) \ 117 if (Name == NAME) { \ 118 FPM.addPass(CREATE_PASS); \ 119 return true; \ 120 } 121#include "PassRegistry.def" 122 123 return false; 124} 125 126static bool parseFunctionPassPipeline(FunctionPassManager &FPM, 127 StringRef &PipelineText, 128 bool VerifyEachPass) { 129 for (;;) { 130 // Parse nested pass managers by recursing. 131 if (PipelineText.startswith("function(")) { 132 FunctionPassManager NestedFPM; 133 134 // Parse the inner pipeline inte the nested manager. 135 PipelineText = PipelineText.substr(strlen("function(")); 136 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || 137 PipelineText.empty()) 138 return false; 139 assert(PipelineText[0] == ')'); 140 PipelineText = PipelineText.substr(1); 141 142 // Add the nested pass manager with the appropriate adaptor. 143 FPM.addPass(std::move(NestedFPM)); 144 } else { 145 // Otherwise try to parse a pass name. 146 size_t End = PipelineText.find_first_of(",)"); 147 if (!parseFunctionPassName(FPM, PipelineText.substr(0, End))) 148 return false; 149 if (VerifyEachPass) 150 FPM.addPass(VerifierPass()); 151 152 PipelineText = PipelineText.substr(End); 153 } 154 155 if (PipelineText.empty() || PipelineText[0] == ')') 156 return true; 157 158 assert(PipelineText[0] == ','); 159 PipelineText = PipelineText.substr(1); 160 } 161} 162 163static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, 164 StringRef &PipelineText, 165 bool VerifyEachPass) { 166 for (;;) { 167 // Parse nested pass managers by recursing. 168 if (PipelineText.startswith("cgscc(")) { 169 CGSCCPassManager NestedCGPM; 170 171 // Parse the inner pipeline into the nested manager. 172 PipelineText = PipelineText.substr(strlen("cgscc(")); 173 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || 174 PipelineText.empty()) 175 return false; 176 assert(PipelineText[0] == ')'); 177 PipelineText = PipelineText.substr(1); 178 179 // Add the nested pass manager with the appropriate adaptor. 180 CGPM.addPass(std::move(NestedCGPM)); 181 } else if (PipelineText.startswith("function(")) { 182 FunctionPassManager NestedFPM; 183 184 // Parse the inner pipeline inte the nested manager. 185 PipelineText = PipelineText.substr(strlen("function(")); 186 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || 187 PipelineText.empty()) 188 return false; 189 assert(PipelineText[0] == ')'); 190 PipelineText = PipelineText.substr(1); 191 192 // Add the nested pass manager with the appropriate adaptor. 193 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM))); 194 } else { 195 // Otherwise try to parse a pass name. 196 size_t End = PipelineText.find_first_of(",)"); 197 if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End))) 198 return false; 199 // FIXME: No verifier support for CGSCC passes! 200 201 PipelineText = PipelineText.substr(End); 202 } 203 204 if (PipelineText.empty() || PipelineText[0] == ')') 205 return true; 206 207 assert(PipelineText[0] == ','); 208 PipelineText = PipelineText.substr(1); 209 } 210} 211 212static bool parseModulePassPipeline(ModulePassManager &MPM, 213 StringRef &PipelineText, 214 bool VerifyEachPass) { 215 for (;;) { 216 // Parse nested pass managers by recursing. 217 if (PipelineText.startswith("module(")) { 218 ModulePassManager NestedMPM; 219 220 // Parse the inner pipeline into the nested manager. 221 PipelineText = PipelineText.substr(strlen("module(")); 222 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) || 223 PipelineText.empty()) 224 return false; 225 assert(PipelineText[0] == ')'); 226 PipelineText = PipelineText.substr(1); 227 228 // Now add the nested manager as a module pass. 229 MPM.addPass(std::move(NestedMPM)); 230 } else if (PipelineText.startswith("cgscc(")) { 231 CGSCCPassManager NestedCGPM; 232 233 // Parse the inner pipeline inte the nested manager. 234 PipelineText = PipelineText.substr(strlen("cgscc(")); 235 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || 236 PipelineText.empty()) 237 return false; 238 assert(PipelineText[0] == ')'); 239 PipelineText = PipelineText.substr(1); 240 241 // Add the nested pass manager with the appropriate adaptor. 242 MPM.addPass( 243 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM))); 244 } else if (PipelineText.startswith("function(")) { 245 FunctionPassManager NestedFPM; 246 247 // Parse the inner pipeline inte the nested manager. 248 PipelineText = PipelineText.substr(strlen("function(")); 249 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || 250 PipelineText.empty()) 251 return false; 252 assert(PipelineText[0] == ')'); 253 PipelineText = PipelineText.substr(1); 254 255 // Add the nested pass manager with the appropriate adaptor. 256 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM))); 257 } else { 258 // Otherwise try to parse a pass name. 259 size_t End = PipelineText.find_first_of(",)"); 260 if (!parseModulePassName(MPM, PipelineText.substr(0, End))) 261 return false; 262 if (VerifyEachPass) 263 MPM.addPass(VerifierPass()); 264 265 PipelineText = PipelineText.substr(End); 266 } 267 268 if (PipelineText.empty() || PipelineText[0] == ')') 269 return true; 270 271 assert(PipelineText[0] == ','); 272 PipelineText = PipelineText.substr(1); 273 } 274} 275 276// Primary pass pipeline description parsing routine. 277// FIXME: Should this routine accept a TargetMachine or require the caller to 278// pre-populate the analysis managers with target-specific stuff? 279bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, 280 bool VerifyEachPass) { 281 // Look at the first entry to figure out which layer to start parsing at. 282 if (PipelineText.startswith("module(")) 283 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && 284 PipelineText.empty(); 285 if (PipelineText.startswith("cgscc(")) { 286 CGSCCPassManager CGPM; 287 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || 288 !PipelineText.empty()) 289 return false; 290 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); 291 return true; 292 } 293 if (PipelineText.startswith("function(")) { 294 FunctionPassManager FPM; 295 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || 296 !PipelineText.empty()) 297 return false; 298 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 299 return true; 300 } 301 302 // This isn't a direct pass manager name, look for the end of a pass name. 303 StringRef FirstName = 304 PipelineText.substr(0, PipelineText.find_first_of(",)")); 305 if (isModulePassName(FirstName)) 306 return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && 307 PipelineText.empty(); 308 309 if (isCGSCCPassName(FirstName)) { 310 CGSCCPassManager CGPM; 311 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || 312 !PipelineText.empty()) 313 return false; 314 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); 315 return true; 316 } 317 318 if (isFunctionPassName(FirstName)) { 319 FunctionPassManager FPM; 320 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || 321 !PipelineText.empty()) 322 return false; 323 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 324 return true; 325 } 326 327 return false; 328} 329