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