Patch #10 from Saem:
[oota-llvm.git] / lib / VMCore / PassManagerT.h
index 157f806651a392af8fbb92df59808dc9c0f6c64d..de0fc46f7e40496ba6f58b9e7fd080ea8e334dcd 100644 (file)
@@ -1,10 +1,10 @@
 //===- PassManagerT.h - Container for Passes --------------------*- C++ -*-===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file defines the PassManagerT class.  This class is used to hold,
 #define LLVM_PASSMANAGER_T_H
 
 #include "llvm/Pass.h"
-#include "Support/CommandLine.h"
-#include "Support/LeakDetector.h"
-#include "Support/Timer.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/LeakDetector.h"
+#include "llvm/Support/Timer.h"
 #include <algorithm>
 #include <iostream>
-class Annotable;
+
+namespace llvm {
 
 //===----------------------------------------------------------------------===//
 // Pass debugging information.  Often it is useful to find out what pass is
@@ -51,7 +52,7 @@ PassDebugging("debug-pass", cl::Hidden,
   clEnumVal(Structure , "print pass structure before run()"),
   clEnumVal(Executions, "print pass name before it is executed"),
   clEnumVal(Details   , "print pass details when it is executed"),
-                         0));
+                         clEnumValEnd));
 
 //===----------------------------------------------------------------------===//
 // PMDebug class - a set of debugging functions, that are not to be
@@ -72,7 +73,9 @@ struct PMDebug {
   }
 
   static void PrintArgumentInformation(const Pass *P);
-  static void PrintPassInformation(unsigned,const char*,Pass *, Annotable *);
+  static void PrintPassInformation(unsigned,const char*,Pass *, Module *);
+  static void PrintPassInformation(unsigned,const char*,Pass *, Function *);
+  static void PrintPassInformation(unsigned,const char*,Pass *, BasicBlock *);
   static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P,
                                    const std::vector<AnalysisID> &);
 };
@@ -120,31 +123,95 @@ public:
 
 static TimingInfo *TheTimeInfo;
 
-//===----------------------------------------------------------------------===//
-// Declare the PassManagerTraits which will be specialized...
-//
-template<class UnitType> class PassManagerTraits;   // Do not define.
+struct BBTraits {
+  typedef BasicBlock UnitType;
+  
+  // PassClass - The type of passes tracked by this PassManager
+  typedef BasicBlockPass PassClass;
+
+  // SubPassClass - The types of classes that should be collated together
+  // This is impossible to match, so BasicBlock instantiations of PassManagerT
+  // do not collate.
+  //
+  typedef BasicBlockPassManager SubPassClass;
+
+  // BatcherClass - The type to use for collation of subtypes... This class is
+  // never instantiated for the BasicBlockPassManager, but it must be an
+  // instance of PassClass to typecheck.
+  //
+  typedef PassClass BatcherClass;
+
+  // ParentClass - The type of the parent PassManager...
+  typedef FunctionPassManagerT ParentClass;
+
+  // PMType - The type of this passmanager
+  typedef BasicBlockPassManager PMType;
+};
+
+struct FTraits {
+  typedef Function UnitType;
+  
+  // PassClass - The type of passes tracked by this PassManager
+  typedef FunctionPass PassClass;
+
+  // SubPassClass - The types of classes that should be collated together
+  typedef BasicBlockPass SubPassClass;
+
+  // BatcherClass - The type to use for collation of subtypes...
+  typedef BasicBlockPassManager BatcherClass;
+
+  // ParentClass - The type of the parent PassManager...
+  typedef ModulePassManager ParentClass;
+
+  // PMType - The type of this passmanager
+  typedef FunctionPassManagerT PMType;
+};
+
+struct MTraits {
+  typedef Module UnitType;
+  
+  // PassClass - The type of passes tracked by this PassManager
+  typedef ModulePass PassClass;
+
+  // SubPassClass - The types of classes that should be collated together
+  typedef FunctionPass SubPassClass;
+
+  // BatcherClass - The type to use for collation of subtypes...
+  typedef FunctionPassManagerT BatcherClass;
+
+  // ParentClass - The type of the parent PassManager...
+  typedef AnalysisResolver ParentClass;
+  
+  // PMType - The type of this passmanager
+  typedef ModulePassManager PMType;
+};
 
 
 //===----------------------------------------------------------------------===//
 // PassManagerT - Container object for passes.  The PassManagerT destructor
-// deletes all passes contained inside of the PassManagerT, so you shouldn't 
+// deletes all passes contained inside of the PassManagerT, so you shouldn't
 // delete passes manually, and all passes should be dynamically allocated.
 //
