PassT Pass;
};
+/// \brief Abstract concept of an analysis result.
+///
+/// This concept is parameterized over the IR unit that this result pertains
+/// to.
+template <typename IRUnitT> struct AnalysisResultConcept {
+ virtual ~AnalysisResultConcept() {}
+ virtual AnalysisResultConcept *clone() = 0;
+
+ /// \brief Method to try and mark a result as invalid.
+ ///
+ /// When the outer \c AnalysisManager detects a change in some underlying
+ /// unit of the IR, it will call this method on all of the results cached.
+ ///
+ /// \returns true if the result should indeed be invalidated (the default).
+ virtual bool invalidate(IRUnitT *IR) = 0;
+};
+
+/// \brief Wrapper to model the analysis result concept.
+///
+/// Can wrap any type which implements a suitable invalidate member and model
+/// the AnalysisResultConcept for the AnalysisManager.
+template <typename IRUnitT, typename ResultT>
+struct AnalysisResultModel : AnalysisResultConcept<IRUnitT> {
+ AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
+ virtual AnalysisResultModel *clone() {
+ return new AnalysisResultModel(Result);
+ }
+
+ /// \brief The model delegates to the \c ResultT method.
+ virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); }
+
+ ResultT Result;
+};
+
+/// \brief Abstract concept of an analysis pass.
+///
+/// This concept is parameterized over the IR unit that it can run over and
+/// produce an analysis result.
+template <typename IRUnitT> struct AnalysisPassConcept {
+ virtual ~AnalysisPassConcept() {}
+ virtual AnalysisPassConcept *clone() = 0;
+
+ /// \brief Method to run this analysis over a unit of IR.
+ /// \returns The analysis result object to be queried by users, the caller
+ /// takes ownership.
+ virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT *IR) = 0;
+};
+
+/// \brief Wrapper to model the analysis pass concept.
+///
+/// Can wrap any type which implements a suitable \c run method. The method
+/// must accept the IRUnitT as an argument and produce an object which can be
+/// wrapped in a \c AnalysisResultModel.
+template <typename PassT>
+struct AnalysisPassModel : AnalysisPassConcept<typename PassT::IRUnitT> {
+ AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
+ virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
+
+ // FIXME: Replace PassT::IRUnitT with type traits when we use C++11.
+ typedef typename PassT::IRUnitT IRUnitT;
+
+ // FIXME: Replace PassT::Result with type traits when we use C++11.
+ typedef AnalysisResultModel<IRUnitT, typename PassT::Result> ResultModelT;
+
+ /// \brief The model delegates to the \c PassT::run method.
+ ///
+ /// The return is wrapped in an \c AnalysisResultModel.
+ virtual ResultModelT *run(IRUnitT *IR) {
+ return new ResultModelT(Pass.run(IR));
+ }
+
+ PassT Pass;
+};
+
}
-class AnalysisManager;
+class ModuleAnalysisManager;
class ModulePassManager {
public:
- ModulePassManager(Module *M, AnalysisManager *AM = 0) : M(M), AM(AM) {}
+ explicit ModulePassManager(ModuleAnalysisManager *AM = 0) : AM(AM) {}
+
+ /// \brief Run all of the module passes in this module pass manager over
+ /// a module.
+ ///
+ /// This method should only be called for a single module as there is the
+ /// expectation that the lifetime of a pass is bounded to that of a module.
+ void run(Module *M);
template <typename ModulePassT> void addPass(ModulePassT Pass) {
Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass)));
}
- void run();
-
private:
// Pull in the concept type and model template specialized for modules.
typedef detail::PassConcept<Module *> ModulePassConcept;
ModulePassModel(PassT Pass) : detail::PassModel<Module *, PassT>(Pass) {}
};
- Module *M;
- AnalysisManager *AM;
+ ModuleAnalysisManager *AM;
std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
};
+class FunctionAnalysisManager;
+
class FunctionPassManager {
public:
- FunctionPassManager(AnalysisManager *AM = 0) : AM(AM) {}
+ explicit FunctionPassManager(FunctionAnalysisManager *AM = 0) : AM(AM) {}
template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
Passes.push_back(new FunctionPassModel<FunctionPassT>(llvm_move(Pass)));
: detail::PassModel<Function *, PassT>(Pass) {}
};
- AnalysisManager *AM;
+ FunctionAnalysisManager *AM;
std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
};
-
-/// \brief An analysis manager to coordinate and cache analyses run over
-/// a module.
-///
-/// The analysis manager is typically used by passes in a pass pipeline
-/// (consisting potentially of several individual pass managers) over a module
-/// of IR. It provides registration of available analyses, declaring
-/// requirements on support for specific analyses, running of an specific
-/// analysis over a specific unit of IR to compute an analysis result, and
-/// caching of the analysis results to reuse them across multiple passes.
-///
-/// It is the responsibility of callers to use the invalidation API to
-/// invalidate analysis results when the IR they correspond to changes. The
-/// \c ModulePassManager and \c FunctionPassManager do this automatically.
-class AnalysisManager {
+/// \brief A module analysis pass manager with lazy running and caching of
+/// results.
+class ModuleAnalysisManager {
public:
- AnalysisManager(Module *M) : M(M) {}
+ ModuleAnalysisManager() {}
/// \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.
- ///
- /// The module passed in must be the same module as the analysis manager was
- /// constructed around.
- template <typename PassT>
- const typename PassT::Result &getResult(Module *M) {
+ template <typename PassT> const typename PassT::Result &getResult(Module *M) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Module>::value),
+ "The analysis pass must be over a Module.");
assert(ModuleAnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
- const AnalysisResultConcept<Module> &ResultConcept =
+ const detail::AnalysisResultConcept<Module> &ResultConcept =
getResultImpl(PassT::ID(), M);
- typedef AnalysisResultModel<Module, typename PassT::Result> ResultModelT;
- return static_cast<const ResultModelT &>(ResultConcept).Result;
- }
-
- /// \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 AnalysisResultConcept<Function> &ResultConcept =
- getResultImpl(PassT::ID(), F);
- typedef AnalysisResultModel<Function, typename PassT::Result> ResultModelT;
+ typedef detail::AnalysisResultModel<Module, typename PassT::Result>
+ ResultModelT;
return static_cast<const ResultModelT &>(ResultConcept).Result;
}
/// 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 registerAnalysisPass(PassT Pass) {
- registerAnalysisPassImpl<PassT>(llvm_move(Pass));
+ template <typename PassT> void registerPass(PassT Pass) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Module>::value),
+ "The analysis pass must be over a Module.");
+ assert(!ModuleAnalysisPasses.count(PassT::ID()) &&
+ "Registered the same analysis pass twice!");
+ ModuleAnalysisPasses[PassT::ID()] =
+ new detail::AnalysisPassModel<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(Module *M) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Module>::value),
+ "The analysis pass must be over a Module.");
+ assert(ModuleAnalysisPasses.count(PassT::ID()) &&
+ "This analysis pass was not registered prior to being invalidated");
invalidateImpl(PassT::ID(), M);
}
- /// \brief Invalidate a specific analysis pass for an IR function.
- ///
- /// Note that the analysis result can disregard invalidation.
- template <typename PassT> void invalidate(Function *F) {
- invalidateImpl(PassT::ID(), F);
- }
-
/// \brief Invalidate analyses cached for an IR Module.
///
/// Note that specific analysis results can disregard invalidation by
/// around.
void invalidateAll(Module *M);
- /// \brief Invalidate analyses cached for an IR Function.
- ///
- /// Note that specific analysis results can disregard invalidation by
- /// overriding the invalidate method.
- void invalidateAll(Function *F);
-
private:
- /// \brief Abstract concept of an analysis result.
- ///
- /// This concept is parameterized over the IR unit that this result pertains
- /// to.
- template <typename IRUnitT> struct AnalysisResultConcept {
- virtual ~AnalysisResultConcept() {}
- virtual AnalysisResultConcept *clone() = 0;
-
- /// \brief Method to try and mark a result as invalid.
- ///
- /// When the outer \c AnalysisManager detects a change in some underlying
- /// unit of the IR, it will call this method on all of the results cached.
- ///
- /// \returns true if the result should indeed be invalidated (the default).
- virtual bool invalidate(IRUnitT *IR) = 0;
- };
-
- /// \brief Wrapper to model the analysis result concept.
- ///
- /// Can wrap any type which implements a suitable invalidate member and model
- /// the AnalysisResultConcept for the AnalysisManager.
- template <typename IRUnitT, typename ResultT>
- struct AnalysisResultModel : AnalysisResultConcept<IRUnitT> {
- AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
- virtual AnalysisResultModel *clone() {
- return new AnalysisResultModel(Result);
- }
-
- /// \brief The model delegates to the \c ResultT method.
- virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); }
-
- ResultT Result;
- };
-
- /// \brief Abstract concept of an analysis pass.
- ///
- /// This concept is parameterized over the IR unit that it can run over and
- /// produce an analysis result.
- template <typename IRUnitT> struct AnalysisPassConcept {
- virtual ~AnalysisPassConcept() {}
- virtual AnalysisPassConcept *clone() = 0;
-
- /// \brief Method to run this analysis over a unit of IR.
- /// \returns The analysis result object to be queried by users, the caller
- /// takes ownership.
- virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT *IR) = 0;
- };
-
- /// \brief Wrapper to model the analysis pass concept.
- ///
- /// Can wrap any type which implements a suitable \c run method. The method
- /// must accept the IRUnitT as an argument and produce an object which can be
- /// wrapped in a \c AnalysisResultModel.
- template <typename PassT>
- struct AnalysisPassModel : AnalysisPassConcept<typename PassT::IRUnitT> {
- AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
- virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
-
- // FIXME: Replace PassT::IRUnitT with type traits when we use C++11.
- typedef typename PassT::IRUnitT IRUnitT;
-
- // FIXME: Replace PassT::Result with type traits when we use C++11.
- typedef AnalysisResultModel<IRUnitT, typename PassT::Result> ResultModelT;
-
- /// \brief The model delegates to the \c PassT::run method.
- ///
- /// The return is wrapped in an \c AnalysisResultModel.
- virtual ResultModelT *run(IRUnitT *IR) {
- return new ResultModelT(Pass.run(IR));
- }
-
- PassT Pass;
- };
-
-
/// \brief Get a module pass result, running the pass if necessary.
- const AnalysisResultConcept<Module> &getResultImpl(void *PassID, Module *M);
-
- /// \brief Get a function pass result, running the pass if necessary.
- const AnalysisResultConcept<Function> &getResultImpl(void *PassID,
- Function *F);
+ const detail::AnalysisResultConcept<Module> &getResultImpl(void *PassID,
+ Module *M);
/// \brief Invalidate a module pass result.
void invalidateImpl(void *PassID, Module *M);
- /// \brief Invalidate a function pass result.
- void invalidateImpl(void *PassID, Function *F);
+ /// \brief Map type from module analysis pass ID to pass concept pointer.
+ typedef DenseMap<void *,
+ polymorphic_ptr<detail::AnalysisPassConcept<Module> > >
+ ModuleAnalysisPassMapT;
+
+ /// \brief Collection of module analysis passes, indexed by ID.
+ ModuleAnalysisPassMapT ModuleAnalysisPasses;
+ /// \brief Map type from module analysis pass ID to pass result concept pointer.
+ typedef DenseMap<void *,
+ polymorphic_ptr<detail::AnalysisResultConcept<Module> > >
+ ModuleAnalysisResultMapT;
+
+ /// \brief Cache of computed module analysis results for this module.
+ ModuleAnalysisResultMapT ModuleAnalysisResults;
+};
- /// \brief Module pass specific implementation of registration.
+/// \brief A function analysis manager to coordinate and cache analyses run over
+/// a module.
+class FunctionAnalysisManager {
+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>
- typename enable_if<is_same<typename PassT::IRUnitT, Module> >::type
- registerAnalysisPassImpl(PassT Pass) {
- assert(!ModuleAnalysisPasses.count(PassT::ID()) &&
- "Registered the same analysis pass twice!");
- ModuleAnalysisPasses[PassT::ID()] =
- new AnalysisPassModel<PassT>(llvm_move(Pass));
+ const typename PassT::Result &getResult(Function *F) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Function>::value),
+ "The analysis pass must be over a Function.");
+ 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, typename PassT::Result>
+ ResultModelT;
+ return static_cast<const ResultModelT &>(ResultConcept).Result;
}
- /// \brief Function pass specific implementation of registration.
- template <typename PassT>
- typename enable_if<is_same<typename PassT::IRUnitT, Function> >::type
- registerAnalysisPassImpl(PassT Pass) {
+ /// \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) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Function>::value),
+ "The analysis pass must be over a Function.");
assert(!FunctionAnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
FunctionAnalysisPasses[PassT::ID()] =
- new AnalysisPassModel<PassT>(llvm_move(Pass));
+ new detail::AnalysisPassModel<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) {
+ LLVM_STATIC_ASSERT((is_same<typename PassT::IRUnitT, Function>::value),
+ "The analysis pass must be over a Function.");
+ assert(FunctionAnalysisPasses.count(PassT::ID()) &&
+ "This analysis pass was not registered prior to being invalidated");
+ invalidateImpl(PassT::ID(), F);
+ }
- /// \brief Map type from module analysis pass ID to pass concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<AnalysisPassConcept<Module> > >
- ModuleAnalysisPassMapT;
-
- /// \brief Collection of module analysis passes, indexed by ID.
- ModuleAnalysisPassMapT ModuleAnalysisPasses;
-
- /// \brief Map type from module analysis pass ID to pass result concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<AnalysisResultConcept<Module> > >
- ModuleAnalysisResultMapT;
+ /// \brief Invalidate analyses cached for an IR Function.
+ ///
+ /// Note that specific analysis results can disregard invalidation by
+ /// overriding the invalidate method.
+ void invalidateAll(Function *F);
- /// \brief Cache of computed module analysis results for this module.
- ModuleAnalysisResultMapT ModuleAnalysisResults;
+private:
+ /// \brief Get a function pass result, running the pass if necessary.
+ const detail::AnalysisResultConcept<Function> &getResultImpl(void *PassID,
+ Function *F);
+ /// \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<AnalysisPassConcept<Function> > >
- FunctionAnalysisPassMapT;
+ typedef DenseMap<void *,
+ polymorphic_ptr<detail::AnalysisPassConcept<Function> > >
+ FunctionAnalysisPassMapT;
/// \brief Collection of function analysis passes, indexed by ID.
FunctionAnalysisPassMapT FunctionAnalysisPasses;
/// Requires iterators to be valid across appending new entries and arbitrary
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
- typedef std::list<
- std::pair<void *, polymorphic_ptr<AnalysisResultConcept<Function> > > >
- FunctionAnalysisResultListT;
+ typedef std::list<std::pair<
+ void *, polymorphic_ptr<detail::AnalysisResultConcept<Function> > > >
+ FunctionAnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
- typedef DenseMap<Function *, FunctionAnalysisResultListT> FunctionAnalysisResultListMapT;
+ typedef DenseMap<Function *, FunctionAnalysisResultListT>
+ FunctionAnalysisResultListMapT;
/// \brief Map from function to a list of function analysis results.
///
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, Function *>,
FunctionAnalysisResultListT::iterator>
- FunctionAnalysisResultMapT;
+ FunctionAnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
FunctionAnalysisResultMapT FunctionAnalysisResults;
-
- /// \brief Module handle for the \c AnalysisManager.
- Module *M;
};
}
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);
}
-bool FunctionPassManager::run(Module *M) {
- bool Changed = false;
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
- for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
- if (Passes[Idx]->run(I)) {
- Changed = true;
- 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.
+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(),
I != E; ++I)
if (I->second->invalidate(M))
ModuleAnalysisResults.erase(I);
-
- // Now 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;)
- 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));
}
-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");
+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<AnalysisResultConcept<Module> >()));
+ PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module> >()));
if (Inserted) {
// We don't have a cached result for this result. Look up the pass and run
return *RI->second;
}
-const AnalysisManager::AnalysisResultConcept<Function> &
-AnalysisManager::getResultImpl(void *PassID, Function *F) {
- assert(F->getParent() == M && "Analyzing a function from another module!");
+void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
+ ModuleAnalysisResults.erase(PassID);
+}
+
+bool FunctionPassManager::run(Module *M) {
+ bool Changed = false;
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
+ if (Passes[Idx]->run(I)) {
+ Changed = true;
+ if (AM)
+ AM->invalidateAll(I);
+ }
+ return Changed;
+}
+
+void FunctionAnalysisManager::invalidateAll(Function *F) {
+ // 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;)
+ 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 detail::AnalysisResultConcept<Function> &
+FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
FunctionAnalysisResultMapT::iterator RI;
bool Inserted;
llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
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())