PM: Print the IR unit's name in debug output. NFC
[oota-llvm.git] / include / llvm / IR / PassManager.h
index 550823fa2e50aafdae948bf4bca1d9f5158c5ccf..2ceb53d21b7a91ed2a1fa4e90ade26a400286e1b 100644 (file)
@@ -46,6 +46,7 @@
 #include "llvm/IR/PassManagerInternal.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/type_traits.h"
 #include <list>
 #include <memory>
@@ -56,13 +57,6 @@ namespace llvm {
 class Module;
 class Function;
 
-namespace detail {
-
-// Declare our debug option here so we can refer to it from templates.
-extern cl::opt<bool> DebugPM;
-
-} // End detail namespace
-
 /// \brief An abstract set of preserved analyses following a transformation pass
 /// run.
 ///
@@ -169,130 +163,101 @@ private:
   SmallPtrSet<void *, 2> PreservedPassIDs;
 };
 
-// Forward declare the analysis manager template and two typedefs used in the
-// pass managers.
+// Forward declare the analysis manager template.
 template <typename IRUnitT> class AnalysisManager;
-typedef AnalysisManager<Module> ModuleAnalysisManager;
-typedef AnalysisManager<Function> FunctionAnalysisManager;
 
-/// \brief Manages a sequence of passes over Modules of IR.
+/// \brief Manages a sequence of passes over units of IR.
 ///
-/// A module pass manager contains a sequence of module passes. It is also
-/// itself a module pass. When it is run over a module of LLVM IR, it will
-/// sequentially run each pass it contains over that module.
+/// A pass manager contains a sequence of passes to run over units of IR. It is
+/// itself a valid pass over that unit of IR, and when over some given IR will
+/// run each pass in sequence. This is the primary and most basic building
+/// block of a pass pipeline.
 ///
-/// If it is run with a \c ModuleAnalysisManager argument, it will propagate
+/// If it is run with an \c AnalysisManager<IRUnitT> argument, it will propagate
 /// that analysis manager to each pass it runs, as well as calling the analysis
 /// manager's invalidation routine with the PreservedAnalyses of each pass it
 /// runs.
