diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2013-11-21 02:11:31 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2013-11-21 02:11:31 +0000 |
commit | 851a2aa0e0285029bd8892a1056411ebb6ac3af9 (patch) | |
tree | f6783af74c23071d7559bf9892dd22f3a5f7125d /llvm/lib/IR/PassManager.cpp | |
parent | e934d7c9f5165671f1715ed490c1c66bb8588922 (diff) | |
download | llvm-851a2aa0e0285029bd8892a1056411ebb6ac3af9.zip llvm-851a2aa0e0285029bd8892a1056411ebb6ac3af9.tar.gz llvm-851a2aa0e0285029bd8892a1056411ebb6ac3af9.tar.bz2 |
[PM] Add a module analysis pass proxy for the function analysis manager.
This proxy will fill the role of proxying invalidation events down IR
unit layers so that when a module changes we correctly invalidate
function analyses. Currently this is a very coarse solution -- any
change blows away the entire thing -- but the next step is to make
invalidation handling more nuanced so that we can propagate specific
amounts of invalidation from one layer to the next.
The test is extended to place a module pass between two function pass
managers each of which have preserved function analyses which get
correctly invalidated by the module pass that might have changed what
functions are even in the module.
llvm-svn: 195304
Diffstat (limited to 'llvm/lib/IR/PassManager.cpp')
-rw-r--r-- | llvm/lib/IR/PassManager.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp index 0508b3c..50ace58 100644 --- a/llvm/lib/IR/PassManager.cpp +++ b/llvm/lib/IR/PassManager.cpp @@ -87,6 +87,19 @@ void FunctionAnalysisManager::invalidate(Function *F, const PreservedAnalyses &P std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } +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(); +} + const detail::AnalysisResultConcept<Function> & FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { FunctionAnalysisResultMapT::iterator RI; @@ -117,3 +130,27 @@ void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { FunctionAnalysisResultLists[F].erase(RI->second); } + +char FunctionAnalysisModuleProxy::PassID; + +FunctionAnalysisModuleProxy::Result +FunctionAnalysisModuleProxy::run(Module *M) { + assert(FAM.empty() && "Function analyses ran prior to the module proxy!"); + return Result(FAM); +} + +FunctionAnalysisModuleProxy::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(); +} + +bool FunctionAnalysisModuleProxy::Result::invalidate(Module *M) { + // FIXME: We should pull the preserved analysis set into the invalidation + // handler so that we can detect when there is no need to clear the entire + // function analysis manager. + FAM.clear(); + + // Return false to indicate that this result is still a valid proxy. + return false; +} |