[PM] Push the debug option for the new pass manager into the opt tool
authorChandler Carruth <chandlerc@gmail.com>
Tue, 13 Jan 2015 22:42:38 +0000 (22:42 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 13 Jan 2015 22:42:38 +0000 (22:42 +0000)
and expose the necessary hooks in the API directly.

This makes it much cleaner for example to log the usage of a pass
manager from a library. It also makes it more obvious that this
functionality isn't "optional" or "asserts-only" for the pass manager.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225841 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/PassManager.h
lib/IR/PassManager.cpp
tools/opt/NewPMDriver.cpp
tools/opt/Passes.cpp
tools/opt/Passes.h

index 0b2a0c4ab7b55611984eb8088b3b41bed51a0204..2625768492645a41ccdafd588af85e765be4bf8b 100644 (file)
@@ -56,13 +56,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.
 ///
@@ -185,12 +178,18 @@ template <typename IRUnitT> class AnalysisManager;
 /// 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;
   }
 
@@ -198,11 +197,11 @@ 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)
+      if (DebugLogging)
         dbgs() << "Running pass: " << Passes[Idx]->name() << "\n";
 
       PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
@@ -226,7 +225,7 @@ public:
       //IR.getContext().yield();
     }
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Finished pass manager run.\n";
 
     return PA;
@@ -246,6 +245,9 @@ private:
   PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
 
   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.
@@ -412,15 +414,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;
   }
 
@@ -458,7 +467,7 @@ 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));
@@ -482,7 +491,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);
@@ -495,7 +504,7 @@ private:
     if (PA.areAllPreserved())
       return std::move(PA);
 
-    if (detail::DebugPM)
+    if (DebugLogging)
       dbgs() << "Invalidating all non-preserved analyses for: "
              << IR.getName() << "\n";
 
@@ -512,7 +521,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";
 
@@ -562,6 +571,9 @@ 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.
index 3e6efb70260a484053910b9125acbf93631c566d..a5f407c00e8e1d530e55ffd82aabb1aacb74afb4 100644 (file)
 #include "llvm/IR/PassManager.h"
 
 using namespace llvm;
-using llvm::detail::DebugPM;
-
-cl::opt<bool> llvm::detail::DebugPM(
-    "debug-pass-manager", cl::Hidden,
-    cl::desc("Print pass management debugging information"));
 
 char FunctionAnalysisManagerModuleProxy::PassID;
 
index 9e24f30c1886020e95431b1ed8dcd859ab9fc7ee..d37211faf6d53fb9dfd71541d588119ab9f0b982 100644 (file)
 using namespace llvm;
 using namespace opt_tool;
 
+static cl::opt<bool>
+    DebugPM("debug-pass-manager", cl::Hidden,
+            cl::desc("Print pass management debugging information"));
+
 bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
                            tool_output_file *Out, StringRef PassPipeline,
                            OutputKind OK, VerifierKind VK) {
-  FunctionAnalysisManager FAM;
-  CGSCCAnalysisManager CGAM;
-  ModuleAnalysisManager MAM;
+  FunctionAnalysisManager FAM(DebugPM);
+  CGSCCAnalysisManager CGAM(DebugPM);
+  ModuleAnalysisManager MAM(DebugPM);
 
   // Register all the basic analyses with the managers.
   registerModuleAnalyses(MAM);
@@ -50,11 +54,11 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
   FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM));
   FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
 
-  ModulePassManager MPM;
+  ModulePassManager MPM(DebugPM);
   if (VK > VK_NoVerifier)
     MPM.addPass(VerifierPass());
 
-  if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
+  if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass, DebugPM)) {
     errs() << Arg0 << ": unable to parse pass pipeline description.\n";
     return false;
   }
index 69301256f89cfc6d22ab3aa4919b70bb1606d7cd..c81c5633684490ebf1c6812970598fe6a3998f78 100644 (file)
@@ -196,15 +196,16 @@ static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
 
 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
                                       StringRef &PipelineText,