-///
-/// Module passes can rely on having exclusive access to the module they are
-/// run over. No other threads will access that module, and they can mutate it
-/// freely. However, they must not mutate other LLVM IR modules.
-class ModulePassManager {
+template <typename IRUnitT> class PassManager {
 public:
+  /// \brief Construct a pass manager.
+  ///
+  /// It can be passed a flag to get debug logging as the passes are run.
+  PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
   // We have to explicitly define all the special member functions because MSVC
   // refuses to generate them.
-  ModulePassManager() {}
-  ModulePassManager(ModulePassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
-  ModulePassManager &operator=(ModulePassManager &&RHS) {
+  PassManager(PassManager &&Arg)
+      : Passes(std::move(Arg.Passes)),
+        DebugLogging(std::move(Arg.DebugLogging)) {}
+  PassManager &operator=(PassManager &&RHS) {
     Passes = std::move(RHS.Passes);
+    DebugLogging = std::move(RHS.DebugLogging);
     return *this;
   }
 
-  /// \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.
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM = nullptr);
+  /// \brief Run all of the passes in this manager over the IR.
+  PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
+    PreservedAnalyses PA = PreservedAnalyses::all();
 
-  template <typename ModulePassT> void addPass(ModulePassT Pass) {
-    Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
-  }
+    if (DebugLogging)
+      dbgs() << "Starting pass manager run.\n";
 
-  static StringRef name() { return "ModulePassManager"; }
+    for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
+      if (DebugLogging)
+        dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
+               << IR.getName() << "\n";
 
-private:
-  // Pull in the concept type and model template specialized for modules.
-  typedef detail::PassConcept<Module, ModuleAnalysisManager> ModulePassConcept;
-  template <typename PassT>
-  struct ModulePassModel
-      : detail::PassModel<Module, ModuleAnalysisManager, PassT> {
-    ModulePassModel(PassT Pass)
-        : detail::PassModel<Module, ModuleAnalysisManager, PassT>(
-              std::move(Pass)) {}
-  };
+      PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
 
-  ModulePassManager(const ModulePassManager &) LLVM_DELETED_FUNCTION;
-  ModulePassManager &operator=(const ModulePassManager &) LLVM_DELETED_FUNCTION;
+      // If we have an active analysis manager at this level we want to ensure
+      // we update it as each pass runs and potentially invalidates analyses.
+      // We also update the preserved set of analyses based on what analyses we
+      // have already handled the invalidation for here and don't need to
+      // invalidate when finished.
+      if (AM)
+        PassPA = AM->invalidate(IR, std::move(PassPA));
 
-  std::vector<std::unique_ptr<ModulePassConcept>> Passes;
-};
+      // Finally, we intersect the final preserved analyses to compute the
+      // aggregate preserved set for this pass manager.
+      PA.intersect(std::move(PassPA));
 
-/// \brief Manages a sequence of passes over a Function of IR.
-///
-/// A function pass manager contains a sequence of function passes. It is also
-/// itself a function pass. When it is run over a function of LLVM IR, it will
-/// sequentially run each pass it contains over that function.
-///
-/// If it is run with a \c FunctionAnalysisManager argument, it will propagate
-/// that analysis manager to each pass it runs, as well as calling the analysis
-/// manager's invalidation routine with the PreservedAnalyses of each pass it
-/// runs.
-///
-/// Function passes can rely on having exclusive access to the function they
-/// are run over. They should not read or modify any other functions! Other
-/// threads or systems may be manipulating other functions in the module, and
-/// so their state should never be relied on.
-/// FIXME: Make the above true for all of LLVM's actual passes, some still
-/// violate this principle.
-///
-/// Function passes can also read the module containing the function, but they
-/// should not modify that module outside of the use lists of various globals.
-/// For example, a function pass is not permitted to add functions to the
-/// module.
-/// FIXME: Make the above true for all of LLVM's actual passes, some still
-/// violate this principle.
-class FunctionPassManager {
-public:
-  // We have to explicitly define all the special member functions because MSVC
-  // refuses to generate them.
-  FunctionPassManager() {}
-  FunctionPassManager(FunctionPassManager &&Arg)
-      : Passes(std::move(Arg.Passes)) {}
-  FunctionPassManager &operator=(FunctionPassManager &&RHS) {
-    Passes = std::move(RHS.Passes);
-    return *this;
-  }
+      // FIXME: Historically, the pass managers all called the LLVM context's
+      // yield function here. We don't have a generic way to acquire the
+      // context and it isn't yet clear what the right pattern is for yielding
+      // in the new pass manager so it is currently omitted.
+      //IR.getContext().yield();
+    }
+
+    if (DebugLogging)
+      dbgs() << "Finished pass manager run.\n";
 
-  template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
-    Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
+    return PA;
   }
 
-  PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM = nullptr);
+  template <typename PassT> void addPass(PassT Pass) {
+    typedef detail::PassModel<IRUnitT, PassT> PassModelT;
+    Passes.emplace_back(new PassModelT(std::move(Pass)));
+  }
 
-  static StringRef name() { return "FunctionPassManager"; }
+  static StringRef name() { return "PassManager"; }
 
 private:
-  // Pull in the concept type and model template specialized for functions.
-  typedef detail::PassConcept<Function, FunctionAnalysisManager>
-      FunctionPassConcept;
-  template <typename PassT>
-  struct FunctionPassModel
-      : detail::PassModel<Function, FunctionAnalysisManager, PassT> {
-    FunctionPassModel(PassT Pass)
-        : detail::PassModel<Function, FunctionAnalysisManager, PassT>(
-              std::move(Pass)) {}
-  };
+  typedef detail::PassConcept<IRUnitT> PassConceptT;
 
