PassManager.cpp revision c67c938de2097f26dba71d9436e4707dd8a5012d
1//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Devang Patel and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the LLVM Pass Manager infrastructure. 11// 12//===----------------------------------------------------------------------===// 13 14 15#include "llvm/PassManager.h" 16#include "llvm/Module.h" 17 18using namespace llvm; 19 20namespace llvm { 21 22/// BasicBlockPassManager_New manages BasicBlockPass. It batches all the 23/// pass together and sequence them to process one basic block before 24/// processing next basic block. 25class BasicBlockPassManager_New : public Pass, 26 public PassManagerAnalysisHelper { 27 28public: 29 BasicBlockPassManager_New() { } 30 31 /// Add a pass into a passmanager queue. 32 bool addPass(Pass *p); 33 34 /// Execute all of the passes scheduled for execution. Keep track of 35 /// whether any of the passes modifies the function, and if so, return true. 36 bool runOnFunction(Function &F); 37 38private: 39 // Collection of pass that are managed by this manager 40 std::vector<Pass *> PassVector; 41}; 42 43/// FunctionPassManager_New manages FunctionPasses and BasicBlockPassManagers. 44/// It batches all function passes and basic block pass managers together and 45/// sequence them to process one function at a time before processing next 46/// function. 47class FunctionPassManager_New : public Pass, 48 public PassManagerAnalysisHelper { 49public: 50 FunctionPassManager_New(ModuleProvider *P) { /* TODO */ } 51 FunctionPassManager_New() { 52 activeBBPassManager = NULL; 53 } 54 ~FunctionPassManager_New() { /* TODO */ }; 55 56 /// add - Add a pass to the queue of passes to run. This passes 57 /// ownership of the Pass to the PassManager. When the 58 /// PassManager_X is destroyed, the pass will be destroyed as well, so 59 /// there is no need to delete the pass. (TODO delete passes.) 60 /// This implies that all passes MUST be allocated with 'new'. 61 void add(Pass *P) { /* TODO*/ } 62 63 /// Add pass into the pass manager queue. 64 bool addPass(Pass *P); 65 66 /// Execute all of the passes scheduled for execution. Keep 67 /// track of whether any of the passes modifies the function, and if 68 /// so, return true. 69 bool runOnModule(Module &M); 70 71private: 72 // Collection of pass that are manged by this manager 73 std::vector<Pass *> PassVector; 74 75 // Active Pass Managers 76 BasicBlockPassManager_New *activeBBPassManager; 77}; 78 79/// ModulePassManager_New manages ModulePasses and function pass managers. 80/// It batches all Module passes passes and function pass managers together and 81/// sequence them to process one module. 82class ModulePassManager_New : public Pass, 83 public PassManagerAnalysisHelper { 84 85public: 86 ModulePassManager_New() { activeFunctionPassManager = NULL; } 87 88 /// Add a pass into a passmanager queue. 89 bool addPass(Pass *p); 90 91 /// run - Execute all of the passes scheduled for execution. Keep track of 92 /// whether any of the passes modifies the module, and if so, return true. 93 bool runOnModule(Module &M); 94 95private: 96 // Collection of pass that are managed by this manager 97 std::vector<Pass *> PassVector; 98 99 // Active Pass Manager 100 FunctionPassManager_New *activeFunctionPassManager; 101}; 102 103} // End of llvm namespace 104 105// PassManagerAnalysisHelper implementation 106 107/// Return true IFF pass P's required analysis set does not required new 108/// manager. 109bool PassManagerAnalysisHelper::manageablePass(Pass *P) { 110 111 AnalysisUsage AnUsage; 112 P->getAnalysisUsage(AnUsage); 113 114 // If this pass is not preserving information that is required by the other passes 115 // managed by this manager then use new manager 116 // TODO 117 return true; 118} 119 120/// Return true IFF AnalysisID AID is currently available. 121bool PassManagerAnalysisHelper::analysisCurrentlyAvailable(AnalysisID AID) { 122 123 // TODO 124 return false; 125} 126 127/// Augment RequiredSet by adding analysis required by pass P. 128void PassManagerAnalysisHelper::noteDownRequiredAnalysis(Pass *P) { 129 130 // TODO 131} 132 133/// Remove AnalysisID from the RequiredSet 134void PassManagerAnalysisHelper::removeAnalysis(AnalysisID AID) { 135 136 // TODO 137} 138 139/// Remove Analyss not preserved by Pass P 140void PassManagerAnalysisHelper::removeNotPreservedAnalysis(Pass *P) { 141 142 // TODO 143} 144 145/// BasicBlockPassManager implementation 146 147/// Add pass P into PassVector and return true. If this pass is not 148/// manageable by this manager then return false. 149bool 150BasicBlockPassManager_New::addPass(Pass *P) { 151 152 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P); 153 if (!BP) 154 return false; 155 156 // If this pass does not preserve anlysis that is used by other passes 157 // managed by this manager than it is not a suiable pass for this manager. 158 if (!manageablePass(P)) 159 return false; 160 161 // Take a note of analysis required by this pass. 162 noteDownRequiredAnalysis(P); 163 164 // Add pass 165 PassVector.push_back(BP); 166 return true; 167} 168 169/// Execute all of the passes scheduled for execution by invoking 170/// runOnBasicBlock method. Keep track of whether any of the passes modifies 171/// the function, and if so, return true. 172bool 173BasicBlockPassManager_New::runOnFunction(Function &F) { 174 175 bool Changed = false; 176 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) 177 for (std::vector<Pass *>::iterator itr = PassVector.begin(), 178 e = PassVector.end(); itr != e; ++itr) { 179 Pass *P = *itr; 180 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P); 181 Changed |= BP->runOnBasicBlock(*I); 182 } 183 return Changed; 184} 185 186// FunctionPassManager_New implementation 187 188// FunctionPassManager 189 190/// Add pass P into the pass manager queue. If P is a BasicBlockPass then 191/// either use it into active basic block pass manager or create new basic 192/// block pass manager to handle pass P. 193bool 194FunctionPassManager_New::addPass(Pass *P) { 195 196 // If P is a BasicBlockPass then use BasicBlockPassManager_New. 197 if (BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P)) { 198 199 if (!activeBBPassManager 200 || !activeBBPassManager->addPass(BP)) { 201 202 activeBBPassManager = new BasicBlockPassManager_New(); 203 204 PassVector.push_back(activeBBPassManager); 205 if (!activeBBPassManager->addPass(BP)) 206 assert(0 && "Unable to add Pass"); 207 } 208 return true; 209 } 210 211 FunctionPass *FP = dynamic_cast<FunctionPass *>(P); 212 if (!FP) 213 return false; 214 215 // If this pass does not preserve anlysis that is used by other passes 216 // managed by this manager than it is not a suiable pass for this manager. 217 if (!manageablePass(P)) 218 return false; 219 220 // Take a note of analysis required by this pass. 221 noteDownRequiredAnalysis(P); 222 223 PassVector.push_back(FP); 224 activeBBPassManager = NULL; 225 return true; 226} 227 228/// Execute all of the passes scheduled for execution by invoking 229/// runOnFunction method. Keep track of whether any of the passes modifies 230/// the function, and if so, return true. 231bool 232FunctionPassManager_New::runOnModule(Module &M) { 233 234 bool Changed = false; 235 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 236 for (std::vector<Pass *>::iterator itr = PassVector.begin(), 237 e = PassVector.end(); itr != e; ++itr) { 238 Pass *P = *itr; 239 FunctionPass *FP = dynamic_cast<FunctionPass*>(P); 240 Changed |= FP->runOnFunction(*I); 241 } 242 return Changed; 243} 244 245 246// ModulePassManager implementation 247 248/// Add P into pass vector if it is manageble. If P is a FunctionPass 249/// then use FunctionPassManager_New to manage it. Return false if P 250/// is not manageable by this manager. 251bool 252ModulePassManager_New::addPass(Pass *P) { 253 254 // If P is FunctionPass then use function pass maanager. 255 if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P)) { 256 257 activeFunctionPassManager = NULL; 258 259 if (!activeFunctionPassManager 260 || !activeFunctionPassManager->addPass(P)) { 261 262 activeFunctionPassManager = new FunctionPassManager_New(); 263 264 PassVector.push_back(activeFunctionPassManager); 265 if (!activeFunctionPassManager->addPass(FP)) 266 assert(0 && "Unable to add pass"); 267 } 268 return true; 269 } 270 271 ModulePass *MP = dynamic_cast<ModulePass *>(P); 272 if (!MP) 273 return false; 274 275 // If this pass does not preserve anlysis that is used by other passes 276 // managed by this manager than it is not a suiable pass for this manager. 277 if (!manageablePass(P)) 278 return false; 279 280 // Take a note of analysis required by this pass. 281 noteDownRequiredAnalysis(P); 282 283 PassVector.push_back(MP); 284 activeFunctionPassManager = NULL; 285 return true; 286} 287 288 289/// Execute all of the passes scheduled for execution by invoking 290/// runOnModule method. Keep track of whether any of the passes modifies 291/// the module, and if so, return true. 292bool 293ModulePassManager_New::runOnModule(Module &M) { 294 bool Changed = false; 295 for (std::vector<Pass *>::iterator itr = PassVector.begin(), 296 e = PassVector.end(); itr != e; ++itr) { 297 Pass *P = *itr; 298 ModulePass *MP = dynamic_cast<ModulePass*>(P); 299 Changed |= MP->runOnModule(M); 300 } 301 return Changed; 302} 303 304/// Schedule all passes from the queue by adding them in their 305/// respective manager's queue. 306void 307PassManager_New::schedulePasses() { 308 /* TODO */ 309} 310 311/// Add pass P to the queue of passes to run. 312void 313PassManager_New::add(Pass *P) { 314 /* TODO */ 315} 316 317// PassManager_New implementation 318/// Add P into active pass manager or use new module pass manager to 319/// manage it. 320bool 321PassManager_New::addPass(Pass *P) { 322 323 if (!activeManager) { 324 activeManager = new ModulePassManager_New(); 325 PassManagers.push_back(activeManager); 326 } 327 328 return activeManager->addPass(P); 329} 330 331/// run - Execute all of the passes scheduled for execution. Keep track of 332/// whether any of the passes modifies the module, and if so, return true. 333bool 334PassManager_New::run(Module &M) { 335 336 schedulePasses(); 337 bool Changed = false; 338 for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(), 339 e = PassManagers.end(); itr != e; ++itr) { 340 ModulePassManager_New *pm = *itr; 341 Changed |= pm->runOnModule(M); 342 } 343 return Changed; 344} 345