-template<typename UnitType>
-class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{
-  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 class PassManagerTraits<UnitType>::PassClass;
-  friend class PassManagerTraits<UnitType>::SubPassClass;  
-  friend class Traits;
+template<typename Trait> class PassManagerT : public AnalysisResolver {
+  
+  typedef typename Trait::PassClass    PassClass;
+  typedef typename Trait::UnitType     UnitType;
+  typedef typename Trait::ParentClass  ParentClass;
+  typedef typename Trait::SubPassClass SubPassClass;
+  typedef typename Trait::BatcherClass BatcherClass;
+  typedef typename Trait::PMType       PMType;
+  
+  friend class ModulePass;
+  friend class FunctionPass;
+  friend class BasicBlockPass;
+  
   friend class ImmutablePass;
+  
+  friend class BasicBlockPassManager;
+  friend class FunctionPassManagerT;
+  friend class ModulePassManager;
 
-  std::vector<PassClass*> Passes;    // List of passes to run
+  std::vector<PassClass*> Passes;               // List of passes to run
   std::vector<ImmutablePass*> ImmutablePasses;  // List of immutable passes
 
   // The parent of this pass manager...
@@ -166,8 +233,20 @@ class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{
   std::map<Pass*, Pass*> LastUseOf;
 
 public:
+  
+  // getPMName() - Return the name of the unit the PassManager operates on for
+  // debugging.
+  virtual const char *getPMName() const =0;
+  
+  virtual const char *getPassName() const =0;
+
+  virtual bool runPass(PassClass *P, UnitType *M) =0;
+  
+  // TODO:Figure out what pure virtuals remain.
+  
+  
   PassManagerT(ParentClass *Par = 0) : Parent(Par), Batcher(0) {}
-  ~PassManagerT() {
+  virtual ~PassManagerT() {
     // Delete all of the contained passes...
     for (typename std::vector<PassClass*>::iterator
            I = Passes.begin(), E = Passes.end(); I != E; ++I)
@@ -181,23 +260,12 @@ public:
   // run - Run all of the queued passes on the specified module in an optimal
   // way.
   virtual bool runOnUnit(UnitType *M) {
-    bool MadeChanges = false;
     closeBatcher();
     CurrentAnalyses.clear();
 
     TimingInfo::createTheTimeInfo();
 
-    // Add any immutable passes to the CurrentAnalyses set...
-    for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
-      ImmutablePass *IPass = ImmutablePasses[i];
-      if (const PassInfo *PI = IPass->getPassInfo()) {
-        CurrentAnalyses[PI] = IPass;
-
-        const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
-        for (unsigned i = 0, e = II.size(); i != e; ++i)
-          CurrentAnalyses[II[i]] = IPass;
-      }
-    }
+    addImmutablePasses();
 
     // LastUserOf - This contains the inverted LastUseOfMap...
     std::map<Pass *, std::vector<Pass*> > LastUserOf;
@@ -205,128 +273,23 @@ public:
                                           E = LastUseOf.end(); I != E; ++I)
       LastUserOf[I->second].push_back(I->first);
 
-
     // Output debug information...
-    if (Parent == 0) PMDebug::PerformPassStartupStuff(this);
+    assert(dynamic_cast<PassClass*>(this) && 
+           "It wasn't the PassClass I thought it was");
+    if (Parent == 0) 
+      PMDebug::PerformPassStartupStuff((dynamic_cast<PMType*>(this)));
 
-    // Run all of the passes
-    for (unsigned i = 0, e = Passes.size(); i < e; ++i) {
-      PassClass *P = Passes[i];
-      
-      PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P,
-                                    (Annotable*)M);
-
-      // Get information about what analyses the pass uses...
-      AnalysisUsage AnUsage;
-      P->getAnalysisUsage(AnUsage);
-      PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P,
-                                    AnUsage.getRequiredSet());
-
-      // All Required analyses should be available to the pass as it runs!  Here
-      // we fill in the AnalysisImpls member of the pass so that it can
-      // successfully use the getAnalysis() method to retrieve the
-      // implementations it needs.
-      //
-      P->AnalysisImpls.clear();
-      P->AnalysisImpls.reserve(AnUsage.getRequiredSet().size());
-      for (std::vector<const PassInfo *>::const_iterator
-             I = AnUsage.getRequiredSet().begin(), 
-             E = AnUsage.getRequiredSet().end(); I != E; ++I) {
-        Pass *Impl = getAnalysisOrNullUp(*I);
-        if (Impl == 0) {
-          std::cerr << "Analysis '" << (*I)->getPassName()
-                    << "' used but not available!";
-          assert(0 && "Analysis used but not available!");
-        } else if (PassDebugging == Details) {
-          if ((*I)->getPassName() != std::string(Impl->getPassName()))
-            std::cerr << "    Interface '" << (*I)->getPassName()
-                    << "' implemented by '" << Impl->getPassName() << "'\n";
-        }
-        P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
-      }
-
-      // Run the sub pass!
-      if (TheTimeInfo) TheTimeInfo->passStarted(P);
-      bool Changed = runPass(P, M);
-      if (TheTimeInfo) TheTimeInfo->passEnded(P);
-      MadeChanges |= Changed;
-
-      // Check for memory leaks by the pass...
-      LeakDetector::checkForGarbage(std::string("after running pass '") +
-                                    P->getPassName() + "'");
-
-      if (Changed)
-        PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P,
-                                      (Annotable*)M);
-      PMDebug::PrintAnalysisSetInfo(getDepth(), "Preserved", P,
-                                    AnUsage.getPreservedSet());
-
-
-      // Erase all analyses not in the preserved set...
-      if (!AnUsage.getPreservesAll()) {
-        const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
-        for (std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.begin(),
-               E = CurrentAnalyses.end(); I != E; )
-          if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) !=
-              PreservedSet.end())
-            ++I; // This analysis is preserved, leave it in the available set...
-          else {
-            if (!dynamic_cast<ImmutablePass*>(I->second)) {
-              std::map<AnalysisID, Pass*>::iterator J = I++;
-              CurrentAnalyses.erase(J);   // Analysis not preserved!
-            } else {
-              ++I;
-            }
-          }
-      }
-
-      // Add the current pass to the set of passes that have been run, and are
-      // thus available to users.
-      //
-      if (const PassInfo *PI = P->getPassInfo()) {
-        CurrentAnalyses[PI] = P;
-
-        // This pass is the current implementation of all of the interfaces it
-        // implements as well.
-        //
-        const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
-        for (unsigned i = 0, e = II.size(); i != e; ++i)
-          CurrentAnalyses[II[i]] = P;
-      }
-
-      // Free memory for any passes that we are the last use of...
-      std::vector<Pass*> &DeadPass = LastUserOf[P];
-      for (std::vector<Pass*>::iterator I = DeadPass.begin(),E = DeadPass.end();
-           I != E; ++I) {
-        PMDebug::PrintPassInformation(getDepth()+1, "Freeing Pass", *I,
-                                      (Annotable*)M);
-        (*I)->releaseMemory();
-      }
-
-      // Make sure to remove dead passes from the CurrentAnalyses list...
-      for (std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.begin();
-           I != CurrentAnalyses.end(); ) {
-        std::vector<Pass*>::iterator DPI = std::find(DeadPass.begin(),
-                                                     DeadPass.end(), I->second);
-        if (DPI != DeadPass.end()) {    // This pass is dead now... remove it
-          std::map<AnalysisID, Pass*>::iterator IDead = I++;
-          CurrentAnalyses.erase(IDead);
-        } else {
-          ++I;  // Move on to the next element...
-        }
-      }
-    }
-
-    return MadeChanges;
+    return runPasses(M, LastUserOf);
   }
 
   // dumpPassStructure - Implement the -debug-passes=PassStructure option