-  FunctionPassManager(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
-  FunctionPassManager &
-  operator=(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
+  PassManager(const PassManager &) = delete;
+  PassManager &operator=(const PassManager &) = delete;
 
-  std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
+  std::vector<std::unique_ptr<PassConceptT>> Passes;
+
+  /// \brief Flag indicating whether we should do debug logging.
+  bool DebugLogging;
 };
 
+/// \brief Convenience typedef for a pass manager over modules.
+typedef PassManager<Module> ModulePassManager;
+
+/// \brief Convenience typedef for a pass manager over functions.
+typedef PassManager<Function> FunctionPassManager;
+
 namespace detail {
 
 /// \brief A CRTP base used to implement analysis managers.
@@ -318,13 +283,13 @@ template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
     return static_cast<const DerivedT *>(this);
   }
 
-  AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+  AnalysisManagerBase(const AnalysisManagerBase &) = delete;
   AnalysisManagerBase &
-  operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+  operator=(const AnalysisManagerBase &) = delete;
 
 protected:
   typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
-  typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
+  typedef detail::AnalysisPassConcept<IRUnitT> PassConceptT;
 
   // FIXME: Provide template aliases for the models when we're using C++11 in
   // a mode supporting them.
@@ -383,7 +348,7 @@ public:
   template <typename PassT> void registerPass(PassT Pass) {
     assert(!AnalysisPasses.count(PassT::ID()) &&
            "Registered the same analysis pass twice!");
-    typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
+    typedef detail::AnalysisPassModel<IRUnitT, PassT> PassModelT;
     AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
   }
 
@@ -451,15 +416,22 @@ class AnalysisManager
 public:
   // Most public APIs are inherited from the CRTP base class.
 
+  /// \brief Construct an empty analysis manager.
+  ///
+  /// A flag can be passed to indicate that the manager should perform debug
+  /// logging.
+  AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
+
   // We have to explicitly define all the special member functions because MSVC
   // refuses to generate them.
-  AnalysisManager() {}
   AnalysisManager(AnalysisManager &&Arg)
       : BaseT(std::move(static_cast<BaseT &>(Arg))),
-        AnalysisResults(std::move(Arg.AnalysisResults)) {}
+        AnalysisResults(std::move(Arg.AnalysisResults)),
+        DebugLogging(std::move(Arg.DebugLogging)) {}
   AnalysisManager &operator=(AnalysisManager &&RHS) {
     BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
     AnalysisResults = std::move(RHS.AnalysisResults);
+    DebugLogging = std::move(RHS.DebugLogging);
     return *this;
   }
 
@@ -483,8 +455,8 @@ public:
   }
 
 private:
-  AnalysisManager(const AnalysisManager &) LLVM_DELETED_FUNCTION;
-  AnalysisManager &operator=(const AnalysisManager &) LLVM_DELETED_FUNCTION;
+  AnalysisManager(const AnalysisManager &) = delete;
+  AnalysisManager &operator=(const AnalysisManager &) = delete;
 
   /// \brief Get an analysis result, running the pass if necessary.
   ResultConceptT &getResultImpl(void *PassID, IRUnitT &IR) {
@@ -497,10 +469,16 @@ private:
     // run it to produce a result, which we then add to the cache.
     if (Inserted) {
       auto &P = this->lookupPass(PassID);
-      if (detail::DebugPM)
+      if (DebugLogging)
         dbgs() << "Running analysis: " << P.name() << "\n";
       AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
       ResultList.emplace_back(PassID, P.run(IR, this));
+
+      // P.run may have inserted elements into AnalysisResults and invalidated
+      // RI.
+      RI = AnalysisResults.find(std::make_pair(PassID, &IR));
+      assert(RI != AnalysisResults.end() && "we just inserted it!");
+
       RI->second = std::prev(ResultList.end());
     }
 
@@ -521,7 +499,7 @@ private:
     if (RI == AnalysisResults.end())
       return;
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
              << "\n";
     AnalysisResultLists[&IR].erase(RI->second);
@@ -532,9 +510,9 @@ private:
   PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) {
     // Short circuit for a common case of all analyses being preserved.
     if (PA.areAllPreserved())
-      return std::move(PA);
+      return PA;
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Invalidating all non-preserved analyses for: "
              << IR.getName() << "\n";
 
@@ -551,7 +529,7 @@ private:
       // necessary. The analysis pass can return false if no action on the part
       // of the analysis manager is required for this invalidation event.
       if (I->second->invalidate(IR, PA)) {
-        if (detail::DebugPM)
+        if (DebugLogging)
           dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
                  << "\n";
 
@@ -572,7 +550,7 @@ private:
     if (ResultsList.empty())
       AnalysisResultLists.erase(&IR);
 
-    return std::move(PA);
+    return PA;
   }
 
   /// \brief List of function analysis pass IDs and associated concept pointers.
@@ -601,8 +579,17 @@ private:
   /// \brief Map from an analysis ID and function to a particular cached
   /// analysis result.
   AnalysisResultMapT AnalysisResults;
+
+  /// \brief A flag indicating whether debug logging is enabled.
+  bool DebugLogging;
 };
 
