[llvm-commits] [llvm] r100249 - in /llvm/trunk: include/llvm/Analysis/LoopPass.h include/llvm/Assembly/PrintModulePass.h include/llvm/CallGraphSCCPass.h include/llvm/CodeGen/MachineFunctionPass.h include/llvm/CodeGen/Passes.h include/llvm/Pass.h lib/Analysis/IPA/CallGraphSCCPass.cpp lib/Analysis/LoopPass.cpp lib/CodeGen/CMakeLists.txt lib/CodeGen/MachineFunction.cpp lib/CodeGen/MachineFunctionPass.cpp lib/CodeGen/MachineFunctionPrinterPass.cpp lib/VMCore/Pass.cpp lib/VMCore/PassManager.cpp lib/VMCore/PrintModulePass.cpp

David Greene greened at obbligato.org
Fri Apr 2 16:17:15 PDT 2010


Author: greened
Date: Fri Apr  2 18:17:14 2010
New Revision: 100249

URL: http://llvm.org/viewvc/llvm-project?rev=100249&view=rev
Log:

Ok, third time's the charm.  No changes from last time except the CMake
source addition.  Apparently the buildbots were wrong about failures.

---

Add some switches helpful for debugging:

-print-before=<Pass Name>

Dump IR before running pass <Pass Name>.

-print-before-all

Dump IR before running each pass.

-print-after-all

Dump IR after running each pass.

These are helpful when tracking down a miscompilation.  It is easy to
get IR dumps and do diffs on them, etc.

To make this work well, add a new getPrinterPass API to Pass so that
each kind of pass (ModulePass, FunctionPass, etc.) can create a Pass
suitable for dumping out the kind of object the Pass works on.

Added:
    llvm/trunk/lib/CodeGen/MachineFunctionPrinterPass.cpp
Modified:
    llvm/trunk/include/llvm/Analysis/LoopPass.h
    llvm/trunk/include/llvm/Assembly/PrintModulePass.h
    llvm/trunk/include/llvm/CallGraphSCCPass.h
    llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h
    llvm/trunk/include/llvm/CodeGen/Passes.h
    llvm/trunk/include/llvm/Pass.h
    llvm/trunk/lib/Analysis/IPA/CallGraphSCCPass.cpp
    llvm/trunk/lib/Analysis/LoopPass.cpp
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/CodeGen/MachineFunction.cpp
    llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp
    llvm/trunk/lib/VMCore/Pass.cpp
    llvm/trunk/lib/VMCore/PassManager.cpp
    llvm/trunk/lib/VMCore/PrintModulePass.cpp

Modified: llvm/trunk/include/llvm/Analysis/LoopPass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopPass.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopPass.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopPass.h Fri Apr  2 18:17:14 2010
@@ -31,6 +31,10 @@
   explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {}
   explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {}
 
+  /// getPrinterPass - Get a pass to print the function corresponding
+  /// to a Loop.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   // runOnLoop - This method should be implemented by the subclass to perform
   // whatever action is necessary for the specified Loop.
   virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;

Modified: llvm/trunk/include/llvm/Assembly/PrintModulePass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Assembly/PrintModulePass.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Assembly/PrintModulePass.h (original)
+++ llvm/trunk/include/llvm/Assembly/PrintModulePass.h Fri Apr  2 18:17:14 2010
@@ -27,7 +27,9 @@
   
   /// createPrintModulePass - Create and return a pass that writes the
   /// module to the specified raw_ostream.
-  ModulePass *createPrintModulePass(raw_ostream *OS, bool DeleteStream=false);
+  ModulePass *createPrintModulePass(raw_ostream *OS,
+                                    bool DeleteStream=false,
+                                    const std::string &Banner = "");
   
   /// createPrintFunctionPass - Create and return a pass that prints
   /// functions to the specified raw_ostream as they are processed.

Modified: llvm/trunk/include/llvm/CallGraphSCCPass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CallGraphSCCPass.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CallGraphSCCPass.h (original)
+++ llvm/trunk/include/llvm/CallGraphSCCPass.h Fri Apr  2 18:17:14 2010
@@ -35,6 +35,10 @@
   explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {}
   explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
 