-  virtual void dumpPassStructure(unsigned Offset = 0) {
+  inline void dumpPassStructure(unsigned Offset = 0) {
     // Print out the immutable passes...
+    
     for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i)
       ImmutablePasses[i]->dumpPassStructure(0);
 
-    std::cerr << std::string(Offset*2, ' ') << Traits::getPMName()
+    std::cerr << std::string(Offset*2, ' ') << this->getPMName()
               << " Pass Manager\n";
     for (typename std::vector<PassClass*>::iterator
            I = Passes.begin(), E = Passes.end(); I != E; ++I) {
@@ -349,7 +312,7 @@ public:
       const PassInfo *IPID = ImmutablePasses[i]->getPassInfo();
       if (IPID == ID)
         return ImmutablePasses[i];
-      
+
       // This pass is the current implementation of all of the interfaces it
       // implements as well.
       //
@@ -397,6 +360,16 @@ public:
 
     if (I != CurrentAnalyses.end()) {
       LastUseOf[I->second] = User;    // Local pass, extend the lifetime
+
+      // Prolong live range of analyses that are needed after an analysis pass
+      // is destroyed, for querying by subsequent passes
+      AnalysisUsage AnUsage;
+      I->second->getAnalysisUsage(AnUsage);
+      const std::vector<AnalysisID> &IDs = AnUsage.getRequiredTransitiveSet();
+      for (std::vector<AnalysisID>::const_iterator i = IDs.begin(),
+             e = IDs.end(); i != e; ++i)
+        markPassUsed(*i, User);
+
     } else {
       // Pass not in current available set, must be a higher level pass
       // available to us, propagate to parent pass manager...  We tell the
@@ -404,16 +377,18 @@ public:
       // frees the analysis AFTER this pass manager runs.
       //
       if (Parent) {
-        Parent->markPassUsed(P, this);
+        assert(dynamic_cast<Pass*>(this) && 
+               "It wasn't the Pass type I thought it was.");
+        Parent->markPassUsed(P, dynamic_cast<Pass*>(this));
       } else {
-        assert(getAnalysisOrNullUp(P) && 
+        assert(getAnalysisOrNullUp(P) &&
                dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) &&
                "Pass available but not found! "
                "Perhaps this is a module pass requiring a function pass?");
       }
     }
   }
-  
+
   // Return the number of parent PassManagers that exist
   virtual unsigned getDepth() const {
     if (Parent == 0) return 0;
@@ -421,6 +396,7 @@ public:
   }
 
   virtual unsigned getNumContainedPasses() const { return Passes.size(); }
+  
   virtual const Pass *getContainedPass(unsigned N) const {
     assert(N < Passes.size() && "Pass number out of range!");
     return Passes[N];
@@ -435,20 +411,16 @@ public:
     // Get information about what analyses the pass uses...
     AnalysisUsage AnUsage;
     P->getAnalysisUsage(AnUsage);
-    const std::vector<AnalysisID> &Required = AnUsage.getRequiredSet();
-
-    // Loop over all of the analyses used by this pass,
-    for (std::vector<AnalysisID>::const_iterator I = Required.begin(),
-           E = Required.end(); I != E; ++I) {
-      if (getAnalysisOrNullDown(*I) == 0)
-        add((PassClass*)(*I)->createPass());
-    }
-
+    
+    addRequiredPasses(AnUsage.getRequiredSet());
+    
     // Tell the pass to add itself to this PassManager... the way it does so
     // depends on the class of the pass, and is critical to laying out passes in
     // an optimal order..
     //
-    P->addToPassManager(this, AnUsage);
+    assert(dynamic_cast<PMType*>(this) && 
+        "It wasn't the right passmanager type.");
+    P->addToPassManager(static_cast<PMType*>(this), AnUsage);
   }
 
   // add - H4x0r an ImmutablePass into a PassManager that might not be
@@ -458,15 +430,9 @@ public:
     // Get information about what analyses the pass uses...
     AnalysisUsage AnUsage;
     P->getAnalysisUsage(AnUsage);
-    const std::vector<AnalysisID> &Required = AnUsage.getRequiredSet();
-
-    // Loop over all of the analyses used by this pass,
-    for (std::vector<AnalysisID>::const_iterator I = Required.begin(),
-           E = Required.end(); I != E; ++I) {
-      if (getAnalysisOrNullDown(*I) == 0)
-        add((PassClass*)(*I)->createPass());
-    }
-
+    
+    addRequiredPasses(AnUsage.getRequiredSet());
+    
     // Add the ImmutablePass to this PassManager.
     addPass(P, AnUsage);
   }
