aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Analysis/CGSCCPassManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Analysis/CGSCCPassManager.h')
-rw-r--r--include/llvm/Analysis/CGSCCPassManager.h192
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