+  /// createPrinterPass - Get a pass that prints the Module
+  /// corresponding to a CallGraph.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   /// doInitialization - This method is called before the SCC's of the program
   /// has been processed, allowing the pass to do initialization as necessary.
   virtual bool doInitialization(CallGraph &CG) {

Modified: llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFunctionPass.h Fri Apr  2 18:17:14 2010
@@ -34,6 +34,9 @@
   explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
   explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
 
+  /// createPrinterPass - Get a machine function printer pass.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   /// runOnMachineFunction - This method must be overloaded to perform the
   /// desired machine code transformation or analysis.
   ///

Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/Passes.h Fri Apr  2 18:17:14 2010
@@ -21,6 +21,7 @@
 namespace llvm {
 
   class FunctionPass;
+  class MachineFunctionPass;
   class PassInfo;
   class TargetLowering;
   class RegisterCoalescer;
@@ -36,8 +37,9 @@
 
   /// MachineFunctionPrinter pass - This pass prints out the machine function to
   /// the given stream, as a debugging tool.
-  FunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS,
-                                                 const std::string &Banner ="");
+  MachineFunctionPass *
+  createMachineFunctionPrinterPass(raw_ostream &OS,
+                                   const std::string &Banner ="");
 
   /// MachineLoopInfo pass - This pass is a loop analysis pass.
   /// 

Modified: llvm/trunk/include/llvm/Pass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Pass.h?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Pass.h (original)
+++ llvm/trunk/include/llvm/Pass.h Fri Apr  2 18:17:14 2010
@@ -30,7 +30,9 @@
 #define LLVM_PASS_H
 
 #include "llvm/System/DataTypes.h"
+
 #include <cassert>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -120,6 +122,11 @@
   virtual void print(raw_ostream &O, const Module *M) const;
   void dump() const; // dump - Print to stderr.
 
+  /// createPrinterPass - Get a Pass appropriate to print the IR this
+  /// pass operates one (Module, Function or MachineFunction).
+  virtual Pass *createPrinterPass(raw_ostream &O,
+                                  const std::string &Banner) const = 0;
+
   /// Each pass is responsible for assigning a pass manager to itself.
   /// PMS is the stack of available pass manager. 
   virtual void assignPassManager(PMStack &, 
@@ -233,6 +240,9 @@
 ///
 class ModulePass : public Pass {
 public:
+  /// createPrinterPass - Get a module printer pass.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   /// runOnModule - Virtual method overriden by subclasses to process the module
   /// being operated on.
   virtual bool runOnModule(Module &M) = 0;
@@ -293,6 +303,9 @@
   explicit FunctionPass(intptr_t pid) : Pass(PT_Function, pid) {}
   explicit FunctionPass(const void *pid) : Pass(PT_Function, pid) {}
 
+  /// createPrinterPass - Get a function printer pass.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   /// doInitialization - Virtual method overridden by subclasses to do
   /// any necessary per-module initialization.
   ///
@@ -343,6 +356,9 @@
   explicit BasicBlockPass(intptr_t pid) : Pass(PT_BasicBlock, pid) {}
   explicit BasicBlockPass(const void *pid) : Pass(PT_BasicBlock, pid) {}
 
+  /// createPrinterPass - Get a function printer pass.
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
   /// doInitialization - Virtual method overridden by subclasses to do
   /// any necessary per-module initialization.
   ///

Modified: llvm/trunk/lib/Analysis/IPA/CallGraphSCCPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/CallGraphSCCPass.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/IPA/CallGraphSCCPass.cpp (original)
+++ llvm/trunk/lib/Analysis/IPA/CallGraphSCCPass.cpp Fri Apr  2 18:17:14 2010
@@ -87,10 +87,40 @@
                         bool IsCheckingMode);
 };
 
+/// PrintCallGraphPass - Print a Module corresponding to a call graph.
+///
+class PrintCallGraphPass : public CallGraphSCCPass {
+private:
+  std::string Banner;
+  raw_ostream &Out;       // raw_ostream to print on.
+
+public:
+  static char ID;
+  PrintCallGraphPass() : CallGraphSCCPass(&ID), Out(dbgs()) {}
+  PrintCallGraphPass(const std::string &B, raw_ostream &o)
+      : CallGraphSCCPass(&ID), Banner(B), Out(o) {}
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+  }
+
+  bool runOnSCC(std::vector<CallGraphNode *> &SCC) {
+    Out << Banner;
+    for (std::vector<CallGraphNode *>::iterator n = SCC.begin(), ne = SCC.end();
+         n != ne;
+         ++n) {
+      (*n)->getFunction()->print(Out);
+    }
+    return false;
+  }
+};
+
 } // end anonymous namespace.
 
 char CGPassManager::ID = 0;
 
