X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FPassManager.cpp;h=2e2a7cb4956c05a6fc2cc9ab73fd709ce1983311;hb=7af88ec907537f9a5de343d439fbca1344f28a29;hp=b53a2b9671d93bc7c9244f0f0afa1aa4bc4a52c3;hpb=523d929368829b5157748f46f85b4577b7fd6ca1;p=oota-llvm.git diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index b53a2b9671d..2e2a7cb4956 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -1,4 +1,4 @@ -//===- PassManager.h - Infrastructure for managing & running IR passes ----===// +//===- PassManager.cpp - Infrastructure for managing & running IR passes --===// // // The LLVM Compiler Infrastructure // @@ -7,65 +7,153 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/PassManager.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" using namespace llvm; -void ModulePassManager::run(Module *M) { - for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) - if (Passes[Idx]->run(M)) - if (AM) - AM->invalidateAll(M); +static cl::opt +DebugPM("debug-pass-manager", cl::Hidden, + cl::desc("Print pass management debugging information")); + +PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { + PreservedAnalyses PA = PreservedAnalyses::all(); + + if (DebugPM) + dbgs() << "Starting module pass manager run.\n"; + + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { + if (DebugPM) + dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n"; + + PreservedAnalyses PassPA = Passes[Idx]->run(M, AM); + if (AM) + AM->invalidate(M, PassPA); + PA.intersect(std::move(PassPA)); + + M->getContext().yield(); + } + + if (DebugPM) + dbgs() << "Finished module pass manager run.\n"; + + return PA; +} + +ModuleAnalysisManager::ResultConceptT & +ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { + ModuleAnalysisResultMapT::iterator RI; + bool Inserted; + std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( + PassID, std::unique_ptr>())); + + // If we don't have a cached result for this module, look up the pass and run + // it to produce a result, which we then add to the cache. + if (Inserted) + RI->second = lookupPass(PassID).run(M, this); + + return *RI->second; +} + +ModuleAnalysisManager::ResultConceptT * +ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const { + ModuleAnalysisResultMapT::const_iterator RI = + ModuleAnalysisResults.find(PassID); + return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second; } -void ModuleAnalysisManager::invalidateAll(Module *M) { +void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { + ModuleAnalysisResults.erase(PassID); +} + +void ModuleAnalysisManager::invalidateImpl(Module *M, + const PreservedAnalyses &PA) { // FIXME: This is a total hack based on the fact that erasure doesn't // invalidate iteration for DenseMap. for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), E = ModuleAnalysisResults.end(); I != E; ++I) - if (I->second->invalidate(M)) + if (I->second->invalidate(M, PA)) ModuleAnalysisResults.erase(I); } -const detail::AnalysisResultConcept & -ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { - ModuleAnalysisResultMapT::iterator RI; +PreservedAnalyses FunctionPassManager::run(Function *F, + FunctionAnalysisManager *AM) { + PreservedAnalyses PA = PreservedAnalyses::all(); + + if (DebugPM) + dbgs() << "Starting function pass manager run.\n"; + + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) { + if (DebugPM) + dbgs() << "Running function pass: " << Passes[Idx]->name() << "\n"; + + PreservedAnalyses PassPA = Passes[Idx]->run(F, AM); + if (AM) + AM->invalidate(F, PassPA); + PA.intersect(std::move(PassPA)); + + F->getContext().yield(); + } + + if (DebugPM) + dbgs() << "Finished function pass manager run.\n"; + + return PA; +} + +bool FunctionAnalysisManager::empty() const { + assert(FunctionAnalysisResults.empty() == + FunctionAnalysisResultLists.empty() && + "The storage and index of analysis results disagree on how many there " + "are!"); + return FunctionAnalysisResults.empty(); +} + +void FunctionAnalysisManager::clear() { + FunctionAnalysisResults.clear(); + FunctionAnalysisResultLists.clear(); +} + +FunctionAnalysisManager::ResultConceptT & +FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { + FunctionAnalysisResultMapT::iterator RI; bool Inserted; - llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( - PassID, polymorphic_ptr >())); + std::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( + std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); + // If we don't have a cached result for this function, look up the pass and + // run it to produce a result, which we then add to the cache. if (Inserted) { - // We don't have a cached result for this result. Look up the pass and run - // it to produce a result, which we then add to the cache. - ModuleAnalysisPassMapT::const_iterator PI = - ModuleAnalysisPasses.find(PassID); - assert(PI != ModuleAnalysisPasses.end() && - "Analysis passes must be registered prior to being queried!"); - RI->second = PI->second->run(M); + FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; + ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this)); + RI->second = std::prev(ResultList.end()); } - return *RI->second; + return *RI->second->second; } -void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { - ModuleAnalysisResults.erase(PassID); +FunctionAnalysisManager::ResultConceptT * +FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const { + FunctionAnalysisResultMapT::const_iterator RI = + FunctionAnalysisResults.find(std::make_pair(PassID, F)); + return RI == FunctionAnalysisResults.end() ? nullptr : &*RI->second->second; } -bool FunctionPassManager::run(Module *M) { - bool Changed = false; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) - if (Passes[Idx]->run(I)) { - Changed = true; - if (AM) - AM->invalidateAll(I); - } - return Changed; +void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { + FunctionAnalysisResultMapT::iterator RI = + FunctionAnalysisResults.find(std::make_pair(PassID, F)); + if (RI == FunctionAnalysisResults.end()) + return; + + FunctionAnalysisResultLists[F].erase(RI->second); } -void FunctionAnalysisManager::invalidateAll(Function *F) { +void FunctionAnalysisManager::invalidateImpl(Function *F, + const PreservedAnalyses &PA) { // Clear all the invalidated results associated specifically with this // function. SmallVector InvalidatedPassIDs; @@ -73,7 +161,7 @@ void FunctionAnalysisManager::invalidateAll(Function *F) { for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), E = ResultsList.end(); I != E;) - if (I->second->invalidate(F)) { + if (I->second->invalidate(F, PA)) { InvalidatedPassIDs.push_back(I->first); I = ResultsList.erase(I); } else { @@ -82,35 +170,35 @@ void FunctionAnalysisManager::invalidateAll(Function *F) { while (!InvalidatedPassIDs.empty()) FunctionAnalysisResults.erase( std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); + if (ResultsList.empty()) + FunctionAnalysisResultLists.erase(F); } -const detail::AnalysisResultConcept & -FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { - FunctionAnalysisResultMapT::iterator RI; - bool Inserted; - llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( - std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator())); +char FunctionAnalysisManagerModuleProxy::PassID; - if (Inserted) { - // We don't have a cached result for this result. Look up the pass and run - // it to produce a result, which we then add to the cache. - FunctionAnalysisPassMapT::const_iterator PI = - FunctionAnalysisPasses.find(PassID); - assert(PI != FunctionAnalysisPasses.end() && - "Analysis passes must be registered prior to being queried!"); - FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; - ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); - RI->second = llvm::prior(ResultList.end()); - } +FunctionAnalysisManagerModuleProxy::Result +FunctionAnalysisManagerModuleProxy::run(Module *M) { + assert(FAM->empty() && "Function analyses ran prior to the module proxy!"); + return Result(*FAM); +} - return *RI->second->second; +FunctionAnalysisManagerModuleProxy::Result::~Result() { + // Clear out the analysis manager if we're being destroyed -- it means we + // didn't even see an invalidate call when we got invalidated. + FAM->clear(); } -void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { - FunctionAnalysisResultMapT::iterator RI = - FunctionAnalysisResults.find(std::make_pair(PassID, F)); - if (RI == FunctionAnalysisResults.end()) - return; +bool FunctionAnalysisManagerModuleProxy::Result::invalidate( + Module *M, const PreservedAnalyses &PA) { + // If this proxy isn't marked as preserved, then we can't even invalidate + // individual function analyses, there may be an invalid set of Function + // objects in the cache making it impossible to incrementally preserve them. + // Just clear the entire manager. + if (!PA.preserved(ID())) + FAM->clear(); - FunctionAnalysisResultLists[F].erase(RI->second); + // Return false to indicate that this result is still a valid proxy. + return false; } + +char ModuleAnalysisManagerFunctionProxy::PassID;