+/// \brief Convenience typedef for the Module analysis manager.
+typedef AnalysisManager<Module> ModuleAnalysisManager;
+
+/// \brief Convenience typedef for the Function analysis manager.
+typedef AnalysisManager<Function> FunctionAnalysisManager;
+
 /// \brief A module analysis which acts as a proxy for a function analysis
 /// manager.
 ///
@@ -761,6 +748,20 @@ private:
 /// \c FunctionAnalysisManagerModuleProxy analysis prior to running the function
 /// pass over the module to enable a \c FunctionAnalysisManager to be used
 /// within this run safely.
+///
+/// Function passes run within this adaptor can rely on having exclusive access
+/// to the function they are run over. They should not read or modify any other
+/// functions! Other threads or systems may be manipulating other functions in
+/// the module, and so their state should never be relied on.
+/// FIXME: Make the above true for all of LLVM's actual passes, some still
+/// violate this principle.
+///
+/// Function passes can also read the module containing the function, but they
+/// should not modify that module outside of the use lists of various globals.
+/// For example, a function pass is not permitted to add functions to the
+/// module.
+/// FIXME: Make the above true for all of LLVM's actual passes, some still
+/// violate this principle.
 template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
 public:
   explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
@@ -789,8 +790,11 @@ public:
       FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
 
     PreservedAnalyses PA = PreservedAnalyses::all();
-    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
-      PreservedAnalyses PassPA = Pass.run(*I, FAM);
+    for (Function &F : M) {
+      if (F.isDeclaration())
+        continue;
+
+      PreservedAnalyses PassPA = Pass.run(F, 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
@@ -798,7 +802,7 @@ public:
       // update our preserved set to reflect that these have already been
       // handled.
       if (FAM)
-        PassPA = FAM->invalidate(*I, std::move(PassPA));
+        PassPA = FAM->invalidate(F, std::move(PassPA));
 
       // Then intersect the preserved set so that invalidation of module
       // analyses will eventually occur when the module pass completes.
@@ -824,7 +828,7 @@ private:
 template <typename FunctionPassT>
 ModuleToFunctionPassAdaptor<FunctionPassT>
 createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
-  return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
+  return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
 }
 
 /// \brief A template utility pass to force an analysis result to be available.
@@ -838,8 +842,8 @@ template <typename AnalysisT> struct RequireAnalysisPass {
   /// provided they satisfy the basic API requirements. When this pass is
   /// created, these methods can be instantiated to satisfy whatever the
   /// context requires.
-  template <typename IRUnitT, typename AnalysisManagerT>
-  PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
+  template <typename IRUnitT>
+  PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
     if (AM)
       (void)AM->template getResult<AnalysisT>(Arg);
 
@@ -861,8 +865,8 @@ template <typename AnalysisT> struct InvalidateAnalysisPass {
   /// provided they satisfy the basic API requirements. When this pass is
   /// created, these methods can be instantiated to satisfy whatever the
   /// context requires.
-  template <typename IRUnitT, typename AnalysisManagerT>
-  PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
+  template <typename IRUnitT>
+  PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
     if (AM)
       // We have to directly invalidate the analysis result as we can't
       // enumerate all other analyses and use the preserved set to control it.