aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/PassManager.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-11-21 02:11:31 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-11-21 02:11:31 +0000
commit851a2aa0e0285029bd8892a1056411ebb6ac3af9 (patch)
treef6783af74c23071d7559bf9892dd22f3a5f7125d /llvm/lib/IR/PassManager.cpp
parente934d7c9f5165671f1715ed490c1c66bb8588922 (diff)
downloadllvm-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.cpp37
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;
+}