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 13 using namespace llvm; 14 15 PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { 16 PreservedAnalyses PA = PreservedAnalyses::all(); 17 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { 18 PreservedAnalyses PassPA = Passes[Idx]->run(M, AM); 19 if (AM) 20 AM->invalidate(M, PassPA); 21 PA.intersect(llvm_move(PassPA)); 22 } 23 return PA; 24 } 25 26 const ModuleAnalysisManager::ResultConceptT & 27 ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { 28 ModuleAnalysisResultMapT::iterator RI; 29 bool Inserted; 30 llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( 31 PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module *> >())); 32 33 // If we don't have a cached result for this module, look up the pass and run 34 // it to produce a result, which we then add to the cache. 35 if (Inserted) 36 RI->second = lookupPass(PassID).run(M, this); 37 38 return *RI->second; 39 } 40 41 const ModuleAnalysisManager::ResultConceptT * 42 ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const { 43 ModuleAnalysisResultMapT::const_iterator RI = ModuleAnalysisResults.find(PassID); 44 return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second; 45 } 46 47 void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { 48 ModuleAnalysisResults.erase(PassID); 49 } 50 51 void ModuleAnalysisManager::invalidateImpl(Module *M, 52 const PreservedAnalyses &PA) { 53 // FIXME: This is a total hack based on the fact that erasure doesn't 54 // invalidate iteration for DenseMap. 55 for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), 56 E = ModuleAnalysisResults.end(); 57 I != E; ++I) 58 if (I->second->invalidate(M, PA)) 59 ModuleAnalysisResults.erase(I); 60 } 61 62 PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager *AM) { 63 PreservedAnalyses PA = PreservedAnalyses::all(); 64 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { 65 PreservedAnalyses PassPA = Passes[Idx]->run(F, AM); 66 if (AM) 67 AM->invalidate(F, PassPA); 68 PA.intersect(llvm_move(PassPA)); 69 } 70 return PA; 71 } 72 73 bool FunctionAnalysisManager::empty() const { 74 assert(FunctionAnalysisResults.empty() == 75 FunctionAnalysisResultLists.empty() && 76 "The storage and index of analysis results disagree on how many there " 77 "are!"); 78 return FunctionAnalysisResults.empty(); 79 } 80 81 void FunctionAnalysisManager::clear() { 82 FunctionAnalysisResults.clear(); 83 FunctionAnalysisResultLists.clear(); 84 } 85 86 const FunctionAnalysisManager::ResultConceptT & 87 FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { 88 FunctionAnalysisResultMapT::iterator RI; 89 bool Inserted; 90 llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( 91 std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); 92 93 // If we don't have a cached result for this function, look up the pass and 94 // run it to produce a result, which we then add to the cache. 95 if (Inserted) { 96 FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; 97 ResultList.push_back(std::make_pair(PassID, lookupPass(PassID).run(F, this))); 98 RI->second = llvm::prior(ResultList.end()); 99 } 100 101 return *RI->second->second; 102 } 103 104 const FunctionAnalysisManager::ResultConceptT * 105 FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const { 106 FunctionAnalysisResultMapT::const_iterator RI = 107 FunctionAnalysisResults.find(std::make_pair(PassID, F)); 108 return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second; 109 } 110 111 void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { 112 FunctionAnalysisResultMapT::iterator RI = 113 FunctionAnalysisResults.find(std::make_pair(PassID, F)); 114 if (RI == FunctionAnalysisResults.end()) 115 return; 116 117 FunctionAnalysisResultLists[F].erase(RI->second); 118 } 119 120 void FunctionAnalysisManager::invalidateImpl(Function *F, 121 const PreservedAnalyses &PA) { 122 // Clear all the invalidated results associated specifically with this 123 // function. 124 SmallVector<void *, 8> InvalidatedPassIDs; 125 FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; 126 for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), 127 E = ResultsList.end(); 128 I != E;) 129 if (I->second->invalidate(F, PA)) { 130 InvalidatedPassIDs.push_back(I->first); 131 I = ResultsList.erase(I); 132 } else { 133 ++I; 134 } 135 while (!InvalidatedPassIDs.empty()) 136 FunctionAnalysisResults.erase( 137 std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); 138 } 139 140 char FunctionAnalysisManagerModuleProxy::PassID; 141 142 FunctionAnalysisManagerModuleProxy::Result 143 FunctionAnalysisManagerModuleProxy::run(Module *M) { 144 assert(FAM.empty() && "Function analyses ran prior to the module proxy!"); 145 return Result(FAM); 146 } 147 148 FunctionAnalysisManagerModuleProxy::Result::~Result() { 149 // Clear out the analysis manager if we're being destroyed -- it means we 150 // didn't even see an invalidate call when we got invalidated. 151 FAM.clear(); 152 } 153 154 bool FunctionAnalysisManagerModuleProxy::Result::invalidate( 155 Module *M, const PreservedAnalyses &PA) { 156 // If this proxy isn't marked as preserved, then we can't even invalidate 157 // individual function analyses, there may be an invalid set of Function 158 // objects in the cache making it impossible to incrementally preserve them. 159 // Just clear the entire manager. 160 if (!PA.preserved(ID())) 161 FAM.clear(); 162 163 // Return false to indicate that this result is still a valid proxy. 164 return false; 165 } 166 167 char ModuleAnalysisManagerFunctionProxy::PassID; 168