mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 17:56:53 +00:00
[PM] Factor the overwhelming majority of the interface boiler plate out
of the two analysis managers into a CRTP base class that can be shared and re-used in building any analysis manager. This will in turn simplify adding yet another analysis manager to the system. The base class provides all of the interface sugar for the analysis manager delegating the functionality back through DerivedT methods which operate on simple pass IDs. It also provides the pass registration, storage, and lookup system which is common across the various formulations of analysis managers. llvm-svn: 195747
This commit is contained in:
parent
b3250399ac
commit
f3c4692f91
@ -439,23 +439,43 @@ private:
|
||||
std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
|
||||
};
|
||||
|
||||
/// \brief A module analysis pass manager with lazy running and caching of
|
||||
/// results.
|
||||
class ModuleAnalysisManager {
|
||||
public:
|
||||
ModuleAnalysisManager() {}
|
||||
namespace detail {
|
||||
|
||||
/// \brief A CRTP base used to implement analysis managers.
|
||||
///
|
||||
/// This class template serves as the boiler plate of an analysis manager. Any
|
||||
/// analysis manager can be implemented on top of this base class. Any
|
||||
/// implementation will be required to provide specific hooks:
|
||||
///
|
||||
/// - getResultImpl
|
||||
/// - getCachedResultImpl
|
||||
/// - invalidateImpl
|
||||
///
|
||||
/// The details of the call pattern are within.
|
||||
template <typename DerivedT, typename IRUnitT>
|
||||
class AnalysisManagerBase {
|
||||
DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
|
||||
const DerivedT *derived_this() const { return static_cast<const DerivedT *>(this); }
|
||||
|
||||
protected:
|
||||
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
|
||||
typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
|
||||
|
||||
// FIXME: Provide template aliases for the models when we're using C++11 in
|
||||
// a mode supporting them.
|
||||
|
||||
public:
|
||||
/// \brief Get the result of an analysis pass for this module.
|
||||
///
|
||||
/// If there is not a valid cached result in the manager already, this will
|
||||
/// re-run the analysis to produce a valid result.
|
||||
template <typename PassT> const typename PassT::Result &getResult(Module *M) {
|
||||
assert(ModuleAnalysisPasses.count(PassT::ID()) &&
|
||||
template <typename PassT> const typename PassT::Result &getResult(IRUnitT IR) {
|
||||
assert(AnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being queried");
|
||||
|
||||
const detail::AnalysisResultConcept<Module *> &ResultConcept =
|
||||
getResultImpl(PassT::ID(), M);
|
||||
typedef detail::AnalysisResultModel<Module *, PassT, typename PassT::Result>
|
||||
const ResultConceptT &ResultConcept =
|
||||
derived_this()->getResultImpl(PassT::ID(), IR);
|
||||
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
|
||||
ResultModelT;
|
||||
return static_cast<const ResultModelT &>(ResultConcept).Result;
|
||||
}
|
||||
@ -466,69 +486,100 @@ public:
|
||||
///
|
||||
/// \returns null if there is no cached result.
|
||||
template <typename PassT>
|
||||
const typename PassT::Result *getCachedResult(Module *M) const {
|
||||
assert(ModuleAnalysisPasses.count(PassT::ID()) &&
|
||||
const typename PassT::Result *getCachedResult(IRUnitT IR) const {
|
||||
assert(AnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being queried");
|
||||
|
||||
const detail::AnalysisResultConcept<Module *> *ResultConcept =
|
||||
getCachedResultImpl(PassT::ID(), M);
|
||||
const ResultConceptT *ResultConcept =
|
||||
derived_this()->getCachedResultImpl(PassT::ID(), IR);
|
||||
if (!ResultConcept)
|
||||
return 0;
|
||||
|
||||
typedef detail::AnalysisResultModel<Module *, PassT, typename PassT::Result>
|
||||
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
|
||||
ResultModelT;
|
||||
return &static_cast<const ResultModelT *>(ResultConcept)->Result;
|
||||
}
|
||||
|
||||
/// \brief Register an analysis pass with the manager.
|
||||
///
|
||||
/// This provides an initialized and set-up analysis pass to the
|
||||
/// analysis
|
||||
/// manager. Whomever is setting up analysis passes must use this to
|
||||
/// populate
|
||||
/// This provides an initialized and set-up analysis pass to the analysis
|
||||
/// manager. Whomever is setting up analysis passes must use this to populate
|
||||
/// the manager with all of the analysis passes available.
|
||||
template <typename PassT> void registerPass(PassT Pass) {
|
||||
assert(!ModuleAnalysisPasses.count(PassT::ID()) &&
|
||||
assert(!AnalysisPasses.count(PassT::ID()) &&
|
||||
"Registered the same analysis pass twice!");
|
||||
ModuleAnalysisPasses[PassT::ID()] =
|
||||
new detail::AnalysisPassModel<Module *, ModuleAnalysisManager, PassT>(
|
||||
llvm_move(Pass));
|
||||
typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
|
||||
AnalysisPasses[PassT::ID()] = new PassModelT(llvm_move(Pass));
|
||||
}
|
||||
|
||||
/// \brief Invalidate a specific analysis pass for an IR module.
|
||||
///
|
||||
/// Note that the analysis result can disregard invalidation.
|
||||
template <typename PassT> void invalidate(Module *M) {
|
||||
assert(ModuleAnalysisPasses.count(PassT::ID()) &&
|
||||
assert(AnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being invalidated");
|
||||
invalidateImpl(PassT::ID(), M);
|
||||
derived_this()->invalidateImpl(PassT::ID(), M);
|
||||
}
|
||||
|
||||
/// \brief Invalidate analyses cached for an IR Module.
|
||||
/// \brief Invalidate analyses cached for an IR unit.
|
||||
///
|
||||
/// Walk through all of the analyses pertaining to this module and invalidate
|
||||
/// them unless they are preserved by the PreservedAnalyses set.
|
||||
void invalidate(Module *M, const PreservedAnalyses &PA);
|
||||
void invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
|
||||
derived_this()->invalidateImpl(IR, PA);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// \brief Lookup a registered analysis pass.
|
||||
PassConceptT &lookupPass(void *PassID) {
|
||||
typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
|
||||
assert(PI != AnalysisPasses.end() &&
|
||||
"Analysis passes must be registered prior to being queried!");
|
||||
return *PI->second;
|
||||
}
|
||||
|
||||
/// \brief Lookup a registered analysis pass.
|
||||
const PassConceptT &lookupPass(void *PassID) const {
|
||||
typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
|
||||
assert(PI != AnalysisPasses.end() &&
|
||||
"Analysis passes must be registered prior to being queried!");
|
||||
return *PI->second;
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Map type from module analysis pass ID to pass concept pointer.
|
||||
typedef DenseMap<void *, polymorphic_ptr<PassConceptT> > AnalysisPassMapT;
|
||||
|
||||
/// \brief Collection of module analysis passes, indexed by ID.
|
||||
AnalysisPassMapT AnalysisPasses;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// \brief A module analysis pass manager with lazy running and caching of
|
||||
/// results.
|
||||
class ModuleAnalysisManager
|
||||
: public detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> {
|
||||
friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module *>;
|
||||
typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> BaseT;
|
||||
typedef typename BaseT::ResultConceptT ResultConceptT;
|
||||
typedef typename BaseT::PassConceptT PassConceptT;
|
||||
|
||||
public:
|
||||
// Public methods provided by the base class.
|
||||
|
||||
private:
|
||||
/// \brief Get a module pass result, running the pass if necessary.
|
||||
const detail::AnalysisResultConcept<Module *> &getResultImpl(void *PassID,
|
||||
Module *M);
|
||||
const ResultConceptT &getResultImpl(void *PassID, Module *M);
|
||||
|
||||
/// \brief Get a cached module pass result or return null.
|
||||
const detail::AnalysisResultConcept<Module *> *
|
||||
getCachedResultImpl(void *PassID, Module *M) const;
|
||||
const ResultConceptT *getCachedResultImpl(void *PassID, Module *M) const;
|
||||
|
||||
/// \brief Invalidate a module pass result.
|
||||
void invalidateImpl(void *PassID, Module *M);
|
||||
|
||||
/// \brief Map type from module analysis pass ID to pass concept pointer.
|
||||
typedef DenseMap<void *, polymorphic_ptr<detail::AnalysisPassConcept<
|
||||
Module *, ModuleAnalysisManager> > >
|
||||
ModuleAnalysisPassMapT;
|
||||
|
||||
/// \brief Collection of module analysis passes, indexed by ID.
|
||||
ModuleAnalysisPassMapT ModuleAnalysisPasses;
|
||||
/// \brief Invalidate results across a module.
|
||||
void invalidateImpl(Module *M, const PreservedAnalyses &PA);
|
||||
|
||||
/// \brief Map type from module analysis pass ID to pass result concept pointer.
|
||||
typedef DenseMap<void *,
|
||||
@ -541,75 +592,15 @@ private:
|
||||
|
||||
/// \brief A function analysis manager to coordinate and cache analyses run over
|
||||
/// a module.
|
||||
class FunctionAnalysisManager {
|
||||
class FunctionAnalysisManager
|
||||
: public detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> {
|
||||
friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>;
|
||||
typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> BaseT;
|
||||
typedef typename BaseT::ResultConceptT ResultConceptT;
|
||||
typedef typename BaseT::PassConceptT PassConceptT;
|
||||
|
||||
public:
|
||||
FunctionAnalysisManager() {}
|
||||
|
||||
/// \brief Get the result of an analysis pass for a function.
|
||||
///
|
||||
/// If there is not a valid cached result in the manager already, this will
|
||||
/// re-run the analysis to produce a valid result.
|
||||
template <typename PassT>
|
||||
const typename PassT::Result &getResult(Function *F) {
|
||||
assert(FunctionAnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being queried");
|
||||
|
||||
const detail::AnalysisResultConcept<Function *> &ResultConcept =
|
||||
getResultImpl(PassT::ID(), F);
|
||||
typedef detail::AnalysisResultModel<Function *, PassT,
|
||||
typename PassT::Result> ResultModelT;
|
||||
return static_cast<const ResultModelT &>(ResultConcept).Result;
|
||||
}
|
||||
|
||||
/// \brief Get the cached result of an analysis pass for a function if
|
||||
/// available.
|
||||
///
|
||||
/// Does not run the analysis ever.
|
||||
/// \returns null if a cached result is not available.
|
||||
template <typename PassT>
|
||||
const typename PassT::Result *getCachedResult(Function *F) {
|
||||
assert(FunctionAnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being queried");
|
||||
|
||||
const detail::AnalysisResultConcept<Function *> *ResultConcept =
|
||||
getCachedResultImpl(PassT::ID(), F);
|
||||
if (!ResultConcept)
|
||||
return 0;
|
||||
|
||||
typedef detail::AnalysisResultModel<Function *, PassT,
|
||||
typename PassT::Result> ResultModelT;
|
||||
return &static_cast<const ResultModelT *>(ResultConcept)->Result;
|
||||
}
|
||||
|
||||
/// \brief Register an analysis pass with the manager.
|
||||
///
|
||||
/// This provides an initialized and set-up analysis pass to the
|
||||
/// analysis
|
||||
/// manager. Whomever is setting up analysis passes must use this to
|
||||
/// populate
|
||||
/// the manager with all of the analysis passes available.
|
||||
template <typename PassT> void registerPass(PassT Pass) {
|
||||
assert(!FunctionAnalysisPasses.count(PassT::ID()) &&
|
||||
"Registered the same analysis pass twice!");
|
||||
FunctionAnalysisPasses[PassT::ID()] = new detail::AnalysisPassModel<
|
||||
Function *, FunctionAnalysisManager, PassT>(llvm_move(Pass));
|
||||
}
|
||||
|
||||
/// \brief Invalidate a specific analysis pass for an IR module.
|
||||
///
|
||||
/// Note that the analysis result can disregard invalidation.
|
||||
template <typename PassT> void invalidate(Function *F) {
|
||||
assert(FunctionAnalysisPasses.count(PassT::ID()) &&
|
||||
"This analysis pass was not registered prior to being invalidated");
|
||||
invalidateImpl(PassT::ID(), F);
|
||||
}
|
||||
|
||||
/// \brief Invalidate analyses cached for an IR Function.
|
||||
///
|
||||
/// Walk through all of the analyses cache for this IR function and
|
||||
/// invalidate them unless they are preserved by the provided
|
||||
/// PreservedAnalyses set.
|
||||
void invalidate(Function *F, const PreservedAnalyses &PA);
|
||||
// Most public APIs are inherited from the CRTP base class.
|
||||
|
||||
/// \brief Returns true if the analysis manager has an empty results cache.
|
||||
bool empty() const;
|
||||
@ -624,23 +615,16 @@ public:
|
||||
|
||||
private:
|
||||
/// \brief Get a function pass result, running the pass if necessary.
|
||||
const detail::AnalysisResultConcept<Function *> &getResultImpl(void *PassID,
|
||||
Function *F);
|
||||
const ResultConceptT &getResultImpl(void *PassID, Function *F);
|
||||
|
||||
/// \brief Get a cached function pass result or return null.
|
||||
const detail::AnalysisResultConcept<Function *> *
|
||||
getCachedResultImpl(void *PassID, Function *F) const;
|
||||
const ResultConceptT *getCachedResultImpl(void *PassID, Function *F) const;
|
||||
|
||||
/// \brief Invalidate a function pass result.
|
||||
void invalidateImpl(void *PassID, Function *F);
|
||||
|
||||
/// \brief Map type from function analysis pass ID to pass concept pointer.
|
||||
typedef DenseMap<void *, polymorphic_ptr<detail::AnalysisPassConcept<
|
||||
Function *, FunctionAnalysisManager> > >
|
||||
FunctionAnalysisPassMapT;
|
||||
|
||||
/// \brief Collection of function analysis passes, indexed by ID.
|
||||
FunctionAnalysisPassMapT FunctionAnalysisPasses;
|
||||
/// \brief Invalidate the results for a function..
|
||||
void invalidateImpl(Function *F, const PreservedAnalyses &PA);
|
||||
|
||||
/// \brief List of function analysis pass IDs and associated concept pointers.
|
||||
///
|
||||
|
@ -23,37 +23,22 @@ PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
|
||||
return PA;
|
||||
}
|
||||
|
||||
void ModuleAnalysisManager::invalidate(Module *M, const PreservedAnalyses &PA) {
|
||||
// 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, PA))
|
||||
ModuleAnalysisResults.erase(I);
|
||||
}
|
||||
|
||||
const detail::AnalysisResultConcept<Module *> &
|
||||
const ModuleAnalysisManager::ResultConceptT &
|
||||
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, this);
|
||||
}
|
||||
// If we don't have a cached result for this module, look up the pass and run
|
||||
// it to produce a result, which we then add to the cache.
|
||||
if (Inserted)
|
||||
RI->second = lookupPass(PassID).run(M, this);
|
||||
|
||||
return *RI->second;
|
||||
}
|
||||
|
||||
const detail::AnalysisResultConcept<Module *> *
|
||||
const ModuleAnalysisManager::ResultConceptT *
|
||||
ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
|
||||
ModuleAnalysisResultMapT::const_iterator RI = ModuleAnalysisResults.find(PassID);
|
||||
return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second;
|
||||
@ -63,6 +48,17 @@ void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
|
||||
ModuleAnalysisResults.erase(PassID);
|
||||
}
|
||||
|
||||
void ModuleAnalysisManager::invalidateImpl(Module *M,
|
||||
const PreservedAnalyses &PA) {
|
||||
// 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, PA))
|
||||
ModuleAnalysisResults.erase(I);
|
||||
}
|
||||
|
||||
PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager *AM) {
|
||||
PreservedAnalyses PA = PreservedAnalyses::all();
|
||||
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
|
||||
@ -74,7 +70,55 @@ PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager
|
||||
return PA;
|
||||
}
|
||||
|
||||
void FunctionAnalysisManager::invalidate(Function *F, const PreservedAnalyses &PA) {
|
||||
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 FunctionAnalysisManager::ResultConceptT &
|
||||
FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
|
||||
FunctionAnalysisResultMapT::iterator RI;
|
||||
bool Inserted;
|
||||
llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
|
||||
std::make_pair(PassID, F), FunctionAnalysisResultListT::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) {
|
||||
FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
|
||||
ResultList.push_back(std::make_pair(PassID, lookupPass(PassID).run(F, this)));
|
||||
RI->second = llvm::prior(ResultList.end());
|
||||
}
|
||||
|
||||
return *RI->second->second;
|
||||
}
|
||||
|
||||
const FunctionAnalysisManager::ResultConceptT *
|
||||
FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
|
||||
FunctionAnalysisResultMapT::const_iterator RI =
|
||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||
return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second;
|
||||
}
|
||||
|
||||
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
||||
FunctionAnalysisResultMapT::iterator RI =
|
||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||
if (RI == FunctionAnalysisResults.end())
|
||||
return;
|
||||
|
||||
FunctionAnalysisResultLists[F].erase(RI->second);
|
||||
}
|
||||
|
||||
void FunctionAnalysisManager::invalidateImpl(Function *F,
|
||||
const PreservedAnalyses &PA) {
|
||||
// Clear all the invalidated results associated specifically with this
|
||||
// function.
|
||||
SmallVector<void *, 8> InvalidatedPassIDs;
|
||||
@ -93,57 +137,6 @@ 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;
|
||||
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, this)));
|
||||
RI->second = llvm::prior(ResultList.end());
|
||||
}
|
||||
|
||||
return *RI->second->second;
|
||||
}
|
||||
|
||||
const detail::AnalysisResultConcept<Function *> *
|
||||
FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
|
||||
FunctionAnalysisResultMapT::const_iterator RI =
|
||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||
return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second;
|
||||
}
|
||||
|
||||
void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
|
||||
FunctionAnalysisResultMapT::iterator RI =
|
||||
FunctionAnalysisResults.find(std::make_pair(PassID, F));
|
||||
if (RI == FunctionAnalysisResults.end())
|
||||
return;
|
||||
|
||||
FunctionAnalysisResultLists[F].erase(RI->second);
|
||||
}
|
||||
|
||||
char FunctionAnalysisManagerModuleProxy::PassID;
|
||||
|
||||
FunctionAnalysisManagerModuleProxy::Result
|
||||
|
Loading…
Reference in New Issue
Block a user