@@ -486,14 +452,13 @@ private:
     const std::vector<AnalysisID> &RequiredSet = AnUsage.getRequiredSet();
 
     // FIXME: If this pass being added isn't killed by any of the passes in the
-    // batcher class then we can reorder to pass to execute before the batcher
+    // batcher class then we can reorder the pass to execute before the batcher
     // does, which will potentially allow us to batch more passes!
     //
-    //const std::vector<AnalysisID> &ProvidedSet = AnUsage.getProvidedSet();
-    if (Batcher /*&& ProvidedSet.empty()*/)
+    if (Batcher)
       closeBatcher();                     // This pass cannot be batched!
-    
-    // Set the Resolver instance variable in the Pass so that it knows where to 
+
+    // Set the Resolver instance variable in the Pass so that it knows where to
     // find this object...
     //
     setAnalysisResolver(P, this);
@@ -507,33 +472,10 @@ private:
            E = RequiredSet.end(); I != E; ++I)
       markPassUsed(*I, P);     // Mark *I as used by P
 
-    // Erase all analyses not in the preserved set...
-    if (!AnUsage.getPreservesAll()) {
-      const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
-      for (std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.begin(),
-             E = CurrentAnalyses.end(); I != E; ) {
-        if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) ==
-            PreservedSet.end()) {             // Analysis not preserved!
-          CurrentAnalyses.erase(I);           // Remove from available analyses
-          I = CurrentAnalyses.begin();
-        } else {
-          ++I;
-        }
-      }
-    }
-
-    // Add this pass to the currently available set...
-    if (const PassInfo *PI = P->getPassInfo()) {
-      CurrentAnalyses[PI] = P;
-
-      // This pass is the current implementation of all of the interfaces it
-      // implements as well.
-      //
-      const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
-      for (unsigned i = 0, e = II.size(); i != e; ++i)
-        CurrentAnalyses[II[i]] = P;
-    }
-
+    removeNonPreservedAnalyses(AnUsage);
+    
+    makeCurrentlyAvailable(P);
+    
     // For now assume that our results are never used...
     LastUseOf[P] = P;
   }