-                                      bool VerifyEachPass) {
+                                      bool VerifyEachPass, bool DebugLogging) {
   for (;;) {
     // Parse nested pass managers by recursing.
     if (PipelineText.startswith("function(")) {
-      FunctionPassManager NestedFPM;
+      FunctionPassManager NestedFPM(DebugLogging);
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -232,16 +233,17 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
 }
 
 static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
-                                      StringRef &PipelineText,
-                                      bool VerifyEachPass) {
+                                   StringRef &PipelineText, bool VerifyEachPass,
+                                   bool DebugLogging) {
   for (;;) {
     // Parse nested pass managers by recursing.
     if (PipelineText.startswith("cgscc(")) {
-      CGSCCPassManager NestedCGPM;
+      CGSCCPassManager NestedCGPM(DebugLogging);
 
       // Parse the inner pipeline into the nested manager.
       PipelineText = PipelineText.substr(strlen("cgscc("));
-      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
+      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
+                                  DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -250,11 +252,12 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
       // Add the nested pass manager with the appropriate adaptor.
       CGPM.addPass(std::move(NestedCGPM));
     } else if (PipelineText.startswith("function(")) {
-      FunctionPassManager NestedFPM;
+      FunctionPassManager NestedFPM(DebugLogging);
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -282,15 +285,16 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
 
 static bool parseModulePassPipeline(ModulePassManager &MPM,
                                     StringRef &PipelineText,
-                                    bool VerifyEachPass) {
+                                    bool VerifyEachPass, bool DebugLogging) {
   for (;;) {
     // Parse nested pass managers by recursing.
     if (PipelineText.startswith("module(")) {
-      ModulePassManager NestedMPM;
+      ModulePassManager NestedMPM(DebugLogging);
 
       // Parse the inner pipeline into the nested manager.
       PipelineText = PipelineText.substr(strlen("module("));
-      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
+      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
+                                   DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -299,11 +303,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
       // Now add the nested manager as a module pass.
       MPM.addPass(std::move(NestedMPM));
     } else if (PipelineText.startswith("cgscc(")) {
-      CGSCCPassManager NestedCGPM;
+      CGSCCPassManager NestedCGPM(DebugLogging);
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("cgscc("));
-      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
+      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
+                                  DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -313,11 +318,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
       MPM.addPass(
           createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
     } else if (PipelineText.startswith("function(")) {
-      FunctionPassManager NestedFPM;
+      FunctionPassManager NestedFPM(DebugLogging);
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -348,11 +354,11 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
 // FIXME: Should this routine accept a TargetMachine or require the caller to
 // pre-populate the analysis managers with target-specific stuff?
 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
-                             bool VerifyEachPass) {
+                             bool VerifyEachPass, bool DebugLogging) {
   // By default, try to parse the pipeline as-if it were within an implicit
   // 'module(...)' pass pipeline. If this will parse at all, it needs to
   // consume the entire string.
-  if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass))
+  if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
     return PipelineText.empty();
 
   // This isn't parsable as a module pipeline, look for the end of a pass name
@@ -365,8 +371,9 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
   // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
   // pipeline.
   if (isCGSCCPassName(FirstName)) {
-    CGSCCPassManager CGPM;
-    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
+    CGSCCPassManager CGPM(DebugLogging);
+    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
+                                DebugLogging) ||
         !PipelineText.empty())
       return false;
     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
@@ -376,8 +383,9 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
   // Similarly, if this looks like a Function pass, parse the whole thing as
   // a Function pipelien.
   if (isFunctionPassName(FirstName)) {
-    FunctionPassManager FPM;
-    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
+    FunctionPassManager FPM(DebugLogging);
+    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
+                                   DebugLogging) ||
         !PipelineText.empty())
       return false;
     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
index f8273be1e9d4294147ae71db91137e6147a9042b..9e58e8b8ac36bdbc85793d6998d940ca6f0bece6 100644 (file)
@@ -72,8 +72,7 @@ void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
 /// an error. You cannot mix different levels implicitly, you must explicitly
 /// form a pass manager in which to nest passes.
 bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
-                       bool VerifyEachPass = true);
-
+                       bool VerifyEachPass = true, bool DebugLogging = false);
 }
 
 #endif