summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/CGSCCPassManager.h299
-rw-r--r--llvm/include/llvm/Analysis/LoopPassManager.h139
-rw-r--r--llvm/include/llvm/IR/PassManager.h180
-rw-r--r--llvm/lib/Analysis/CGSCCPassManager.cpp63
-rw-r--r--llvm/lib/Analysis/LoopPassManager.cpp31
-rw-r--r--llvm/lib/IR/PassManager.cpp31
-rw-r--r--llvm/test/Other/new-pass-manager.ll6
7 files changed, 147 insertions, 602 deletions
diff --git a/llvm/include/llvm/Analysis/CGSCCPassManager.h b/llvm/include/llvm/Analysis/CGSCCPassManager.h
index cede4b0d117..6fc84b6a2de 100644
--- a/llvm/include/llvm/Analysis/CGSCCPassManager.h
+++ b/llvm/include/llvm/Analysis/CGSCCPassManager.h
@@ -41,146 +41,16 @@ typedef PassManager<LazyCallGraph::SCC> CGSCCPassManager;
/// pass manager infrastructure.
typedef AnalysisManager<LazyCallGraph::SCC> CGSCCAnalysisManager;
-/// \brief A module analysis which acts as a proxy for a CGSCC analysis
-/// manager.
-///
-/// This primarily proxies invalidation information from the module analysis
-/// manager and module pass manager to a CGSCC analysis manager. You should
-/// never use a CGSCC analysis manager from within (transitively) a module
-/// pass manager unless your parent module pass has received a proxy result
-/// object for it.
-///
-/// Note that the proxy's result is a move-only object and represents ownership
-/// of the validity of the analyses in the \c CGSCCAnalysisManager it provides.
-class CGSCCAnalysisManagerModuleProxy
- : public AnalysisBase<CGSCCAnalysisManagerModuleProxy> {
-public:
- class Result {
- public:
- explicit Result(CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
- Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of its responsibilty to clear the
- // analysis state.
- Arg.CGAM = nullptr;
- }
- Result &operator=(Result &&RHS) {
- CGAM = RHS.CGAM;
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of its responsibilty to clear the
- // analysis state.
- RHS.CGAM = nullptr;
- return *this;
- }
- ~Result();
-
- /// \brief Accessor for the \c CGSCCAnalysisManager.
- CGSCCAnalysisManager &getManager() { return *CGAM; }
-
- /// \brief Handler for invalidation of the module.
- ///
- /// If this analysis itself is preserved, then we assume that the call
- /// graph of the module hasn't changed and thus we don't need to invalidate
- /// *all* cached data associated with a \c SCC* in the \c
- /// CGSCCAnalysisManager.
- ///
- /// Regardless of whether this analysis is marked as preserved, all of the
- /// analyses in the \c CGSCCAnalysisManager are potentially invalidated
- /// based on the set of preserved analyses.
- bool invalidate(Module &M, const PreservedAnalyses &PA);
-
- private:
- CGSCCAnalysisManager *CGAM;
- };
-
- explicit CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManager &CGAM)
- : CGAM(&CGAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- CGSCCAnalysisManagerModuleProxy(const CGSCCAnalysisManagerModuleProxy &Arg)
- : CGAM(Arg.CGAM) {}
- CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManagerModuleProxy &&Arg)
- : CGAM(std::move(Arg.CGAM)) {}
- CGSCCAnalysisManagerModuleProxy &
- operator=(CGSCCAnalysisManagerModuleProxy RHS) {
- std::swap(CGAM, RHS.CGAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- ///
- /// This doesn't do any interesting work, it is primarily used to insert our
- /// proxy result object into the module analysis cache so that we can proxy
- /// invalidation to the CGSCC analysis manager.
- ///
- /// In debug builds, it will also assert that the analysis manager is empty
- /// as no queries should arrive at the CGSCC analysis manager prior to
- /// this analysis being requested.
- Result run(Module &M);
-
-private:
- CGSCCAnalysisManager *CGAM;
-};
+extern template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
+/// A proxy from a \c CGSCCAnalysisManager to a \c Module.
+typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>
+ CGSCCAnalysisManagerModuleProxy;
-/// \brief A CGSCC analysis which acts as a proxy for a module analysis
-/// manager.
-///
-/// This primarily provides an accessor to a parent module analysis manager to
-/// CGSCC passes. Only the const interface of the module analysis manager is
-/// provided to indicate that once inside of a CGSCC analysis pass you
-/// cannot request a module analysis to actually run. Instead, the user must
-/// rely on the \c getCachedResult API.
-///
-/// This proxy *doesn't* manage the invalidation in any way. That is handled by
-/// the recursive return path of each layer of the pass manager and the
-/// returned PreservedAnalysis set.
-class ModuleAnalysisManagerCGSCCProxy
- : public AnalysisBase<ModuleAnalysisManagerCGSCCProxy> {
-public:
- /// \brief Result proxy object for \c ModuleAnalysisManagerCGSCCProxy.
- class Result {
- public:
- explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : MAM(Arg.MAM) {}
- Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
- Result &operator=(Result RHS) {
- std::swap(MAM, RHS.MAM);
- return *this;
- }
-
- const ModuleAnalysisManager &getManager() const { return *MAM; }
-
- /// \brief Handle invalidation by ignoring it, this pass is immutable.
- bool invalidate(LazyCallGraph::SCC &) { return false; }
-
- private:
- const ModuleAnalysisManager *MAM;
- };
-
- ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManager &MAM)
- : MAM(&MAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManagerCGSCCProxy &Arg)
- : MAM(Arg.MAM) {}
- ModuleAnalysisManagerCGSCCProxy(ModuleAnalysisManagerCGSCCProxy &&Arg)
- : MAM(std::move(Arg.MAM)) {}
- ModuleAnalysisManagerCGSCCProxy &
- operator=(ModuleAnalysisManagerCGSCCProxy RHS) {
- std::swap(MAM, RHS.MAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- /// Nothing to see here, it just forwards the \c MAM reference into the
- /// result.
- Result run(LazyCallGraph::SCC &) { return Result(*MAM); }
-
-private:
- const ModuleAnalysisManager *MAM;
-};
+extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
+ LazyCallGraph::SCC>;
+/// A proxy from a \c ModuleAnalysisManager to an \c SCC.
+typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, LazyCallGraph::SCC>
+ ModuleAnalysisManagerCGSCCProxy;
/// \brief The core module pass which does a post-order walk of the SCCs and
/// runs a CGSCC pass over each one.
@@ -266,149 +136,16 @@ createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass));
}
-/// \brief A CGSCC analysis which acts as a proxy for a function analysis
-/// manager.
-///
-/// This primarily proxies invalidation information from the CGSCC analysis
-/// manager and CGSCC pass manager to a function analysis manager. You should
-/// never use a function analysis manager from within (transitively) a CGSCC
-/// pass manager unless your parent CGSCC pass has received a proxy result
-/// object for it.
-///
-/// Note that the proxy's result is a move-only object and represents ownership
-/// of the validity of the analyses in the \c FunctionAnalysisManager it
-/// provides.
-class FunctionAnalysisManagerCGSCCProxy
- : public AnalysisBase<FunctionAnalysisManagerCGSCCProxy> {
-public:
- class Result {
- public:
- explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of the responsibilty to clear the
- // analysis state.
- Arg.FAM = nullptr;
- }
- Result &operator=(Result &&RHS) {
- FAM = RHS.FAM;
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of the responsibilty to clear the
- // analysis state.
- RHS.FAM = nullptr;
- return *this;
- }
- ~Result();
-
- /// \brief Accessor for the \c FunctionAnalysisManager.
- FunctionAnalysisManager &getManager() { return *FAM; }
-
- /// \brief Handler for invalidation of the SCC.
- ///
- /// If this analysis itself is preserved, then we assume that the set of \c
- /// Function objects in the \c SCC hasn't changed and thus we don't need
- /// to invalidate *all* cached data associated with a \c Function* in the \c
- /// FunctionAnalysisManager.
- ///
- /// Regardless of whether this analysis is marked as preserved, all of the
- /// analyses in the \c FunctionAnalysisManager are potentially invalidated
- /// based on the set of preserved analyses.
- bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA);
-
- private:
- FunctionAnalysisManager *FAM;
- };
-
- explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM)
- : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- FunctionAnalysisManagerCGSCCProxy(
- const FunctionAnalysisManagerCGSCCProxy &Arg)
- : FAM(Arg.FAM) {}
- FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManagerCGSCCProxy &&Arg)
- : FAM(std::move(Arg.FAM)) {}
- FunctionAnalysisManagerCGSCCProxy &
- operator=(FunctionAnalysisManagerCGSCCProxy RHS) {
- std::swap(FAM, RHS.FAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- ///
- /// This doesn't do any interesting work, it is primarily used to insert our
- /// proxy result object into the module analysis cache so that we can proxy
- /// invalidation to the function analysis manager.
- ///
- /// In debug builds, it will also assert that the analysis manager is empty
- /// as no queries should arrive at the function analysis manager prior to
- /// this analysis being requested.
- Result run(LazyCallGraph::SCC &C);
-
-private:
- FunctionAnalysisManager *FAM;
-};
+extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
+ LazyCallGraph::SCC>;
+/// A proxy from a \c FunctionAnalysisManager to an \c SCC.
+typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, LazyCallGraph::SCC>
+ FunctionAnalysisManagerCGSCCProxy;
-/// \brief A function analysis which acts as a proxy for a CGSCC analysis
-/// manager.
-///
-/// This primarily provides an accessor to a parent CGSCC analysis manager to
-/// function passes. Only the const interface of the CGSCC analysis manager is
-/// provided to indicate that once inside of a function analysis pass you
-/// cannot request a CGSCC analysis to actually run. Instead, the user must
-/// rely on the \c getCachedResult API.
-///
-/// This proxy *doesn't* manage the invalidation in any way. That is handled by
-/// the recursive return path of each layer of the pass manager and the
-/// returned PreservedAnalysis set.
-class CGSCCAnalysisManagerFunctionProxy
- : public AnalysisBase<CGSCCAnalysisManagerFunctionProxy> {
-public:
- /// \brief Result proxy object for \c CGSCCAnalysisManagerFunctionProxy.
- class Result {
- public:
- explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : CGAM(Arg.CGAM) {}
- Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
- Result &operator=(Result RHS) {
- std::swap(CGAM, RHS.CGAM);
- return *this;
- }
-
- const CGSCCAnalysisManager &getManager() const { return *CGAM; }
-
- /// \brief Handle invalidation by ignoring it, this pass is immutable.
- bool invalidate(Function &) { return false; }
-
- private:
- const CGSCCAnalysisManager *CGAM;
- };
-
- CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM)
- : CGAM(&CGAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- CGSCCAnalysisManagerFunctionProxy(
- const CGSCCAnalysisManagerFunctionProxy &Arg)
- : CGAM(Arg.CGAM) {}
- CGSCCAnalysisManagerFunctionProxy(CGSCCAnalysisManagerFunctionProxy &&Arg)
- : CGAM(std::move(Arg.CGAM)) {}
- CGSCCAnalysisManagerFunctionProxy &
- operator=(CGSCCAnalysisManagerFunctionProxy RHS) {
- std::swap(CGAM, RHS.CGAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- /// Nothing to see here, it just forwards the \c CGAM reference into the
- /// result.
- Result run(Function &) { return Result(*CGAM); }
-
-private:
- const CGSCCAnalysisManager *CGAM;
-};
+extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
+/// A proxy from a \c CGSCCAnalysisManager to a \c Function.
+typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>
+ CGSCCAnalysisManagerFunctionProxy;
/// \brief Adaptor that maps from a SCC to its functions.
///
diff --git a/llvm/include/llvm/Analysis/LoopPassManager.h b/llvm/include/llvm/Analysis/LoopPassManager.h
index 9fd4c7bd141..8693855b313 100644
--- a/llvm/include/llvm/Analysis/LoopPassManager.h
+++ b/llvm/include/llvm/Analysis/LoopPassManager.h
@@ -36,136 +36,15 @@ typedef PassManager<Loop> LoopPassManager;
/// pass manager infrastructure.
typedef AnalysisManager<Loop> LoopAnalysisManager;
-/// \brief A function analysis which acts as a proxy for a loop analysis
-/// manager.
-///
-/// This primarily proxies invalidation information from the function analysis
-/// manager and function pass manager to a loop analysis manager. You should
-/// never use a loop analysis manager from within (transitively) a function
-/// pass manager unless your parent function pass has received a proxy result
-/// object for it.
-class LoopAnalysisManagerFunctionProxy
- : public AnalysisBase<LoopAnalysisManagerFunctionProxy> {
-public:
- class Result {
- public:
- explicit Result(LoopAnalysisManager &LAM) : LAM(&LAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : LAM(Arg.LAM) {}
- Result(Result &&Arg) : LAM(std::move(Arg.LAM)) {}
- Result &operator=(Result RHS) {
- std::swap(LAM, RHS.LAM);
- return *this;
- }
- ~Result();
-
- /// \brief Accessor for the \c LoopAnalysisManager.
- LoopAnalysisManager &getManager() { return *LAM; }
-
- /// \brief Handler for invalidation of the function.
- ///
- /// If this analysis itself is preserved, then we assume that the function
- /// hasn't changed and thus we don't need to invalidate *all* cached data
- /// associated with a \c Loop* in the \c LoopAnalysisManager.
- ///
- /// Regardless of whether this analysis is marked as preserved, all of the
- /// analyses in the \c LoopAnalysisManager are potentially invalidated based
- /// on the set of preserved analyses.
- bool invalidate(Function &F, const PreservedAnalyses &PA);
-
- private:
- LoopAnalysisManager *LAM;
- };
-
- explicit LoopAnalysisManagerFunctionProxy(LoopAnalysisManager &LAM)
- : LAM(&LAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- LoopAnalysisManagerFunctionProxy(const LoopAnalysisManagerFunctionProxy &Arg)
- : LAM(Arg.LAM) {}
- LoopAnalysisManagerFunctionProxy(LoopAnalysisManagerFunctionProxy &&Arg)
- : LAM(std::move(Arg.LAM)) {}
- LoopAnalysisManagerFunctionProxy &
- operator=(LoopAnalysisManagerFunctionProxy RHS) {
- std::swap(LAM, RHS.LAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- ///
- /// This doesn't do any interesting work, it is primarily used to insert our
- /// proxy result object into the function analysis cache so that we can proxy
- /// invalidation to the loop analysis manager.
- ///
- /// In debug builds, it will also assert that the analysis manager is empty as
- /// no queries should arrive at the loop analysis manager prior to this
- /// analysis being requested.
- Result run(Function &F);
-
-private:
- LoopAnalysisManager *LAM;
-};
-
-/// \brief A loop analysis which acts as a proxy for a function analysis
-/// manager.
-///
-/// This primarily provides an accessor to a parent function analysis manager to
-/// loop passes. Only the const interface of the function analysis manager is
-/// provided to indicate that once inside of a loop analysis pass you cannot
-/// request a function analysis to actually run. Instead, the user must rely on
-/// the \c getCachedResult API.
-///
-/// This proxy *doesn't* manage the invalidation in any way. That is handled by
-/// the recursive return path of each layer of the pass manager and the
-/// returned PreservedAnalysis set.
-class FunctionAnalysisManagerLoopProxy
- : public AnalysisBase<FunctionAnalysisManagerLoopProxy> {
-public:
- /// \brief Result proxy object for \c FunctionAnalysisManagerLoopProxy.
- class Result {
- public:
- explicit Result(const FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : FAM(Arg.FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
- Result &operator=(Result RHS) {
- std::swap(FAM, RHS.FAM);
- return *this;
- }
-
- const FunctionAnalysisManager &getManager() const { return *FAM; }
-
- /// \brief Handle invalidation by ignoring it, this pass is immutable.
- bool invalidate(Function &) { return false; }
-
- private:
- const FunctionAnalysisManager *FAM;
- };
-
- FunctionAnalysisManagerLoopProxy(const FunctionAnalysisManager &FAM)
- : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- FunctionAnalysisManagerLoopProxy(const FunctionAnalysisManagerLoopProxy &Arg)
- : FAM(Arg.FAM) {}
- FunctionAnalysisManagerLoopProxy(FunctionAnalysisManagerLoopProxy &&Arg)
- : FAM(std::move(Arg.FAM)) {}
- FunctionAnalysisManagerLoopProxy &
- operator=(FunctionAnalysisManagerLoopProxy RHS) {
- std::swap(FAM, RHS.FAM);
- return *this;
- }
-
- /// \brief Run the analysis pass and create our proxy result object.
- /// Nothing to see here, it just forwards the \c FAM reference into the
- /// result.
- Result run(Loop &) { return Result(*FAM); }
-
-private:
- const FunctionAnalysisManager *FAM;
-};
+extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
+/// A proxy from a \c LoopAnalysisManager to a \c Function.
+typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
+ LoopAnalysisManagerFunctionProxy;
+
+extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
+/// A proxy from a \c FunctionAnalysisManager to a \c Loop.
+typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
+ FunctionAnalysisManagerLoopProxy;
/// \brief Adaptor that maps from a function to its loops.
///
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index 68f74f8a616..e51142d5e32 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -651,23 +651,76 @@ typedef AnalysisManager<Function> FunctionAnalysisManager;
/// Note that the proxy's result is a move-only object and represents ownership
/// of the validity of the analyses in the \c FunctionAnalysisManager it
/// provides.
-class FunctionAnalysisManagerModuleProxy
- : public AnalysisBase<FunctionAnalysisManagerModuleProxy> {
+template <typename AnalysisManagerT, typename IRUnitT>
+class InnerAnalysisManagerProxy
+ : public AnalysisBase<
+ InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
public:
- class Result;
+ class Result {
+ public:
+ explicit Result(AnalysisManagerT &AM) : AM(&AM) {}
+ Result(Result &&Arg) : AM(std::move(Arg.AM)) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ Arg.AM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ AM = RHS.AM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.AM = nullptr;
+ return *this;
+ }
+ ~Result() {
+ // AM is cleared in a moved from state where there is nothing to do.
+ if (!AM)
+ return;
+
+ // Clear out the analysis manager if we're being destroyed -- it means we
+ // didn't even see an invalidate call when we got invalidated.
+ AM->clear();
+ }
+
+ /// \brief Accessor for the analysis manager.
+ AnalysisManagerT &getManager() { return *AM; }
+
+ /// \brief Handler for invalidation of the module.
+ ///
+ /// If this analysis itself is preserved, then we assume that the set of \c
+ /// Function objects in the \c Module hasn't changed and thus we don't need
+ /// to invalidate *all* cached data associated with a \c Function* in the \c
+ /// FunctionAnalysisManager.
+ ///
+ /// Regardless of whether this analysis is marked as preserved, all of the
+ /// analyses in the \c FunctionAnalysisManager are potentially invalidated
+ /// based on the set of preserved analyses.
+ bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
+ // If this proxy isn't marked as preserved, then we can't even invalidate
+ // individual function analyses, there may be an invalid set of Function
+ // objects in the cache making it impossible to incrementally preserve
+ // them. Just clear the entire manager.
+ if (!PA.preserved(InnerAnalysisManagerProxy::ID()))
+ AM->clear();
+
+ // Return false to indicate that this result is still a valid proxy.
+ return false;
+ }
+
+ private:
+ AnalysisManagerT *AM;
+ };
- explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
- : FAM(&FAM) {}
+ explicit InnerAnalysisManagerProxy(AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- FunctionAnalysisManagerModuleProxy(
- const FunctionAnalysisManagerModuleProxy &Arg)
- : FAM(Arg.FAM) {}
- FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
- : FAM(std::move(Arg.FAM)) {}
- FunctionAnalysisManagerModuleProxy &
- operator=(FunctionAnalysisManagerModuleProxy RHS) {
- std::swap(FAM, RHS.FAM);
+ InnerAnalysisManagerProxy(const InnerAnalysisManagerProxy &Arg)
+ : AM(Arg.AM) {}
+ InnerAnalysisManagerProxy(InnerAnalysisManagerProxy &&Arg)
+ : AM(std::move(Arg.AM)) {}
+ InnerAnalysisManagerProxy &operator=(InnerAnalysisManagerProxy RHS) {
+ std::swap(AM, RHS.AM);
return *this;
}
@@ -680,53 +733,17 @@ public:
/// In debug builds, it will also assert that the analysis manager is empty
/// as no queries should arrive at the function analysis manager prior to
/// this analysis being requested.
- Result run(Module &M);
+ Result run(IRUnitT &IR) { return Result(*AM); }
private:
- FunctionAnalysisManager *FAM;
+ AnalysisManagerT *AM;
};
-/// \brief The result proxy object for the
-/// \c FunctionAnalysisManagerModuleProxy.
-///
-/// See its documentation for more information.
-class FunctionAnalysisManagerModuleProxy::Result {
-public:
- explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of the responsibilty to clear the
- // analysis state.
- Arg.FAM = nullptr;
- }
- Result &operator=(Result &&RHS) {
- FAM = RHS.FAM;
- // We have to null out the analysis manager in the moved-from state
- // because we are taking ownership of the responsibilty to clear the
- // analysis state.
- RHS.FAM = nullptr;
- return *this;
- }
- ~Result();
-
- /// \brief Accessor for the \c FunctionAnalysisManager.
- FunctionAnalysisManager &getManager() { return *FAM; }
-
- /// \brief Handler for invalidation of the module.
- ///
- /// If this analysis itself is preserved, then we assume that the set of \c
- /// Function objects in the \c Module hasn't changed and thus we don't need
- /// to invalidate *all* cached data associated with a \c Function* in the \c
- /// FunctionAnalysisManager.
- ///
- /// Regardless of whether this analysis is marked as preserved, all of the
- /// analyses in the \c FunctionAnalysisManager are potentially invalidated
- /// based on the set of preserved analyses.
- bool invalidate(Module &M, const PreservedAnalyses &PA);
-
-private:
- FunctionAnalysisManager *FAM;
-};
+extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
+ Module>;
+/// Provide the \c FunctionAnalysisManager to \c Module proxy.
+typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
+ FunctionAnalysisManagerModuleProxy;
/// \brief A function analysis which acts as a proxy for a module analysis
/// manager.
@@ -740,55 +757,60 @@ private:
/// This proxy *doesn't* manage the invalidation in any way. That is handled by
/// the recursive return path of each layer of the pass manager and the
/// returned PreservedAnalysis set.
-class ModuleAnalysisManagerFunctionProxy
- : public AnalysisBase<ModuleAnalysisManagerFunctionProxy> {
+template <typename AnalysisManagerT, typename IRUnitT>
+class OuterAnalysisManagerProxy
+ : public AnalysisBase<
+ OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
public:
- /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+ /// \brief Result proxy object for \c OuterAnalysisManagerProxy.
class Result {
public:
- explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+ explicit Result(const AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because
// MSVC refuses to generate them.
- Result(const Result &Arg) : MAM(Arg.MAM) {}
- Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
+ Result(const Result &Arg) : AM(Arg.AM) {}
+ Result(Result &&Arg) : AM(std::move(Arg.AM)) {}
Result &operator=(Result RHS) {
- std::swap(MAM, RHS.MAM);
+ std::swap(AM, RHS.AM);
return *this;
}
- const ModuleAnalysisManager &getManager() const { return *MAM; }
+ const AnalysisManagerT &getManager() const { return *AM; }
/// \brief Handle invalidation by ignoring it, this pass is immutable.
- bool invalidate(Function &) { return false; }
+ bool invalidate(IRUnitT &) { return false; }
private:
- const ModuleAnalysisManager *MAM;
+ const AnalysisManagerT *AM;
};
- ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
- : MAM(&MAM) {}
+ OuterAnalysisManagerProxy(const AnalysisManagerT &AM) : AM(&AM) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- ModuleAnalysisManagerFunctionProxy(
- const ModuleAnalysisManagerFunctionProxy &Arg)
- : MAM(Arg.MAM) {}
- ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
- : MAM(std::move(Arg.MAM)) {}
- ModuleAnalysisManagerFunctionProxy &
- operator=(ModuleAnalysisManagerFunctionProxy RHS) {
- std::swap(MAM, RHS.MAM);
+ OuterAnalysisManagerProxy(const OuterAnalysisManagerProxy &Arg)
+ : AM(Arg.AM) {}
+ OuterAnalysisManagerProxy(OuterAnalysisManagerProxy &&Arg)
+ : AM(std::move(Arg.AM)) {}
+ OuterAnalysisManagerProxy &operator=(OuterAnalysisManagerProxy RHS) {
+ std::swap(AM, RHS.AM);
return *this;
}
/// \brief Run the analysis pass and create our proxy result object.
- /// Nothing to see here, it just forwards the \c MAM reference into the
+ /// Nothing to see here, it just forwards the \c AM reference into the
/// result.
- Result run(Function &) { return Result(*MAM); }
+ Result run(IRUnitT &) { return Result(*AM); }
private:
- const ModuleAnalysisManager *MAM;
+ const AnalysisManagerT *AM;
};
+extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
+ Function>;
+/// Provide the \c ModuleAnalysisManager to \c Fucntion proxy.
+typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>
+ ModuleAnalysisManagerFunctionProxy;
+
/// \brief Trivial adaptor that maps from a module to its functions.
///
/// Designed to allow composition of a FunctionPass(Manager) and
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index 69c37f57528..d5058d6aab1 100644
--- a/llvm/lib/Analysis/CGSCCPassManager.cpp
+++ b/llvm/lib/Analysis/CGSCCPassManager.cpp
@@ -13,59 +13,12 @@
using namespace llvm;
-CGSCCAnalysisManagerModuleProxy::Result
-CGSCCAnalysisManagerModuleProxy::run(Module &M) {
- assert(CGAM->empty() && "CGSCC analyses ran prior to the module proxy!");
- return Result(*CGAM);
-}
-
-CGSCCAnalysisManagerModuleProxy::Result::~Result() {
- // CGAM is cleared in a moved from state where there is nothing to do.
- if (!CGAM)
- return;
-
- // Clear out the analysis manager if we're being destroyed -- it means we
- // didn't even see an invalidate call when we got invalidated.
- CGAM->clear();
-}
-
-bool CGSCCAnalysisManagerModuleProxy::Result::invalidate(
- Module &M, const PreservedAnalyses &PA) {
- // If this proxy isn't marked as preserved, then we can't even invalidate
- // individual CGSCC analyses, there may be an invalid set of SCC objects in
- // the cache making it impossible to incrementally preserve them.
- // Just clear the entire manager.
- if (!PA.preserved(ID()))
- CGAM->clear();
-
- // Return false to indicate that this result is still a valid proxy.
- return false;
-}
-
-FunctionAnalysisManagerCGSCCProxy::Result
-FunctionAnalysisManagerCGSCCProxy::run(LazyCallGraph::SCC &C) {
- return Result(*FAM);
-}
-
-FunctionAnalysisManagerCGSCCProxy::Result::~Result() {
- // FAM is cleared in a moved from state where there is nothing to do.
- if (!FAM)
- return;
-
- // 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 FunctionAnalysisManagerCGSCCProxy::Result::invalidate(
- LazyCallGraph::SCC &C, const PreservedAnalyses &PA) {
- // If this proxy isn't marked as preserved, then we can't even invalidate
- // individual function analyses, there may be an invalid set of Function
- // objects in the cache making it impossible to incrementally preserve them.
- // Just clear the entire manager.
- if (!PA.preserved(ID()))
- FAM->clear();
-
- // Return false to indicate that this result is still a valid proxy.
- return false;
+// Explicit instantiations for the core proxy templates.
+namespace llvm {
+template class InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>;
+template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
+ LazyCallGraph::SCC>;
+template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
+ LazyCallGraph::SCC>;
+template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
}
diff --git a/llvm/lib/Analysis/LoopPassManager.cpp b/llvm/lib/Analysis/LoopPassManager.cpp
index 1d87e07b837..fd77b786262 100644
--- a/llvm/lib/Analysis/LoopPassManager.cpp
+++ b/llvm/lib/Analysis/LoopPassManager.cpp
@@ -11,31 +11,8 @@
using namespace llvm;
-LoopAnalysisManagerFunctionProxy::Result
-LoopAnalysisManagerFunctionProxy::run(Function &F) {
- // TODO: In FunctionAnalysisManagerModuleProxy we assert that the
- // AnalysisManager is empty, but if we do that here we run afoul of the fact
- // that we still have results for previous functions alive. Should we be
- // clearing those when we finish a function?
- //assert(LAM->empty() && "Loop analyses ran prior to the function proxy!");
- return Result(*LAM);
-}
-
-LoopAnalysisManagerFunctionProxy::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.
- LAM->clear();
-}
-
-bool LoopAnalysisManagerFunctionProxy::Result::invalidate(
- Function &F, const PreservedAnalyses &PA) {
- // If this proxy isn't marked as preserved, then we can't even invalidate
- // individual loop analyses, there may be an invalid set of Loops in the cache
- // making it impossible to incrementally preserve them. Just clear the entire
- // manager.
- if (!PA.preserved(ID()))
- LAM->clear();
-
- // Return false to indicate that this result is still a valid proxy.
- return false;
+// Explicit instantiations for core typedef'ed templates.
+namespace llvm {
+template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
+template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
}
diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index 06491ae08a7..18e7a73f03e 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/lib/IR/PassManager.cpp
@@ -13,31 +13,8 @@
using namespace llvm;
-FunctionAnalysisManagerModuleProxy::Result
-FunctionAnalysisManagerModuleProxy::run(Module &M) {
- assert(FAM->empty() && "Function analyses ran prior to the module proxy!");
- return Result(*FAM);
-}
-
-FunctionAnalysisManagerModuleProxy::Result::~Result() {
- // FAM is cleared in a moved from state where there is nothing to do.
- if (!FAM)
- return;
-
- // 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 FunctionAnalysisManagerModuleProxy::Result::invalidate(
- Module &M, const PreservedAnalyses &PA) {
- // If this proxy isn't marked as preserved, then we can't even invalidate
- // individual function analyses, there may be an invalid set of Function
- // objects in the cache making it impossible to incrementally preserve them.
- // Just clear the entire manager.
- if (!PA.preserved(ID()))
- FAM->clear();
-
- // Return false to indicate that this result is still a valid proxy.
- return false;
+// Explicit template instantiations for core template typedefs.
+namespace llvm {
+template class InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
+template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
}
diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll
index f1a7ef68ff6..11a31ae8f7a 100644
--- a/llvm/test/Other/new-pass-manager.ll
+++ b/llvm/test/Other/new-pass-manager.ll
@@ -20,7 +20,7 @@
; RUN: | FileCheck %s --check-prefix=CHECK-CGSCC-PASS
; CHECK-CGSCC-PASS: Starting llvm::Module pass manager run
; CHECK-CGSCC-PASS-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor
-; CHECK-CGSCC-PASS-NEXT: Running analysis: CGSCCAnalysisManagerModuleProxy
+; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<CGSCCAnalysisManager, llvm::Module>
; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
@@ -35,7 +35,7 @@
; RUN: | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
; CHECK-FUNCTION-PASS: Starting llvm::Module pass manager run
; CHECK-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
-; CHECK-FUNCTION-PASS-NEXT: Running analysis: FunctionAnalysisManagerModuleProxy
+; CHECK-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<FunctionAnalysisManager, llvm::Module>
; CHECK-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
; CHECK-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
@@ -65,7 +65,7 @@
; CHECK-FUNCTION-PRINT: Starting llvm::Module pass manager run
; CHECK-FUNCTION-PRINT: Running pass: VerifierPass
; CHECK-FUNCTION-PRINT: Running pass: ModuleToFunctionPassAdaptor
-; CHECK-FUNCTION-PRINT: Running analysis: FunctionAnalysisManagerModuleProxy
+; CHECK-FUNCTION-PRINT: Running analysis: InnerAnalysisManagerProxy<FunctionAnalysisManager, llvm::Module>
; CHECK-FUNCTION-PRINT: Starting llvm::Function pass manager run
; CHECK-FUNCTION-PRINT: Running pass: PrintFunctionPass
; CHECK-FUNCTION-PRINT-NOT: ModuleID
OpenPOWER on IntegriCloud