@@ -543,8 +485,13 @@ private:
   // together a function at a time.
   //
   void addPass(SubPassClass *MP, AnalysisUsage &AnUsage) {
-    if (Batcher == 0) // If we don't have a batcher yet, make one now.
-      Batcher = new BatcherClass(this);
+
+    if (Batcher == 0) { // If we don't have a batcher yet, make one now.
+      assert(dynamic_cast<PMType*>(this) && 
+             "It wasn't the PassManager type I thought it was");
+      Batcher = new BatcherClass((static_cast<PMType*>(this)));
+    }
+
     // The Batcher will queue the passes up
     MP->addToPassManager(Batcher, AnUsage);
   }
@@ -557,6 +504,18 @@ private:
     }
   }
 
+  void addRequiredPasses(const std::vector<AnalysisID> &Required) {
+    for (std::vector<AnalysisID>::const_iterator I = Required.begin(),
+         E = Required.end(); I != E; ++I) {
+      if (getAnalysisOrNullDown(*I) == 0) {
+        Pass *AP = (*I)->createPass();
+        if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (AP)) add(IP);
+        else if (PassClass *RP = dynamic_cast<PassClass *> (AP)) add(RP);
+        else assert (0 && "Wrong kind of pass for this PassManager");
+      }
+    }
+  }
+
 public:
   // When an ImmutablePass is added, it gets added to the top level pass
   // manager.
@@ -566,7 +525,7 @@ public:
       return;
     }
 
-    // Set the Resolver instance variable in the Pass so that it knows where to 
+    // Set the Resolver instance variable in the Pass so that it knows where to
     // find this object...
     //
     setAnalysisResolver(IP, this);
@@ -579,7 +538,7 @@ public:
     //
     IP->AnalysisImpls.clear();
     IP->AnalysisImpls.reserve(AU.getRequiredSet().size());
-    for (std::vector<const PassInfo *>::const_iterator 
+    for (std::vector<const PassInfo *>::const_iterator
            I = AU.getRequiredSet().begin(),
            E = AU.getRequiredSet().end(); I != E; ++I) {
       Pass *Impl = getAnalysisOrNullUp(*I);
@@ -594,202 +553,358 @@ public:
       }
       IP->AnalysisImpls.push_back(std::make_pair(*I, Impl));
     }
-    
+
     // Initialize the immutable pass...
     IP->initializePass();
   }
-};
+private:
+  
+  // Add any immutable passes to the CurrentAnalyses set...
+  inline void addImmutablePasses() { 
+    for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
+      ImmutablePass *IPass = ImmutablePasses[i];
+      if (const PassInfo *PI = IPass->getPassInfo()) {
+        CurrentAnalyses[PI] = IPass;
+
+        const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+        for (unsigned i = 0, e = II.size(); i != e; ++i)
+          CurrentAnalyses[II[i]] = IPass;
+      }
+    }
+  }
+  
+  // Run all of the passes
+  inline bool runPasses(UnitType *M, 
+                 std::map<Pass *, std::vector<Pass*> > &LastUserOf) { 
+    bool MadeChanges = false;
+    
+    for (unsigned i = 0, e = Passes.size(); i < e; ++i) {
+      PassClass *P = Passes[i];
 
+      PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, M);
 
+      // Get information about what analyses the pass uses...
+      AnalysisUsage AnUsage;
+      P->getAnalysisUsage(AnUsage);
+      PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P,
+                                    AnUsage.getRequiredSet());
+      
+      initialiseAnalysisImpl(P, AnUsage);
+      
+      // Run the sub pass!
+      if (TheTimeInfo) TheTimeInfo->passStarted(P);
+      bool Changed = runPass(P, M);
+      if (TheTimeInfo) TheTimeInfo->passEnded(P);
+      MadeChanges |= Changed;
 
