1263508Sdim//===- PassManager.h - Infrastructure for managing & running IR passes ----===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim 10263508Sdim#include "llvm/IR/PassManager.h" 11263508Sdim#include "llvm/ADT/STLExtras.h" 12249259Sdim 13249259Sdimusing namespace llvm; 14249259Sdim 15263508Sdimvoid ModulePassManager::run() { 16263508Sdim for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) 17263508Sdim if (Passes[Idx]->run(M)) 18263508Sdim if (AM) AM->invalidateAll(M); 19249259Sdim} 20249259Sdim 21263508Sdimbool FunctionPassManager::run(Module *M) { 22263508Sdim bool Changed = false; 23263508Sdim for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 24263508Sdim for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) 25263508Sdim if (Passes[Idx]->run(I)) { 26263508Sdim Changed = true; 27263508Sdim if (AM) AM->invalidateAll(I); 28249259Sdim } 29263508Sdim return Changed; 30249259Sdim} 31249259Sdim 32263508Sdimvoid AnalysisManager::invalidateAll(Function *F) { 33263508Sdim assert(F->getParent() == M && "Invalidating a function from another module!"); 34249259Sdim 35263508Sdim // First invalidate any module results we still have laying about. 36263508Sdim // FIXME: This is a total hack based on the fact that erasure doesn't 37263508Sdim // invalidate iteration for DenseMap. 38263508Sdim for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), 39263508Sdim E = ModuleAnalysisResults.end(); 40249259Sdim I != E; ++I) 41263508Sdim if (I->second->invalidate(M)) 42263508Sdim ModuleAnalysisResults.erase(I); 43249259Sdim 44263508Sdim // Now clear all the invalidated results associated specifically with this 45263508Sdim // function. 46263508Sdim SmallVector<void *, 8> InvalidatedPassIDs; 47263508Sdim FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; 48263508Sdim for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), 49263508Sdim E = ResultsList.end(); 50263508Sdim I != E;) 51263508Sdim if (I->second->invalidate(F)) { 52263508Sdim InvalidatedPassIDs.push_back(I->first); 53263508Sdim I = ResultsList.erase(I); 54249259Sdim } else { 55263508Sdim ++I; 56249259Sdim } 57263508Sdim while (!InvalidatedPassIDs.empty()) 58263508Sdim FunctionAnalysisResults.erase( 59263508Sdim std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); 60249259Sdim} 61249259Sdim 62263508Sdimvoid AnalysisManager::invalidateAll(Module *M) { 63263508Sdim // First invalidate any module results we still have laying about. 64263508Sdim // FIXME: This is a total hack based on the fact that erasure doesn't 65263508Sdim // invalidate iteration for DenseMap. 66263508Sdim for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), 67263508Sdim E = ModuleAnalysisResults.end(); 68263508Sdim I != E; ++I) 69263508Sdim if (I->second->invalidate(M)) 70263508Sdim ModuleAnalysisResults.erase(I); 71249259Sdim 72263508Sdim // Now walk all of the functions for which there are cached results, and 73263508Sdim // attempt to invalidate each of those as the entire module may have changed. 74263508Sdim // FIXME: How do we handle functions which have been deleted or RAUWed? 75263508Sdim SmallVector<void *, 8> InvalidatedPassIDs; 76263508Sdim for (FunctionAnalysisResultListMapT::iterator 77263508Sdim FI = FunctionAnalysisResultLists.begin(), 78263508Sdim FE = FunctionAnalysisResultLists.end(); 79263508Sdim FI != FE; ++FI) { 80263508Sdim Function *F = FI->first; 81263508Sdim FunctionAnalysisResultListT &ResultsList = FI->second; 82263508Sdim for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), 83263508Sdim E = ResultsList.end(); 84263508Sdim I != E;) 85263508Sdim if (I->second->invalidate(F)) { 86263508Sdim InvalidatedPassIDs.push_back(I->first); 87263508Sdim I = ResultsList.erase(I); 88263508Sdim } else { 89263508Sdim ++I; 90249259Sdim } 91263508Sdim while (!InvalidatedPassIDs.empty()) 92263508Sdim FunctionAnalysisResults.erase( 93263508Sdim std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); 94249259Sdim } 95249259Sdim} 96249259Sdim 97263508Sdimconst AnalysisManager::AnalysisResultConcept<Module> & 98263508SdimAnalysisManager::getResultImpl(void *PassID, Module *M) { 99263508Sdim assert(M == this->M && "Wrong module used when querying the AnalysisManager"); 100263508Sdim ModuleAnalysisResultMapT::iterator RI; 101263508Sdim bool Inserted; 102263508Sdim llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( 103263508Sdim PassID, polymorphic_ptr<AnalysisResultConcept<Module> >())); 104249259Sdim 105263508Sdim if (Inserted) { 106263508Sdim // We don't have a cached result for this result. Look up the pass and run 107263508Sdim // it to produce a result, which we then add to the cache. 108263508Sdim ModuleAnalysisPassMapT::const_iterator PI = 109263508Sdim ModuleAnalysisPasses.find(PassID); 110263508Sdim assert(PI != ModuleAnalysisPasses.end() && 111263508Sdim "Analysis passes must be registered prior to being queried!"); 112263508Sdim RI->second = PI->second->run(M); 113249259Sdim } 114249259Sdim 115263508Sdim return *RI->second; 116249259Sdim} 117249259Sdim 118263508Sdimconst AnalysisManager::AnalysisResultConcept<Function> & 119263508SdimAnalysisManager::getResultImpl(void *PassID, Function *F) { 120263508Sdim assert(F->getParent() == M && "Analyzing a function from another module!"); 121249259Sdim 122263508Sdim FunctionAnalysisResultMapT::iterator RI; 123263508Sdim bool Inserted; 124263508Sdim llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( 125263508Sdim std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); 126249259Sdim 127263508Sdim if (Inserted) { 128263508Sdim // We don't have a cached result for this result. Look up the pass and run 129263508Sdim // it to produce a result, which we then add to the cache. 130263508Sdim FunctionAnalysisPassMapT::const_iterator PI = 131263508Sdim FunctionAnalysisPasses.find(PassID); 132263508Sdim assert(PI != FunctionAnalysisPasses.end() && 133263508Sdim "Analysis passes must be registered prior to being queried!"); 134263508Sdim FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; 135263508Sdim ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); 136263508Sdim RI->second = llvm::prior(ResultList.end()); 137249259Sdim } 138249259Sdim 139263508Sdim return *RI->second->second; 140249259Sdim} 141249259Sdim 142263508Sdimvoid AnalysisManager::invalidateImpl(void *PassID, Module *M) { 143263508Sdim assert(M == this->M && "Invalidating a pass over a different module!"); 144263508Sdim ModuleAnalysisResults.erase(PassID); 145249259Sdim} 146249259Sdim 147263508Sdimvoid AnalysisManager::invalidateImpl(void *PassID, Function *F) { 148263508Sdim assert(F->getParent() == M && 149263508Sdim "Invalidating a pass over a function from another module!"); 150249259Sdim 151263508Sdim FunctionAnalysisResultMapT::iterator RI = 152263508Sdim FunctionAnalysisResults.find(std::make_pair(PassID, F)); 153263508Sdim if (RI == FunctionAnalysisResults.end()) 154249259Sdim return; 155249259Sdim 156263508Sdim FunctionAnalysisResultLists[F].erase(RI->second); 157249259Sdim} 158