*** empty log message ***
[oota-llvm.git] / lib / VMCore / PassManagerT.h
index d4dfda02d66d9af91b9f44b2e833848093e2bcee..e61d994d9a339d61491e161c5c43045f04523b7e 100644 (file)
@@ -1,16 +1,19 @@
-//===- llvm/PassManager.h - Container for Passes -----------------*- C++ -*--=//
+//===- PassManagerT.h - Container for Passes ---------------------*- C++ -*--=//
 //
-// This file defines the PassManager class.  This class is used to hold,
+// This file defines the PassManagerT class.  This class is used to hold,
 // maintain, and optimize execution of Pass's.  The PassManager class ensures
 // that analysis results are available before a pass runs, and that Pass's are
 // destroyed when the PassManager is destroyed.
 //
-// The PassManagerT template is instantiated three times to do its job.
+// The PassManagerT template is instantiated three times to do its job.  The
+// public PassManager class is a Pimpl around the PassManagerT<Module> interface
+// to avoid having all of the PassManager clients being exposed to the
+// implementation details herein.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_PASSMANAGER_H
-#define LLVM_PASSMANAGER_H
+#ifndef LLVM_PASSMANAGER_T_H
+#define LLVM_PASSMANAGER_T_H
 
 #include "llvm/Pass.h"
 #include <string>
@@ -32,6 +35,28 @@ struct PMDebug {
 };
 
 
+//===----------------------------------------------------------------------===//
+// TimingInfo Class - This class is used to calculate information about the
+// amount of time each pass takes to execute.  This only happens when
+// -time-passes is enabled on the command line.
+//
+class TimingInfo {
+  std::map<Pass*, double> TimingData;
+  TimingInfo() {}   // Private ctor, must use create member
+public:
+  // Create method.  If Timing is enabled, this creates and returns a new timing
+  // object, otherwise it returns null.
+  //
+  static TimingInfo *create();
+
+  // TimingDtor - Print out information about timing information
+  ~TimingInfo();
+
+  void passStarted(Pass *P);
+  void passEnded(Pass *P);
+};
+
+
 
 //===----------------------------------------------------------------------===//
 // Declare the PassManagerTraits which will be specialized...
@@ -46,15 +71,15 @@ template<class UnitType> class PassManagerTraits;   // Do not define.
 //
 template<typename UnitType>
 class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{
-  typedef typename PassManagerTraits<UnitType>::PassClass       PassClass;
-  typedef typename PassManagerTraits<UnitType>::SubPassClass SubPassClass;
-  typedef typename PassManagerTraits<UnitType>::BatcherClass BatcherClass;
-  typedef typename PassManagerTraits<UnitType>::ParentClass   ParentClass;
-  typedef          PassManagerTraits<UnitType>                     Traits;
+  typedef PassManagerTraits<UnitType> Traits;
+  typedef typename Traits::PassClass       PassClass;
+  typedef typename Traits::SubPassClass SubPassClass;
+  typedef typename Traits::BatcherClass BatcherClass;
+  typedef typename Traits::ParentClass   ParentClass;
 
-  friend typename PassManagerTraits<UnitType>::PassClass;
-  friend typename PassManagerTraits<UnitType>::SubPassClass;  
-  friend class PassManagerTraits<UnitType>;
+  friend typename Traits::PassClass;
+  friend typename Traits::SubPassClass;  
+  friend class Traits;
 
   std::vector<PassClass*> Passes;    // List of pass's to run
 
@@ -125,7 +150,9 @@ public:
 #endif
 
       // Run the sub pass!
-      bool Changed = Traits::runPass(P, M);
+      startPass(P);
+      bool Changed = runPass(P, M);
+      endPass(P);
       MadeChanges |= Changed;
 
       if (Changed)
@@ -214,6 +241,20 @@ public:
     return I->second;
   }
 
+  // {start/end}Pass - Called when a pass is started, it just propogates
+  // information up to the top level PassManagerT object to tell it that a pass
+  // has started or ended.  This is used to gather timing information about
+  // passes.
+  //
+  void startPass(Pass *P) {
+    if (Parent) Parent->startPass(P);
+    else PassStarted(P);
+  }
+  void endPass(Pass *P) {
+    if (Parent) Parent->endPass(P);
+    else PassEnded(P);
+  }
+
   // markPassUsed - Inform higher level pass managers (and ourselves)
   // that these analyses are being used by this pass.  This is used to
   // make sure that analyses are not free'd before we have to use
@@ -386,14 +427,23 @@ template<> struct PassManagerTraits<BasicBlock> : public BasicBlockPass {
     return P->runOnBasicBlock(M);
   }
 
+  // Dummy implementation of PassStarted/PassEnded
+  static void PassStarted(Pass *P) {}
+  static void PassEnded(Pass *P) {}
+
   // getPMName() - Return the name of the unit the PassManager operates on for
   // debugging.
   const char *getPMName() const { return "BasicBlock"; }
+  virtual const char *getPassName() const { return "BasicBlock Pass Manager"; }
 
   // Implement the BasicBlockPass interface...
   virtual bool doInitialization(Module *M);
   virtual bool runOnBasicBlock(BasicBlock *BB);
   virtual bool doFinalization(Module *M);
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+  }
 };
 
 
@@ -425,14 +475,23 @@ template<> struct PassManagerTraits<Function> : public FunctionPass {
     return P->runOnFunction(F);
   }
 
+  // Dummy implementation of PassStarted/PassEnded
+  static void PassStarted(Pass *P) {}
+  static void PassEnded(Pass *P) {}
+
   // getPMName() - Return the name of the unit the PassManager operates on for
   // debugging.
   const char *getPMName() const { return "Function"; }
+  virtual const char *getPassName() const { return "Function Pass Manager"; }
 
   // Implement the FunctionPass interface...
   virtual bool doInitialization(Module *M);
   virtual bool runOnFunction(Function *F);
   virtual bool doFinalization(Module *M);
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.setPreservesAll();
+  }
 };
 
 
@@ -461,11 +520,39 @@ template<> struct PassManagerTraits<Module> : public Pass {
   // getPMName() - Return the name of the unit the PassManager operates on for
   // debugging.
   const char *getPMName() const { return "Module"; }
+  virtual const char *getPassName() const { return "Module Pass Manager"; }
+
+  // TimingInformation - This data member maintains timing information for each
+  // of the passes that is executed.
+  //
+  TimingInfo *TimeInfo;
 
-  // run - Implement the Pass interface...
-  virtual bool run(Module *M) {
-    return ((PassManagerT<Module>*)this)->runOnUnit(M);
+  // PassStarted/Ended - This callback is notified any time a pass is started
+  // or stops.  This is used to collect timing information about the different
+  // passes being executed.
+  //
+  void PassStarted(Pass *P) {
+    if (TimeInfo) TimeInfo->passStarted(P);
+  }
+  void PassEnded(Pass *P) {
+    if (TimeInfo) TimeInfo->passEnded(P);
   }
+
+  // run - Implement the PassManager interface...
+  bool run(Module *M) {
+    TimeInfo = TimingInfo::create();
+    bool Result = ((PassManagerT<Module>*)this)->runOnUnit(M);
+    if (TimeInfo) {
+      delete TimeInfo;
+      TimeInfo = 0;
+    }
+    return Result;
+  }
+
+  // PassManagerTraits constructor - Create a timing info object if the user
+  // specified timing info should be collected on the command line.
+  //
+  PassManagerTraits() : TimeInfo(0) {}
 };