-//===----------------------------------------------------------------------===//
-// PassManagerTraits<BasicBlock> Specialization
-//
-// This pass manager is used to group together all of the BasicBlockPass's
-// into a single unit.
-//
-template<> struct PassManagerTraits<BasicBlock> : public BasicBlockPass {
-  // PassClass - The type of passes tracked by this PassManager
-  typedef BasicBlockPass PassClass;
+      // Check for memory leaks by the pass...
+      LeakDetector::checkForGarbage(std::string("after running pass '") +
+                                    P->getPassName() + "'");
 
-  // SubPassClass - The types of classes that should be collated together
-  // This is impossible to match, so BasicBlock instantiations of PassManagerT
-  // do not collate.
+      if (Changed)
+        PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P, M);
+      PMDebug::PrintAnalysisSetInfo(getDepth(), "Preserved", P,
+                                    AnUsage.getPreservedSet());
+      
+      // Erase all analyses not in the preserved set
+      removeNonPreservedAnalyses(AnUsage);
+      
+      makeCurrentlyAvailable(P);
+      
+      // free memory and remove dead passes from the CurrentAnalyses list...
+      removeDeadPasses(P, M, LastUserOf);
+    }
+    
+    return MadeChanges;
+  }
+  
+  // All Required analyses should be available to the pass as it runs!  Here
+  // we fill in the AnalysisImpls member of the pass so that it can
+  // successfully use the getAnalysis() method to retrieve the
+  // implementations it needs.
   //
-  typedef PassManagerT<Module> SubPassClass;
+  inline void initialiseAnalysisImpl(PassClass *P, AnalysisUsage &AnUsage) { 
+    P->AnalysisImpls.clear();
+    P->AnalysisImpls.reserve(AnUsage.getRequiredSet().size());
+    
+    for (std::vector<const PassInfo *>::const_iterator
+         I = AnUsage.getRequiredSet().begin(),
+         E = AnUsage.getRequiredSet().end(); I != E; ++I) {
+      Pass *Impl = getAnalysisOrNullUp(*I);
+      if (Impl == 0) {
+        std::cerr << "Analysis '" << (*I)->getPassName()
+                  << "' used but not available!";
+        assert(0 && "Analysis used but not available!");
+      } else if (PassDebugging == Details) {
+        if ((*I)->getPassName() != std::string(Impl->getPassName()))
+          std::cerr << "    Interface '" << (*I)->getPassName()
+                  << "' implemented by '" << Impl->getPassName() << "'\n";
+      }
+      
+      P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
+    }
+  }
+  
+  inline void removeNonPreservedAnalyses(AnalysisUsage &AnUsage) { 
+    if (!AnUsage.getPreservesAll()) {
+      const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
+      for (std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.begin(),
+           E = CurrentAnalyses.end(); I != E; )
+        if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) !=
+            PreservedSet.end())
+          ++I; // This analysis is preserved, leave it in the available set...
+      else {
+        if (!dynamic_cast<ImmutablePass*>(I->second)) {
+          std::map<AnalysisID, Pass*>::iterator J = I++;
+          CurrentAnalyses.erase(J);   // Analysis not preserved!
+        } else {
+          ++I;
+        }
+      }
+    }
+  }
+  
+  inline void removeDeadPasses(Pass* P, UnitType *M, 
+              std::map<Pass *, std::vector<Pass*> > &LastUserOf) { 
+    std::vector<Pass*> &DeadPass = LastUserOf[P];
+    for (std::vector<Pass*>::iterator I = DeadPass.begin(),E = DeadPass.end();
+          I != E; ++I) {
+      PMDebug::PrintPassInformation(getDepth()+1, "Freeing Pass", *I, M);
+      (*I)->releaseMemory();
+    }
+    
+    for (std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.begin();
+          I != CurrentAnalyses.end(); ) {
+      std::vector<Pass*>::iterator DPI = std::find(DeadPass.begin(),
+                                                    DeadPass.end(), I->second);
+      if (DPI != DeadPass.end()) {    // This pass is dead now... remove it
+        std::map<AnalysisID, Pass*>::iterator IDead = I++;
+        CurrentAnalyses.erase(IDead);
+      } else {
+        ++I;  // Move on to the next element...
+      }
+    }
+  }
+  
+  inline void makeCurrentlyAvailable(Pass* P) { 
+    if (const PassInfo *PI = P->getPassInfo()) {
+      CurrentAnalyses[PI] = P;
 
-  // BatcherClass - The type to use for collation of subtypes... This class is
-  // never instantiated for the PassManager<BasicBlock>, but it must be an 
-  // instance of PassClass to typecheck.
-  //
-  typedef PassClass BatcherClass;
+      // This pass is the current implementation of all of the interfaces it
+      // implements as well.
+      //
+      const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+      for (unsigned i = 0, e = II.size(); i != e; ++i)
+        CurrentAnalyses[II[i]] = P;
+    }
+  }
+};
 
-  // ParentClass - The type of the parent PassManager...
-  typedef PassManagerT<Function> ParentClass;
 
-  // PMType - The type of the passmanager that subclasses this class
-  typedef PassManagerT<BasicBlock> PMType;
 
