Merging r259886 and r259888:
[oota-llvm.git] / include / llvm / Analysis / CGSCCPassManager.h
index 1533b36f24ca28074264bae350f6f6f182e10e3d..e7635eb1ab678431915779fbb7723ce2830f59b7 100644 (file)
 #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.
@@ -369,8 +263,7 @@ private:
 template <typename CGSCCPassT>
 ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
-  return std::move(
-      ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass)));
+  return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass));
 }
 
 /// \brief A CGSCC analysis which acts as a proxy for a function analysis
@@ -409,7 +302,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 +310,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 +336,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;
@@ -463,7 +358,7 @@ private:
 /// returned PreservedAnalysis set.
 class CGSCCAnalysisManagerFunctionProxy {
 public:
-  /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+  /// \brief Result proxy object for \c CGSCCAnalysisManagerFunctionProxy.
   class Result {
   public:
     explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
@@ -479,7 +374,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 +382,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 +402,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 +428,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 +439,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.
@@ -583,9 +483,8 @@ private:
 template <typename FunctionPassT>
 CGSCCToFunctionPassAdaptor<FunctionPassT>
 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
-  return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
+  return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
 }
-
 }
 
 #endif