mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
[PM] Fold all three analysis managers into a single AnalysisManager
template. This consolidates three copies of nearly the same core logic. It adds "complexity" to the ModuleAnalysisManager in that it makes it possible to share a ModuleAnalysisManager across multiple modules... But it does so by deleting *all of the code*, so I'm OK with that. This will naturally make fixing bugs in this code much simpler, etc. The only down side here is that we have to use 'typename' and 'this->' in various places, and the implementation is lifted into the header. I'll take that for the code size reduction. The convenient names are still typedef-ed and used throughout so that users can largely ignore this aspect of the implementation. The follow-up change to this will do the exact same refactoring for the PassManagers. =D It turns out that the interesting different code is almost entirely in the adaptors. At the end, that should be essentially all that is left. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225757 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -49,106 +49,6 @@ PreservedAnalyses CGSCCPassManager::run(LazyCallGraph::SCC &C,
|
||||
return PA;
|
||||
}
|
||||
|
||||
bool CGSCCAnalysisManager::empty() const {
|
||||
assert(CGSCCAnalysisResults.empty() == CGSCCAnalysisResultLists.empty() &&
|
||||
"The storage and index of analysis results disagree on how many there "
|
||||
"are!");
|
||||
return CGSCCAnalysisResults.empty();
|
||||
}
|
||||
|
||||
void CGSCCAnalysisManager::clear() {
|
||||
CGSCCAnalysisResults.clear();
|
||||
CGSCCAnalysisResultLists.clear();
|
||||
}
|
||||
|
||||
CGSCCAnalysisManager::ResultConceptT &
|
||||
CGSCCAnalysisManager::getResultImpl(void *PassID, LazyCallGraph::SCC &C) {
|
||||
CGSCCAnalysisResultMapT::iterator RI;
|
||||
bool Inserted;
|
||||
std::tie(RI, Inserted) = CGSCCAnalysisResults.insert(std::make_pair(
|
||||
std::make_pair(PassID, &C), CGSCCAnalysisResultListT::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) {
|
||||
auto &P = lookupPass(PassID);
|
||||
if (DebugPM)
|
||||
dbgs() << "Running CGSCC analysis: " << P.name() << "\n";
|
||||
CGSCCAnalysisResultListT &ResultList = CGSCCAnalysisResultLists[&C];
|
||||
ResultList.emplace_back(PassID, P.run(C, this));
|
||||
RI->second = std::prev(ResultList.end());
|
||||
}
|
||||
|
||||
return *RI->second->second;
|
||||
}
|
||||
|
||||
CGSCCAnalysisManager::ResultConceptT *
|
||||
CGSCCAnalysisManager::getCachedResultImpl(void *PassID,
|
||||
LazyCallGraph::SCC &C) const {
|
||||
CGSCCAnalysisResultMapT::const_iterator RI =
|
||||
CGSCCAnalysisResults.find(std::make_pair(PassID, &C));
|
||||
return RI == CGSCCAnalysisResults.end() ? nullptr : &*RI->second->second;
|
||||
}
|
||||
|
||||
void CGSCCAnalysisManager::invalidateImpl(void *PassID, LazyCallGraph::SCC &C) {
|
||||
CGSCCAnalysisResultMapT::iterator RI =
|
||||
CGSCCAnalysisResults.find(std::make_pair(PassID, &C));
|
||||
if (RI == CGSCCAnalysisResults.end())
|
||||
return;
|
||||
|
||||
if (DebugPM)
|
||||
dbgs() << "Invalidating CGSCC analysis: " << lookupPass(PassID).name()
|
||||
<< "\n";
|
||||
CGSCCAnalysisResultLists[&C].erase(RI->second);
|
||||
CGSCCAnalysisResults.erase(RI);
|
||||
}
|
||||
|
||||
PreservedAnalyses CGSCCAnalysisManager::invalidateImpl(LazyCallGraph::SCC &C,
|
||||
PreservedAnalyses PA) {
|
||||
// Short circuit for a common case of all analyses being preserved.
|
||||
if (PA.areAllPreserved())
|
||||
return std::move(PA);
|
||||
|
||||
if (DebugPM)
|
||||
dbgs() << "Invalidating all non-preserved analyses for SCC: " << C.getName()
|
||||
<< "\n";
|
||||
|
||||
// Clear all the invalidated results associated specifically with this
|
||||
// function.
|
||||
SmallVector<void *, 8> InvalidatedPassIDs;
|
||||
CGSCCAnalysisResultListT &ResultsList = CGSCCAnalysisResultLists[&C];
|
||||
for (CGSCCAnalysisResultListT::iterator I = ResultsList.begin(),
|
||||
E = ResultsList.end();
|
||||
I != E;) {
|
||||
void *PassID = I->first;
|
||||
|
||||
// Pass the invalidation down to the pass itself to see if it thinks it is
|
||||
// necessary. The analysis pass can return false if no action on the part
|
||||
// of the analysis manager is required for this invalidation event.
|
||||
if (I->second->invalidate(C, PA)) {
|
||||
if (DebugPM)
|
||||
dbgs() << "Invalidating CGSCC analysis: " << lookupPass(PassID).name()
|
||||
<< "\n";
|
||||
|
||||
InvalidatedPassIDs.push_back(I->first);
|
||||
I = ResultsList.erase(I);
|
||||
} else {
|
||||
++I;
|
||||
}
|
||||
|
||||
// After handling each pass, we mark it as preserved. Once we've
|
||||
// invalidated any stale results, the rest of the system is allowed to
|
||||
// start preserving this analysis again.
|
||||
PA.preserve(PassID);
|
||||
}
|
||||
while (!InvalidatedPassIDs.empty())
|
||||
CGSCCAnalysisResults.erase(
|
||||
std::make_pair(InvalidatedPassIDs.pop_back_val(), &C));
|
||||
CGSCCAnalysisResultLists.erase(&C);
|
||||
|
||||
return std::move(PA);
|
||||
}
|
||||
|
||||
char CGSCCAnalysisManagerModuleProxy::PassID;
|
||||
|
||||
CGSCCAnalysisManagerModuleProxy::Result
|
||||
|
Reference in New Issue
Block a user