mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-28 03:25:23 +00:00
[PM] Split the analysis manager into a function-specific interface and
a module-specific interface. This is the first of many steps necessary to generalize the infrastructure such that we can support both a Module-to-Function and Module-to-SCC-to-Function pass manager nestings. After a *lot* of attempts that never worked and didn't even make it to a committable state, it became clear that I had gotten the layering design of analyses flat out wrong. Four days later, I think I have most of the plan for how to correct this, and I'm starting to reshape the code into it. This is just a baby step I'm afraid, but starts separating the fundamentally distinct concepts of function analysis passes and module analysis passes so that in subsequent steps we can effectively layer them, and have a consistent design for the eventual SCC layer. As part of this, I've started some interface changes to make passes more regular. The module pass accepts the module in the run method, and some of the constructor parameters are gone. I'm still working out exactly where constructor parameters vs. method parameters will be used, so I expect this to fluctuate a bit. This actually makes the invalidation less "correct" at this phase, because now function passes don't invalidate module analysis passes, but that was actually somewhat of a misfeature. It will return in a better factored form which can scale to other units of IR. The documentation has gotten less verbose and helpful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -12,10 +12,45 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void ModulePassManager::run() {
|
||||
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);
|
||||
if (AM)
|
||||
AM->invalidateAll(M);
|
||||
}
|
||||
|
||||
void ModuleAnalysisManager::invalidateAll(Module *M) {
|
||||
// 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))
|
||||
ModuleAnalysisResults.erase(I);
|
||||
}
|
||||
|
||||
const detail::AnalysisResultConcept<Module> &
|
||||
ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
|
||||
ModuleAnalysisResultMapT::iterator RI;
|
||||
bool Inserted;
|
||||
llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
|
||||
PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module> >()));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return *RI->second;
|
||||
}
|
||||
|
||||
void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
|
||||
ModuleAnalysisResults.erase(PassID);
|
||||
}
|
||||
|
||||
bool FunctionPassManager::run(Module *M) {
|
||||
@@ -24,24 +59,14 @@ bool FunctionPassManager::run(Module *M) {
|
||||
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
|
||||
if (Passes[Idx]->run(I)) {
|
||||
Changed = true;
|
||||
if (AM) AM->invalidateAll(I);
|
||||
if (AM)
|
||||
AM->invalidateAll(I);
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
void AnalysisManager::invalidateAll(Function *F) {
|
||||
assert(F->getParent() == M && "Invalidating a function from another module!");
|
||||
|
||||
// First invalidate any module results we still have laying about.
|
||||
// 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))
|
||||
ModuleAnalysisResults.erase(I);
|
||||
|
||||
// Now clear all the invalidated results associated specifically with this
|
||||
void FunctionAnalysisManager::invalidateAll(Function *F) {
|
||||
// Clear all the invalidated results associated specifically with this
|
||||
// function.
|
||||
SmallVector<void *, 8> InvalidatedPassIDs;
|
||||
FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F];
|
||||
@@ -59,66 +84,8 @@ void AnalysisManager::invalidateAll(Function *F) {
|
||||
std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
|
||||
}
|
||||
|
||||
void AnalysisManager::invalidateAll(Module *M) {
|
||||
// First invalidate any module results we still have laying about.
|
||||
// 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))
|
||||
ModuleAnalysisResults.erase(I);
|
||||
|
||||
// Now walk all of the functions for which there are cached results, and
|
||||
// attempt to invalidate each of those as the entire module may have changed.
|
||||
// FIXME: How do we handle functions which have been deleted or RAUWed?
|
||||
SmallVector<void *, 8> InvalidatedPassIDs;
|
||||
for (FunctionAnalysisResultListMapT::iterator
|
||||
FI = FunctionAnalysisResultLists.begin(),
|
||||
FE = FunctionAnalysisResultLists.end();
|
||||
FI != FE; ++FI) {
|
||||
Function *F = FI->first;
|
||||
FunctionAnalysisResultListT &ResultsList = FI->second;
|
||||
for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
|
||||
E = ResultsList.end();
|
||||
I != E;)
|
||||
if (I->second->invalidate(F)) {
|
||||
InvalidatedPassIDs.push_back(I->first);
|
||||
I = ResultsList.erase(I);
|
||||
} else {
|
||||
++I;
|
||||
}
|
||||
while (!InvalidatedPassIDs.empty())
|
||||
FunctionAnalysisResults.erase(
|
||||
std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
|
||||
}
|
||||
}
|
||||
|
||||
const AnalysisManager::AnalysisResultConcept<Module> &
|
||||
AnalysisManager::getResultImpl(void *PassID, Module *M) {
|
||||
assert(M == this->M && "Wrong module used when querying the AnalysisManager");
|
||||
ModuleAnalysisResultMapT::iterator RI;
|
||||
bool Inserted;
|
||||
llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
|
||||
PassID, polymorphic_ptr<AnalysisResultConcept<Module> >()));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return *RI->second;
|
||||
}
|
||||
|
||||
const AnalysisManager::AnalysisResultConcept<Function> &
|
||||
AnalysisManager::getResultImpl(void *PassID, Function *F) {
|
||||
assert(F->getParent() == M && "Analyzing a function from another module!");
|
||||
|
||||
const detail::AnalysisResultConcept<Function> &
|
||||
FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
|
||||
FunctionAnalysisResultMapT::iterator RI;
|
||||
bool Inserted;
|
||||
llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
|
||||
@@ -139,15 +106,7 @@ AnalysisManager::getResultImpl(void *PassID, Function *F) {
|
||||
return *RI->second->second;
|
||||
}
|
||||
|
||||
void AnalysisManager::invalidateImpl(void *PassID, Module *M) {
|
||||
assert(M == this->M && "Invalidating a pass over a different module!");
|
||||
ModuleAnalysisResults.erase(PassID);
|
||||
}
|
||||
|
||||
void AnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
||||
assert(F->getParent() == M &&
|
||||
"Invalidating a pass over a function from another module!");
|
||||
|
||||
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
||||
FunctionAnalysisResultMapT::iterator RI =
|
||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||
if (RI == FunctionAnalysisResults.end())
|
||||
|
Reference in New Issue
Block a user