diff options
Diffstat (limited to 'include/llvm/Analysis/CGSCCPassManager.h')
-rw-r--r-- | include/llvm/Analysis/CGSCCPassManager.h | 192 |
1 files changed, 46 insertions, 146 deletions
diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h index 1533b36..0d4fe93 100644 --- a/include/llvm/Analysis/CGSCCPassManager.h +++ b/include/llvm/Analysis/CGSCCPassManager.h @@ -21,135 +21,25 @@ #ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H #define LLVM_ANALYSIS_CGSCCPASSMANAGER_H -#include "llvm/IR/PassManager.h" #include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/IR/PassManager.h" namespace llvm { -class CGSCCAnalysisManager; - -class CGSCCPassManager { -public: - // We have to explicitly define all the special member functions because MSVC - // refuses to generate them. - CGSCCPassManager() {} - CGSCCPassManager(CGSCCPassManager &&Arg) : Passes(std::move(Arg.Passes)) {} - CGSCCPassManager &operator=(CGSCCPassManager &&RHS) { - Passes = std::move(RHS.Passes); - return *this; - } - - /// \brief Run all of the CGSCC passes in this pass manager over a SCC. - PreservedAnalyses run(LazyCallGraph::SCC *C, - CGSCCAnalysisManager *AM = nullptr); - - template <typename CGSCCPassT> void addPass(CGSCCPassT Pass) { - Passes.emplace_back(new CGSCCPassModel<CGSCCPassT>(std::move(Pass))); - } - - static StringRef name() { return "CGSCCPassManager"; } - -private: - // Pull in the concept type and model template specialized for SCCs. - typedef detail::PassConcept<LazyCallGraph::SCC *, CGSCCAnalysisManager> - CGSCCPassConcept; - template <typename PassT> - struct CGSCCPassModel - : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT> { - CGSCCPassModel(PassT Pass) - : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT>( - std::move(Pass)) {} - }; - - CGSCCPassManager(const CGSCCPassManager &) LLVM_DELETED_FUNCTION; - CGSCCPassManager &operator=(const CGSCCPassManager &) LLVM_DELETED_FUNCTION; - - std::vector<std::unique_ptr<CGSCCPassConcept>> Passes; -}; - -/// \brief A function analysis manager to coordinate and cache analyses run over -/// a module. -class CGSCCAnalysisManager : public detail::AnalysisManagerBase< - CGSCCAnalysisManager, LazyCallGraph::SCC *> { - friend class detail::AnalysisManagerBase<CGSCCAnalysisManager, - LazyCallGraph::SCC *>; - typedef detail::AnalysisManagerBase<CGSCCAnalysisManager, - LazyCallGraph::SCC *> BaseT; - typedef BaseT::ResultConceptT ResultConceptT; - typedef BaseT::PassConceptT PassConceptT; - -public: - // Most public APIs are inherited from the CRTP base class. - - // We have to explicitly define all the special member functions because MSVC - // refuses to generate them. - CGSCCAnalysisManager() {} - CGSCCAnalysisManager(CGSCCAnalysisManager &&Arg) - : BaseT(std::move(static_cast<BaseT &>(Arg))), - CGSCCAnalysisResults(std::move(Arg.CGSCCAnalysisResults)) {} - CGSCCAnalysisManager &operator=(CGSCCAnalysisManager &&RHS) { - BaseT::operator=(std::move(static_cast<BaseT &>(RHS))); - CGSCCAnalysisResults = std::move(RHS.CGSCCAnalysisResults); - return *this; - } - - /// \brief Returns true if the analysis manager has an empty results cache. - bool empty() const; - - /// \brief Clear the function analysis result cache. - /// - /// This routine allows cleaning up when the set of functions itself has - /// potentially changed, and thus we can't even look up a a result and - /// invalidate it directly. Notably, this does *not* call invalidate - /// functions as there is nothing to be done for them. - void clear(); - -private: - CGSCCAnalysisManager(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION; - CGSCCAnalysisManager & - operator=(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION; - - /// \brief Get a function pass result, running the pass if necessary. - ResultConceptT &getResultImpl(void *PassID, LazyCallGraph::SCC *C); - - /// \brief Get a cached function pass result or return null. - ResultConceptT *getCachedResultImpl(void *PassID, - LazyCallGraph::SCC *C) const; - - /// \brief Invalidate a function pass result. - void invalidateImpl(void *PassID, LazyCallGraph::SCC *C); - - /// \brief Invalidate the results for a function.. - void invalidateImpl(LazyCallGraph::SCC *C, const PreservedAnalyses &PA); +/// \brief The CGSCC pass manager. +/// +/// See the documentation for the PassManager template for details. It runs +/// a sequency of SCC passes over each SCC that the manager is run over. This +/// typedef serves as a convenient way to refer to this construct. +typedef PassManager<LazyCallGraph::SCC> CGSCCPassManager; - /// \brief List of function analysis pass IDs and associated concept pointers. - /// - /// 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 *, std::unique_ptr<detail::AnalysisResultConcept< - LazyCallGraph::SCC *>>>> CGSCCAnalysisResultListT; - - /// \brief Map type from function pointer to our custom list type. - typedef DenseMap<LazyCallGraph::SCC *, CGSCCAnalysisResultListT> - CGSCCAnalysisResultListMapT; - - /// \brief Map from function to a list of function analysis results. - /// - /// Provides linear time removal of all analysis results for a function and - /// the ultimate storage for a particular cached analysis result. - CGSCCAnalysisResultListMapT CGSCCAnalysisResultLists; - - /// \brief Map type from a pair of analysis ID and function pointer to an - /// iterator into a particular result list. - typedef DenseMap<std::pair<void *, LazyCallGraph::SCC *>, - CGSCCAnalysisResultListT::iterator> CGSCCAnalysisResultMapT; - - /// \brief Map from an analysis ID and function to a particular cached - /// analysis result. - CGSCCAnalysisResultMapT CGSCCAnalysisResults; -}; +/// \brief The CGSCC analysis manager. +/// +/// See the documentation for the AnalysisManager template for detail +/// documentation. This typedef serves as a convenient way to refer to this +/// construct in the adaptors and proxies used to integrate this into the larger +/// pass manager infrastructure. +typedef AnalysisManager<LazyCallGraph::SCC> CGSCCAnalysisManager; /// \brief A module analysis which acts as a proxy for a CGSCC analysis /// manager. @@ -187,7 +77,7 @@ public: /// 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); + bool invalidate(Module &M, const PreservedAnalyses &PA); private: CGSCCAnalysisManager *CGAM; @@ -195,12 +85,13 @@ public: static void *ID() { return (void *)&PassID; } + static StringRef name() { return "CGSCCAnalysisManagerModuleProxy"; } + 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) + CGSCCAnalysisManagerModuleProxy(const CGSCCAnalysisManagerModuleProxy &Arg) : CGAM(Arg.CGAM) {} CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManagerModuleProxy &&Arg) : CGAM(std::move(Arg.CGAM)) {} @@ -219,7 +110,7 @@ public: /// 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); + Result run(Module &M); private: static char PassID; @@ -257,7 +148,7 @@ public: const ModuleAnalysisManager &getManager() const { return *MAM; } /// \brief Handle invalidation by ignoring it, this pass is immutable. - bool invalidate(LazyCallGraph::SCC *) { return false; } + bool invalidate(LazyCallGraph::SCC &) { return false; } private: const ModuleAnalysisManager *MAM; @@ -265,12 +156,13 @@ public: static void *ID() { return (void *)&PassID; } + static StringRef name() { return "ModuleAnalysisManagerCGSCCProxy"; } + 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) + ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManagerCGSCCProxy &Arg) : MAM(Arg.MAM) {} ModuleAnalysisManagerCGSCCProxy(ModuleAnalysisManagerCGSCCProxy &&Arg) : MAM(std::move(Arg.MAM)) {} @@ -283,7 +175,7 @@ public: /// \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); } + Result run(LazyCallGraph::SCC &) { return Result(*MAM); } private: static char PassID; @@ -323,7 +215,7 @@ public: } /// \brief Runs the CGSCC pass across every SCC in the module. - PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) { + PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) { assert(AM && "We need analyses to compute the call graph!"); // Setup the CGSCC analysis manager from its proxy. @@ -335,15 +227,17 @@ public: PreservedAnalyses PA = PreservedAnalyses::all(); for (LazyCallGraph::SCC &C : CG.postorder_sccs()) { - PreservedAnalyses PassPA = Pass.run(&C, &CGAM); + PreservedAnalyses PassPA = Pass.run(C, &CGAM); // We know that the CGSCC pass couldn't have invalidated any other // SCC's analyses (that's the contract of a CGSCC pass), so - // directly handle the CGSCC analysis manager's invalidation here. + // directly handle the CGSCC analysis manager's invalidation here. We + // also update the preserved set of analyses to reflect that invalidated + // analyses are now safe to preserve. // FIXME: This isn't quite correct. We need to handle the case where the // pass updated the CG, particularly some child of the current SCC, and // invalidate its analyses. - CGAM.invalidate(&C, PassPA); + PassPA = CGAM.invalidate(C, std::move(PassPA)); // Then intersect the preserved set so that invalidation of module // analyses will eventually occur when the module pass completes. @@ -409,7 +303,7 @@ public: /// 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); + bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA); private: FunctionAnalysisManager *FAM; @@ -417,6 +311,8 @@ public: static void *ID() { return (void *)&PassID; } + static StringRef name() { return "FunctionAnalysisManagerCGSCCProxy"; } + explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM) : FAM(&FAM) {} // We have to explicitly define all the special member functions because MSVC @@ -441,7 +337,7 @@ 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(LazyCallGraph::SCC *C); + Result run(LazyCallGraph::SCC &C); private: static char PassID; @@ -479,7 +375,7 @@ public: const CGSCCAnalysisManager &getManager() const { return *CGAM; } /// \brief Handle invalidation by ignoring it, this pass is immutable. - bool invalidate(Function *) { return false; } + bool invalidate(Function &) { return false; } private: const CGSCCAnalysisManager *CGAM; @@ -487,6 +383,8 @@ public: static void *ID() { return (void *)&PassID; } + static StringRef name() { return "CGSCCAnalysisManagerFunctionProxy"; } + CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {} // We have to explicitly define all the special member functions because MSVC @@ -505,7 +403,7 @@ public: /// \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); } + Result run(Function &) { return Result(*CGAM); } private: static char PassID; @@ -531,7 +429,8 @@ public: : Pass(Arg.Pass) {} CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg) : Pass(std::move(Arg.Pass)) {} - friend void swap(CGSCCToFunctionPassAdaptor &LHS, CGSCCToFunctionPassAdaptor &RHS) { + friend void swap(CGSCCToFunctionPassAdaptor &LHS, + CGSCCToFunctionPassAdaptor &RHS) { using std::swap; swap(LHS.Pass, RHS.Pass); } @@ -541,21 +440,23 @@ public: } /// \brief Runs the function pass across every function in the module. - PreservedAnalyses run(LazyCallGraph::SCC *C, CGSCCAnalysisManager *AM) { + PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager *AM) { FunctionAnalysisManager *FAM = nullptr; if (AM) // Setup the function analysis manager from its proxy. FAM = &AM->getResult<FunctionAnalysisManagerCGSCCProxy>(C).getManager(); PreservedAnalyses PA = PreservedAnalyses::all(); - for (LazyCallGraph::Node *N : *C) { - PreservedAnalyses PassPA = Pass.run(&N->getFunction(), FAM); + for (LazyCallGraph::Node *N : C) { + PreservedAnalyses PassPA = Pass.run(N->getFunction(), FAM); // We know that the function pass couldn't have invalidated any other // function's analyses (that's the contract of a function pass), so // directly handle the function analysis manager's invalidation here. + // Also, update the preserved analyses to reflect that once invalidated + // these can again be preserved. if (FAM) - FAM->invalidate(&N->getFunction(), PassPA); + PassPA = FAM->invalidate(N->getFunction(), std::move(PassPA)); // Then intersect the preserved set so that invalidation of module // analyses will eventually occur when the module pass completes. @@ -585,7 +486,6 @@ CGSCCToFunctionPassAdaptor<FunctionPassT> createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) { return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass))); } - } #endif |