+//===----------------------------------------------------------------------===//
+// BasicBlockPassManager
+//
+// This pass manager is used to group together all of the BasicBlockPass's
+// into a single unit.
+//
+class BasicBlockPassManager : public BasicBlockPass, 
+                              public BBTraits, 
+                              public PassManagerT<BBTraits> {
+public:
+  BasicBlockPassManager(BBTraits::ParentClass* PC) : 
+    PassManagerT<BBTraits>(PC) {
+  }
+  
+  BasicBlockPassManager(BasicBlockPassManager* BBPM) : 
+    PassManagerT<BBTraits>(BBPM->Parent) {
+  }
+  
   // runPass - Specify how the pass should be run on the UnitType
-  static bool runPass(PassClass *P, BasicBlock *M) {
-    // todo, init and finalize
+  virtual bool runPass(BBTraits::PassClass *P, BasicBlock *M) {
+    // TODO: init and finalize
     return P->runOnBasicBlock(*M);
   }
-
+  
+  virtual ~BasicBlockPassManager() {}
+  
+  virtual void dumpPassStructure(unsigned Offset = 0) { 
+    PassManagerT<BBTraits>::dumpPassStructure(Offset);
+  }
+  
   // getPMName() - Return the name of the unit the PassManager operates on for
   // debugging.
-  const char *getPMName() const { return "BasicBlock"; }
+  virtual 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 doInitialization(Function &F);
   virtual bool runOnBasicBlock(BasicBlock &BB);
   virtual bool doFinalization(Function &F);
   virtual bool doFinalization(Module &M);
-
+  
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
   }
 };
 
-
-
 //===----------------------------------------------------------------------===//
-// PassManagerTraits<Function> Specialization
+// FunctionPassManager
 //
 // This pass manager is used to group together all of the FunctionPass's
 // into a single unit.
 //