+char PrintCallGraphPass::ID = 0;
+
 bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC,
                                  CallGraph &CG, bool &CallGraphUpToDate) {
   bool Changed = false;
@@ -396,6 +426,11 @@
   return Changed;
 }
 
+Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &O,
+                                          const std::string &Banner) const {
+  return new PrintCallGraphPass(Banner, O);
+}
+
 /// Assign pass manager to manage this pass.
 void CallGraphSCCPass::assignPassManager(PMStack &PMS,
                                          PassManagerType PreferredType) {

Modified: llvm/trunk/lib/Analysis/LoopPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopPass.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopPass.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopPass.cpp Fri Apr  2 18:17:14 2010
@@ -14,9 +14,44 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/LoopPass.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/Timer.h"
 using namespace llvm;
 
+namespace {
+
+/// PrintLoopPass - Print a Function corresponding to a Loop.
+///
+class PrintLoopPass : public LoopPass {
+private:
+  std::string Banner;
+  raw_ostream &Out;       // raw_ostream to print on.
+
+public:
+  static char ID;
+  PrintLoopPass() : LoopPass(&ID), Out(dbgs()) {}
+  PrintLoopPass(const std::string &B, raw_ostream &o)
+      : LoopPass(&ID), Banner(B), Out(o) {}
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+  }
+
+  bool runOnLoop(Loop *L, LPPassManager &) {
+    Out << Banner;
+    for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
+         b != be;
+         ++b) {
+      (*b)->print(Out);
+    }
+    return false;
+  }
+};
+
+char PrintLoopPass::ID = 0;
+}
+
 //===----------------------------------------------------------------------===//
 // LPPassManager
 //
@@ -306,6 +341,11 @@
 //===----------------------------------------------------------------------===//
 // LoopPass
 
+Pass *LoopPass::createPrinterPass(raw_ostream &O,
+                                  const std::string &Banner) const {
+  return new PrintLoopPass(Banner, O);
+}
+
 // Check if this pass is suitable for the current LPPassManager, if
 // available. This pass P is not suitable for a LPPassManager if P
 // is not preserving higher level analysis info used by other

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Fri Apr  2 18:17:14 2010
@@ -27,6 +27,7 @@
   MachineFunction.cpp
   MachineFunctionAnalysis.cpp
   MachineFunctionPass.cpp
+  MachineFunctionPrinterPass.cpp
   MachineInstr.cpp
   MachineLICM.cpp
   MachineLoopInfo.cpp

Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Fri Apr  2 18:17:14 2010
@@ -39,40 +39,6 @@
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
-namespace {
-  struct Printer : public MachineFunctionPass {
-    static char ID;
-
-    raw_ostream &OS;
-    const std::string Banner;
-
-    Printer(raw_ostream &os, const std::string &banner) 
-      : MachineFunctionPass(&ID), OS(os), Banner(banner) {}
-
-    const char *getPassName() const { return "MachineFunction Printer"; }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.setPreservesAll();
-      MachineFunctionPass::getAnalysisUsage(AU);
-    }
-
-    bool runOnMachineFunction(MachineFunction &MF) {
-      OS << "# " << Banner << ":\n";
-      MF.print(OS);
-      return false;
-    }
-  };
-  char Printer::ID = 0;
-}
-
-/// Returns a newly-created MachineFunction Printer pass. The default banner is
-/// empty.
-///
-FunctionPass *llvm::createMachineFunctionPrinterPass(raw_ostream &OS,
-                                                     const std::string &Banner){
-  return new Printer(OS, Banner);
-}
-
 //===----------------------------------------------------------------------===//
 // MachineFunction implementation
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineFunctionPass.cpp Fri Apr  2 18:17:14 2010
@@ -15,8 +15,14 @@
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
 using namespace llvm;
 
+Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
+                                             const std::string &Banner) const {
+  return createMachineFunctionPrinterPass(O, Banner);
+}
+
 bool MachineFunctionPass::runOnFunction(Function &F) {
   // Do not codegen any 'available_externally' functions at all, they have
   // definitions outside the translation unit.

Added: llvm/trunk/lib/CodeGen/MachineFunctionPrinterPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunctionPrinterPass.cpp?rev=100249&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunctionPrinterPass.cpp (added)
+++ llvm/trunk/lib/CodeGen/MachineFunctionPrinterPass.cpp Fri Apr  2 18:17:14 2010
@@ -0,0 +1,60 @@
+//===-- MachineFunctionPrinterPass.cpp ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// MachineFunctionPrinterPass implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+/// MachineFunctionPrinterPass - This is a pass to dump the IR of a
+/// MachineFunction.
+///
+struct MachineFunctionPrinterPass : public MachineFunctionPass {
+  static char ID;
+
+  raw_ostream &OS;
+  const std::string Banner;
+
+  MachineFunctionPrinterPass(raw_ostream &os, const std::string &banner) 
+      : MachineFunctionPass(&ID), OS(os), Banner(banner) {}
+
+  const char *getPassName() const { return "MachineFunction Printer"; }
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) {
+    OS << "# " << Banner << ":\n";
+    MF.print(OS);
+    return false;
+  }
+};
+
+char MachineFunctionPrinterPass::ID = 0;
+}
+
+namespace llvm {
+/// Returns a newly-created MachineFunction Printer pass. The
+/// default banner is empty.
+///
+MachineFunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS,
+                                                      const std::string &Banner){
+  return new MachineFunctionPrinterPass(OS, Banner);
+}
+
+}

Modified: llvm/trunk/lib/VMCore/Pass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Pass.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Pass.cpp (original)
+++ llvm/trunk/lib/VMCore/Pass.cpp Fri Apr  2 18:17:14 2010
@@ -18,6 +18,7 @@
 #include "llvm/Module.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/PassNameParser.h"
@@ -42,6 +43,11 @@
 // Force out-of-line virtual method.
 ModulePass::~ModulePass() { }
 
+Pass *ModulePass::createPrinterPass(raw_ostream &O,
+                                    const std::string &Banner) const {
+  return createPrintModulePass(&O, false, Banner);
+}
+
 PassManagerType ModulePass::getPotentialPassManagerType() const {
   return PMT_ModulePassManager;
 }
@@ -113,6 +119,11 @@
 // FunctionPass Implementation
 //
 
+Pass *FunctionPass::createPrinterPass(raw_ostream &O,
+                                      const std::string &Banner) const {
+  return createPrintFunctionPass(Banner, &O);
+}
+
 // run - On a module, we run this pass by initializing, runOnFunction'ing once
 // for every function in the module, then by finalizing.
 //
@@ -155,6 +166,13 @@
 // BasicBlockPass Implementation
 //
 
+Pass *BasicBlockPass::createPrinterPass(raw_ostream &O,
+                                        const std::string &Banner) const {
+  
+  llvm_unreachable("BasicBlockPass printing unsupported.");
+  return 0;
+}
+
 // To run this pass on a function, we simply call runOnBasicBlock once for each
 // function.
 //

Modified: llvm/trunk/lib/VMCore/PassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassManager.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/PassManager.cpp (original)
+++ llvm/trunk/lib/VMCore/PassManager.cpp Fri Apr  2 18:17:14 2010
@@ -13,6 +13,7 @@
 
 
 #include "llvm/PassManagers.h"
+#include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -20,6 +21,7 @@
 #include "llvm/Module.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Mutex.h"
 #include "llvm/System/Threading.h"
@@ -55,6 +57,57 @@
   clEnumVal(Executions, "print pass name before it is executed"),
   clEnumVal(Details   , "print pass details when it is executed"),
                              clEnumValEnd));
+
+typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser>
+PassOptionList;
+
+// Print IR out before/after specified passes.
+static PassOptionList
+PrintBefore("print-before",
+            llvm::cl::desc("Print IR before specified passes"));
+
+static PassOptionList
+PrintAfter("print-after",
+           llvm::cl::desc("Print IR after specified passes"));
+
+static cl::opt<bool>
+PrintBeforeAll("print-before-all",
+               llvm::cl::desc("Print IR before each pass"),
+               cl::init(false));
+static cl::opt<bool>
+PrintAfterAll("print-after-all",
+              llvm::cl::desc("Print IR after each pass"),
+              cl::init(false));
+
+/// This is a helper to determine whether to print IR before or
+/// after a pass.
+
+static bool ShouldPrintBeforeOrAfterPass(Pass *P,
+                                         PassOptionList &PassesToPrint) {
+  for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
+    const llvm::PassInfo *PassInf = PassesToPrint[i];
+    if (PassInf && P->getPassInfo())
+      if (PassInf->getPassArgument() ==
+          P->getPassInfo()->getPassArgument()) {
+        return true;
+      }
+  }
+  return false;
+}
+  
+
+/// This is a utility to check whether a pass should have IR dumped
+/// before it.
+static bool ShouldPrintBeforePass(Pass *P) {
+  return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(P, PrintBefore);
+}
+
+/// This is a utility to check whether a pass should have IR dumped
+/// after it.
+static bool ShouldPrintAfterPass(Pass *P) {
+  return PrintAfterAll || ShouldPrintBeforeOrAfterPass(P, PrintAfter);
+}
+
 } // End of llvm namespace
 
 /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
