2013-11-13 01:12:08 +00:00
|
|
|
//===- PassManager.h - Infrastructure for managing & running IR passes ----===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/IR/PassManager.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2013-11-20 11:31:50 +00:00
|
|
|
PreservedAnalyses ModulePassManager::run(Module *M) {
|
|
|
|
PreservedAnalyses PA = PreservedAnalyses::all();
|
|
|
|
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
|
|
|
|
PreservedAnalyses PassPA = Passes[Idx]->run(M);
|
|
|
|
if (AM)
|
|
|
|
AM->invalidate(M, PassPA);
|
|
|
|
PA.intersect(llvm_move(PassPA));
|
|
|
|
}
|
|
|
|
return PA;
|
2013-11-13 01:12:08 +00:00
|
|
|
}
|
|
|
|
|
2013-11-20 11:31:50 +00:00
|
|
|
void ModuleAnalysisManager::invalidate(Module *M, const PreservedAnalyses &PA) {
|
2013-11-13 01:12:08 +00:00
|
|
|
// 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)
|
2013-11-20 11:31:50 +00:00
|
|
|
if (!PA.preserved(I->first) && I->second->invalidate(M))
|
2013-11-13 01:12:08 +00:00
|
|
|
ModuleAnalysisResults.erase(I);
|
|
|
|
}
|
|
|
|
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
const detail::AnalysisResultConcept<Module> &
|
|
|
|
ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
|
2013-11-13 01:12:08 +00:00
|
|
|
ModuleAnalysisResultMapT::iterator RI;
|
|
|
|
bool Inserted;
|
|
|
|
llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module> >()));
|
2013-11-13 01:12:08 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
|
|
|
|
ModuleAnalysisResults.erase(PassID);
|
|
|
|
}
|
|
|
|
|
2013-11-20 11:31:50 +00:00
|
|
|
PreservedAnalyses FunctionPassManager::run(Function *F) {
|
|
|
|
PreservedAnalyses PA = PreservedAnalyses::all();
|
|
|
|
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
|
|
|
|
PreservedAnalyses PassPA = Passes[Idx]->run(F);
|
|
|
|
if (AM)
|
|
|
|
AM->invalidate(F, PassPA);
|
|
|
|
PA.intersect(llvm_move(PassPA));
|
|
|
|
}
|
|
|
|
return PA;
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
}
|
|
|
|
|
2013-11-20 11:31:50 +00:00
|
|
|
void FunctionAnalysisManager::invalidate(Function *F, const PreservedAnalyses &PA) {
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
// Clear all the invalidated results associated specifically with this
|
|
|
|
// function.
|
|
|
|
SmallVector<void *, 8> InvalidatedPassIDs;
|
|
|
|
FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F];
|
|
|
|
for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
|
|
|
|
E = ResultsList.end();
|
|
|
|
I != E;)
|
2013-11-20 11:31:50 +00:00
|
|
|
if (!PA.preserved(I->first) && I->second->invalidate(F)) {
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
InvalidatedPassIDs.push_back(I->first);
|
|
|
|
I = ResultsList.erase(I);
|
|
|
|
} else {
|
|
|
|
++I;
|
|
|
|
}
|
|
|
|
while (!InvalidatedPassIDs.empty())
|
|
|
|
FunctionAnalysisResults.erase(
|
|
|
|
std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
|
|
|
|
}
|
2013-11-13 01:12:08 +00:00
|
|
|
|
2013-11-21 02:11:31 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
const detail::AnalysisResultConcept<Function> &
|
|
|
|
FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
|
2013-11-13 01:12:08 +00:00
|
|
|
FunctionAnalysisResultMapT::iterator RI;
|
|
|
|
bool Inserted;
|
|
|
|
llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
|
|
|
|
std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator()));
|
|
|
|
|
|
|
|
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.
|
|
|
|
FunctionAnalysisPassMapT::const_iterator PI =
|
|
|
|
FunctionAnalysisPasses.find(PassID);
|
|
|
|
assert(PI != FunctionAnalysisPasses.end() &&
|
|
|
|
"Analysis passes must be registered prior to being queried!");
|
|
|
|
FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
|
|
|
|
ResultList.push_back(std::make_pair(PassID, PI->second->run(F)));
|
|
|
|
RI->second = llvm::prior(ResultList.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
return *RI->second->second;
|
|
|
|
}
|
|
|
|
|
[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
2013-11-20 04:01:38 +00:00
|
|
|
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
2013-11-15 21:44:35 +00:00
|
|
|
FunctionAnalysisResultMapT::iterator RI =
|
|
|
|
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
2013-11-13 01:12:08 +00:00
|
|
|
if (RI == FunctionAnalysisResults.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
FunctionAnalysisResultLists[F].erase(RI->second);
|
|
|
|
}
|
2013-11-21 02:11:31 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|