[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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195304 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth
2013-11-21 02:11:31 +00:00
parent 7b98dd33fd
commit 7fac06c423
3 changed files with 185 additions and 44 deletions

View File

@@ -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;
}