1//===- PassManager.h - Infrastructure for managing & running IR 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 10#include "llvm/IR/PassManager.h" 11#include "llvm/ADT/STLExtras.h" 12 13using namespace llvm; 14 15void ModulePassManager::run() { 16 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) 17 if (Passes[Idx]->run(M)) 18 if (AM) AM->invalidateAll(M); 19} 20 21bool FunctionPassManager::run(Module *M) { 22 bool Changed = false; 23 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 24 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) 25 if (Passes[Idx]->run(I)) { 26 Changed = true; 27 if (AM) AM->invalidateAll(I); 28 } 29 return Changed; 30} 31 32void AnalysisManager::invalidateAll(Function *F) { 33 assert(F->getParent() == M && "Invalidating a function from another module!"); 34 35 // First invalidate any module results we still have laying about. 36 // FIXME: This is a total hack based on the fact that erasure doesn't 37 // invalidate iteration for DenseMap. 38 for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), 39 E = ModuleAnalysisResults.end(); 40 I != E; ++I) 41 if (I->second->invalidate(M)) 42 ModuleAnalysisResults.erase(I); 43 44 // Now clear all the invalidated results associated specifically with this 45 // function. 46 SmallVector<void *, 8> InvalidatedPassIDs; 47 FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; 48 for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), 49 E = ResultsList.end(); 50 I != E;) 51 if (I->second->invalidate(F)) { 52 InvalidatedPassIDs.push_back(I->first); 53 I = ResultsList.erase(I); 54 } else { 55 ++I; 56 } 57 while (!InvalidatedPassIDs.empty()) 58 FunctionAnalysisResults.erase( 59 std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); 60} 61 62void AnalysisManager::invalidateAll(Module *M) { 63 // First invalidate any module results we still have laying about. 64 // FIXME: This is a total hack based on the fact that erasure doesn't 65 // invalidate iteration for DenseMap. 66 for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), 67 E = ModuleAnalysisResults.end(); 68 I != E; ++I) 69 if (I->second->invalidate(M)) 70 ModuleAnalysisResults.erase(I); 71 72 // Now walk all of the functions for which there are cached results, and 73 // attempt to invalidate each of those as the entire module may have changed. 74 // FIXME: How do we handle functions which have been deleted or RAUWed? 75 SmallVector<void *, 8> InvalidatedPassIDs; 76 for (FunctionAnalysisResultListMapT::iterator 77 FI = FunctionAnalysisResultLists.begin(), 78 FE = FunctionAnalysisResultLists.end(); 79 FI != FE; ++FI) { 80 Function *F = FI->first; 81 FunctionAnalysisResultListT &ResultsList = FI->second; 82 for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), 83 E = ResultsList.end(); 84 I != E;) 85 if (I->second->invalidate(F)) { 86 InvalidatedPassIDs.push_back(I->first); 87 I = ResultsList.erase(I); 88 } else { 89 ++I; 90 } 91 while (!InvalidatedPassIDs.empty()) 92 FunctionAnalysisResults.erase( 93 std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); 94 } 95} 96 97const AnalysisManager::AnalysisResultConcept<Module> & 98AnalysisManager::getResultImpl(void *PassID, Module *M) { 99 assert(M == this->M && "Wrong module used when querying the AnalysisManager"); 100 ModuleAnalysisResultMapT::iterator RI; 101 bool Inserted; 102 llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( 103 PassID, polymorphic_ptr<AnalysisResultConcept<Module> >())); 104 105 if (Inserted) { 106 // We don't have a cached result for this result. Look up the pass and run 107 // it to produce a result, which we then add to the cache. 108 ModuleAnalysisPassMapT::const_iterator PI = 109 ModuleAnalysisPasses.find(PassID); 110 assert(PI != ModuleAnalysisPasses.end() && 111 "Analysis passes must be registered prior to being queried!"); 112 RI->second = PI->second->run(M); 113 } 114 115 return *RI->second; 116} 117 118const AnalysisManager::AnalysisResultConcept<Function> & 119AnalysisManager::getResultImpl(void *PassID, Function *F) { 120 assert(F->getParent() == M && "Analyzing a function from another module!"); 121 122 FunctionAnalysisResultMapT::iterator RI; 123 bool Inserted; 124 llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( 125 std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); 126 127 if (Inserted) { 128 // We don't have a cached result for this result. Look up the pass and run 129 // it to produce a result, which we then add to the cache. 130 FunctionAnalysisPassMapT::const_iterator PI = 131 FunctionAnalysisPasses.find(PassID); 132 assert(PI != FunctionAnalysisPasses.end() && 133 "Analysis passes must be registered prior to being queried!"); 134 FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; 135 ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); 136 RI->second = llvm::prior(ResultList.end()); 137 } 138 139 return *RI->second->second; 140} 141 142void AnalysisManager::invalidateImpl(void *PassID, Module *M) { 143 assert(M == this->M && "Invalidating a pass over a different module!"); 144 ModuleAnalysisResults.erase(PassID); 145} 146 147void AnalysisManager::invalidateImpl(void *PassID, Function *F) { 148 assert(F->getParent() == M && 149 "Invalidating a pass over a function from another module!"); 150 151 FunctionAnalysisResultMapT::iterator RI = 152 FunctionAnalysisResults.find(std::make_pair(PassID, F)); 153 if (RI == FunctionAnalysisResults.end()) 154 return; 155 156 FunctionAnalysisResultLists[F].erase(RI->second); 157} 158