PM: Print the IR unit's name in debug output. NFC
[oota-llvm.git] / include / llvm / IR / PassManager.h
index 70618c53ac5da056fd5bd75f855d909635a7225e..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,11 +163,8 @@ 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 units of IR.
 ///
@@ -188,12 +179,18 @@ typedef AnalysisManager<Function> FunctionAnalysisManager;
 /// runs.
 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.
-  PassManager() {}
-  PassManager(PassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
+  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;
   }
 
@@ -201,12 +198,13 @@ public:
   PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
     PreservedAnalyses PA = PreservedAnalyses::all();
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Starting pass manager run.\n";
 
     for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
-      if (detail::DebugPM)
-        dbgs() << "Running pass: " << Passes[Idx]->name() << "\n";
+      if (DebugLogging)
+        dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
+               << IR.getName() << "\n";
 
       PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
 
@@ -229,33 +227,29 @@ public:
       //IR.getContext().yield();
     }
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Finished pass manager run.\n";
 
     return PA;
   }
 
   template <typename PassT> void addPass(PassT Pass) {
-    Passes.emplace_back(new PassModel<PassT>(std::move(Pass)));
+    typedef detail::PassModel<IRUnitT, PassT> PassModelT;
+    Passes.emplace_back(new PassModelT(std::move(Pass)));
   }
 
   static StringRef name() { return "PassManager"; }
 
 private:
-  // Pull in the concept type and model template specialized for modules.
-  typedef detail::PassConcept<IRUnitT, AnalysisManager<IRUnitT>> PassConcept;
-  template <typename PassT>
-  struct PassModel
-      : detail::PassModel<IRUnitT, AnalysisManager<IRUnitT>, PassT> {
-    PassModel(PassT Pass)
-        : detail::PassModel<IRUnitT, AnalysisManager<IRUnitT>, PassT>(
-              std::move(Pass)) {}
-  };
+  typedef detail::PassConcept<IRUnitT> PassConceptT;
 
-  PassManager(const PassManager &) LLVM_DELETED_FUNCTION;
-  PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
+  PassManager(const PassManager &) = delete;
+  PassManager &operator=(const PassManager &) = delete;
 
-  std::vector<std::unique_ptr<PassConcept>> 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.
@@ -289,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.
@@ -354,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)));
   }
 
@@ -422,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;
   }
 
@@ -454,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) {
@@ -468,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());
     }
 
@@ -492,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);
@@ -503,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";
 
@@ -522,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";
 
@@ -543,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.
@@ -572,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.
 ///
@@ -774,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
@@ -783,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.
@@ -809,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.
@@ -823,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);
 
@@ -846,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.