-template<> struct PassManagerTraits<Function> : public FunctionPass {
-  // PassClass - The type of passes tracked by this PassManager
-  typedef FunctionPass PassClass;
-
-  // SubPassClass - The types of classes that should be collated together
-  typedef BasicBlockPass SubPassClass;
-
-  // BatcherClass - The type to use for collation of subtypes...
-  typedef PassManagerT<BasicBlock> BatcherClass;
-
-  // ParentClass - The type of the parent PassManager...
-  typedef PassManagerT<Module> ParentClass;
-
-  // PMType - The type of the passmanager that subclasses this class
-  typedef PassManagerT<Function> PMType;
-
-  // runPass - Specify how the pass should be run on the UnitType
-  static bool runPass(PassClass *P, Function *F) {
-    return P->runOnFunction(*F);
+class FunctionPassManagerT : public FunctionPass, 
+                             public FTraits, 
+                             public PassManagerT<FTraits> {
+public:
+  FunctionPassManagerT() : PassManagerT<FTraits>(0) {}
+  
+  // Parent constructor
+  FunctionPassManagerT(FTraits::ParentClass* PC) : PassManagerT<FTraits>(PC) {}
+  
+  FunctionPassManagerT(FunctionPassManagerT* FPM) : 
+    PassManagerT<FTraits>(FPM->Parent) {
   }
-
+  
+  virtual ~FunctionPassManagerT() {}
+  
+  virtual void dumpPassStructure(unsigned Offset = 0) { 
+    PassManagerT<FTraits>::dumpPassStructure(Offset);
+  }
+  
   // getPMName() - Return the name of the unit the PassManager operates on for
   // debugging.
-  const char *getPMName() const { return "Function"; }
+  virtual 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 doInitialization(Module &M);
+  
   virtual bool doFinalization(Module &M);
-
+  
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
   }
+  
+  // runPass - Specify how the pass should be run on the UnitType
+  virtual bool runPass(FTraits::PassClass *P, Function *F) {
+    return P->runOnFunction(*F);
+  }
 };
 
 
-
 //===----------------------------------------------------------------------===//
-// PassManagerTraits<Module> Specialization
+// ModulePassManager
 //
 // This is the top level PassManager implementation that holds generic passes.
 //
-template<> struct PassManagerTraits<Module> : public Pass {
-  // PassClass - The type of passes tracked by this PassManager
-  typedef Pass PassClass;
-
-  // SubPassClass - The types of classes that should be collated together
-  typedef FunctionPass SubPassClass;
-
-  // BatcherClass - The type to use for collation of subtypes...
-  typedef PassManagerT<Function> BatcherClass;
-
-  // ParentClass - The type of the parent PassManager...
-  typedef AnalysisResolver ParentClass;
-
-  // runPass - Specify how the pass should be run on the UnitType
-  static bool runPass(PassClass *P, Module *M) { return P->run(*M); }
-
+class ModulePassManager : public ModulePass, 
+                          public MTraits, 
+                          public PassManagerT<MTraits> {
+public:
+  ModulePassManager() : PassManagerT<MTraits>(0) {}
+  
+  // Batcher Constructor
+  ModulePassManager(MTraits::ParentClass* PC) : PassManagerT<MTraits>(PC) {}
+  
+  ModulePassManager(ModulePassManager* MPM) : 
+    PassManagerT<MTraits>((MPM->Parent)) {
+  }
+  
+  virtual ~ModulePassManager() {}
+  
+  virtual void dumpPassStructure(unsigned Offset = 0) { 
+    PassManagerT<MTraits>::dumpPassStructure(Offset);
+  }
+  
   // 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"; }
-
-  // run - Implement the PassManager interface...
-  bool run(Module &M) {
-    return ((PassManagerT<Module>*)this)->runOnUnit(&M);
+  
+  // getPMName() - Return the name of the unit the PassManager operates on for
+  // debugging.
+  virtual const char *getPMName() const { return "Module"; }
+  
+  // runOnModule - Implement the PassManager interface.
+  virtual bool runOnModule(Module &M);
+  
+  // runPass - Specify how the pass should be run on the UnitType
+  virtual bool runPass(MTraits::PassClass *P, Module *M) {
+    return P->runOnModule(*M);
   }
 };
 
-
-
 //===----------------------------------------------------------------------===//
-// PassManagerTraits Method Implementations
+// PassManager Method Implementations
 //
 
-// PassManagerTraits<BasicBlock> Implementations
+// BasicBlockPassManager Implementations
 //
-inline bool PassManagerTraits<BasicBlock>::doInitialization(Module &M) {
-  bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doInitialization(M);
-  return Changed;
+
+inline bool BasicBlockPassManager::runOnBasicBlock(BasicBlock &BB) {
+  return ((BBTraits::PMType*)this)->runOnUnit(&BB);
 }
 
-inline bool PassManagerTraits<BasicBlock>::doInitialization(Function &F) {
+inline bool BasicBlockPassManager::doInitialization(Module &M) {
   bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doInitialization(F);
+  for (unsigned i = 0, e =((BBTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((BBTraits::PMType*)this)->Passes[i]->doInitialization(M);
   return Changed;
 }
 
-inline bool PassManagerTraits<BasicBlock>::runOnBasicBlock(BasicBlock &BB) {
-  return ((PMType*)this)->runOnUnit(&BB);
+inline bool BasicBlockPassManager::doInitialization(Function &F) {
+  bool Changed = false;
+  for (unsigned i = 0, e =((BBTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((BBTraits::PMType*)this)->Passes[i]->doInitialization(F);
+  return Changed;
 }
 
-inline bool PassManagerTraits<BasicBlock>::doFinalization(Function &F) {
+inline bool BasicBlockPassManager::doFinalization(Function &F) {
   bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doFinalization(F);
+  for (unsigned i = 0, e =((BBTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((BBTraits::PMType*)this)->Passes[i]->doFinalization(F);
   return Changed;
 }
 
-inline bool PassManagerTraits<BasicBlock>::doFinalization(Module &M) {
+inline bool BasicBlockPassManager::doFinalization(Module &M) {
   bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doFinalization(M);
+  for (unsigned i=0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((BBTraits::PMType*)this)->Passes[i]->doFinalization(M);
   return Changed;
 }
 
-
-// PassManagerTraits<Function> Implementations
+// FunctionPassManagerT Implementations
 //
-inline bool PassManagerTraits<Function>::doInitialization(Module &M) {
-  bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doInitialization(M);
-  return Changed;
+
+inline bool FunctionPassManagerT::runOnFunction(Function &F) {
+  return ((FTraits::PMType*)this)->runOnUnit(&F);
 }
 
-inline bool PassManagerTraits<Function>::runOnFunction(Function &F) {
-  return ((PMType*)this)->runOnUnit(&F);
+inline bool FunctionPassManagerT::doInitialization(Module &M) {
+  bool Changed = false;
+  for (unsigned i=0, e = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((FTraits::PMType*)this)->Passes[i]->doInitialization(M);
+  return Changed;
 }
 
-inline bool PassManagerTraits<Function>::doFinalization(Module &M) {
+inline bool FunctionPassManagerT::doFinalization(Module &M) {
   bool Changed = false;
-  for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
-    ((PMType*)this)->Passes[i]->doFinalization(M);
+  for (unsigned i=0, e = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i)
+    ((FTraits::PMType*)this)->Passes[i]->doFinalization(M);
   return Changed;
 }
 
+// ModulePassManager Implementations
+//
+
+bool ModulePassManager::runOnModule(Module &M) {
+  return ((PassManagerT<MTraits>*)this)->runOnUnit(&M);
+}
+
+} // End llvm namespace
+
 #endif