@@ -182,6 +235,11 @@
     schedulePass(P);
   }
  
+  /// createPrinterPass - Get a function printer pass. 
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+    return createPrintFunctionPass(Banner, &O);
+  }
+
   // Prepare for running an on the fly pass, freeing memory if needed
   // from a previous run.
   void releaseMemoryOnTheFly();
@@ -252,6 +310,11 @@
     }
   }
 
+  /// createPrinterPass - Get a module printer pass. 
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+    return createPrintModulePass(&O, false, Banner);
+  }
+
   /// run - Execute all of the passes scheduled for execution.  Keep track of
   /// whether any of the passes modifies the module, and if so, return true.
   bool runOnModule(Module &M);
@@ -331,6 +394,11 @@
     schedulePass(P);
   }
  
+  /// createPrinterPass - Get a module printer pass. 
+  Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+    return createPrintModulePass(&O, false, Banner);
+  }
+
   /// run - Execute all of the passes scheduled for execution.  Keep track of
   /// whether any of the passes modifies the module, and if so, return true.
   bool run(Module &M);
@@ -1208,7 +1276,14 @@
 /// there is no need to delete the pass. (TODO delete passes.)
 /// This implies that all passes MUST be allocated with 'new'.
 void FunctionPassManager::add(Pass *P) { 
+  if (ShouldPrintBeforePass(P))
+    add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+                             + P->getPassName() + " ***"));
   FPM->add(P);
+
+  if (ShouldPrintAfterPass(P))
+    add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+                             + P->getPassName() + " ***"));
 }
 
 /// run - Execute all of the passes scheduled for execution.  Keep
@@ -1519,7 +1594,15 @@
 /// will be destroyed as well, so there is no need to delete the pass.  This
 /// implies that all passes MUST be allocated with 'new'.
 void PassManager::add(Pass *P) {
+  if (ShouldPrintBeforePass(P))
+    add(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+                             + P->getPassName() + " ***"));
+
   PM->add(P);
+
+  if (ShouldPrintAfterPass(P))
+    add(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+                             + P->getPassName() + " ***"));
 }
 
 /// run - Execute all of the passes scheduled for execution.  Keep track of

Modified: llvm/trunk/lib/VMCore/PrintModulePass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PrintModulePass.cpp?rev=100249&r1=100248&r2=100249&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/PrintModulePass.cpp (original)
+++ llvm/trunk/lib/VMCore/PrintModulePass.cpp Fri Apr  2 18:17:14 2010
@@ -23,21 +23,22 @@
 namespace {
 
   class PrintModulePass : public ModulePass {
+    std::string Banner;
     raw_ostream *Out;       // raw_ostream to print on
     bool DeleteStream;      // Delete the ostream in our dtor?
   public:
     static char ID;
     PrintModulePass() : ModulePass(&ID), Out(&dbgs()), 
       DeleteStream(false) {}
-    PrintModulePass(raw_ostream *o, bool DS)
-      : ModulePass(&ID), Out(o), DeleteStream(DS) {}
+    PrintModulePass(const std::string &B, raw_ostream *o, bool DS)
+        : ModulePass(&ID), Banner(B), Out(o), DeleteStream(DS) {}
     
     ~PrintModulePass() {
       if (DeleteStream) delete Out;
     }
     
     bool runOnModule(Module &M) {
-      (*Out) << M;
+      (*Out) << Banner << M;
       return false;
     }
     
@@ -85,8 +86,9 @@
 /// createPrintModulePass - Create and return a pass that writes the
 /// module to the specified raw_ostream.
 ModulePass *llvm::createPrintModulePass(llvm::raw_ostream *OS, 
-                                        bool DeleteStream) {
-  return new PrintModulePass(OS, DeleteStream);
+                                        bool DeleteStream,
+                                        const std::string &Banner) {
+  return new PrintModulePass(Banner, OS, DeleteStream);
 }
 
 /// createPrintFunctionPass - Create and return a pass that prints





More information about the llvm-commits mailing list