Add PMStack, a Pass Manager stack.
authorDevang Patel <dpatel@apple.com>
Mon, 8 Jan 2007 19:29:38 +0000 (19:29 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 8 Jan 2007 19:29:38 +0000 (19:29 +0000)
Eventually, Top level pass managers  will use this to keep track of
active pass managers. Eass pass will also learn how to find appropriate
manager from these managers stack.

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

include/llvm/Pass.h
lib/VMCore/PassManager.cpp

index 2c82e565ba8adcf2143a8105bf19a0e0649426b9..b3ac33485d55edaec95ee6c95e7ffec3d6d4f906 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "llvm/Support/Streams.h"
 #include <vector>
+#include <deque>
 #include <map>
 #include <iosfwd>
 #include <typeinfo>
@@ -49,6 +50,7 @@ template<class Trait> class PassManagerT;
 class BasicBlockPassManager;
 class FunctionPassManagerT;
 class ModulePassManager;
+class PMStack;
 class AnalysisResolver;
 
 // AnalysisID - Use the PassInfo to identify a pass...
@@ -133,8 +135,6 @@ public:
   // dumpPassStructure - Implement the -debug-passes=PassStructure option
   virtual void dumpPassStructure(unsigned Offset = 0);
 
-
-  // getPassInfo - Static method to get the pass information from a class name.
   template<typename AnalysisClass>
   static const PassInfo *getClassPassInfo() {
     return lookupPassInfo(typeid(AnalysisClass));
@@ -198,6 +198,7 @@ public:
   virtual bool runPass(Module &M) { return runOnModule(M); }
   virtual bool runPass(BasicBlock&) { return false; }
 
+  virtual void assignPassManager(PMStack &PMS);
   // Force out-of-line virtual method.
   virtual ~ModulePass();
 };
@@ -263,6 +264,7 @@ public:
   ///
   bool run(Function &F);
 
+  virtual void assignPassManager(PMStack &PMS);
 };
 
 
@@ -316,8 +318,36 @@ public:
   virtual bool runPass(Module &M) { return false; }
   virtual bool runPass(BasicBlock &BB);
 
+  virtual void assignPassManager(PMStack &PMS);
+};
+
+/// PMStack
+/// Top level pass manager (see PasManager.cpp) maintains active Pass Managers 
+/// using PMStack. Each Pass implements assignPassManager() to connect itself
+/// with appropriate manager. assignPassManager() walks PMStack to find
+/// suitable manager.
+///
+/// PMStack is just a wrapper around standard deque that overrides pop() and
+/// push() methods.
+class PMDataManager;
+class PMStack {
+public:
+  typedef std::deque<PMDataManager *>::reverse_iterator iterator;
+  iterator begin() { return S.rbegin(); }
+  iterator end() { return S.rend(); }
+
+  void handleLastUserOverflow();
+
+  void pop();
+  inline PMDataManager *top() { return S.back(); }
+  void push(PMDataManager *PM);
+  inline bool empty() { return S.empty(); }
+
+private:
+  std::deque<PMDataManager *> S;
 };
 
+
 /// If the user specifies the -time-passes argument on an LLVM tool command line
 /// then the value of this boolean will be true, otherwise false.
 /// @brief This is the storage for the -time-passes option.
index faab37e3de7b6ef6cf05aff44fbd02471fcd4932..46ad33bf96489695eaff7cfdcf6efbfa5c53740e 100644 (file)
@@ -1514,7 +1514,9 @@ MPPassManager::runOnModule(Module &M) {
 bool PassManagerImpl::addPass(Pass *P) {
 
   if (!activeManager || !activeManager->addPass(P)) {
+
     activeManager = new MPPassManager(getDepth() + 1);
+    
     // Inherit top level manager
     activeManager->setTopLevelManager(this->getTopLevelManager());
 
@@ -1601,4 +1603,140 @@ void TimingInfo::createTheTimeInfo() {
   TheTimeInfo = &*TTI;
 }
 
+//===----------------------------------------------------------------------===//
+// PMStack implementation
+//
+// Pop Pass Manager from the stack and clear its analysis info.
+void PMStack::pop() {
+
+  PMDataManager *Top = this->top();
+  Top->initializeAnalysisInfo();
+
+  S.pop_back();
+}
+
+// Push PM on the stack and set its top level manager.
+void PMStack::push(PMDataManager *PM) {
+
+  PMDataManager *Top = this->top();
+
+  // Inherit top level manager
+  PMTopLevelManager *TPM = Top->getTopLevelManager();
+  PM->setTopLevelManager(TPM);
+  TPM->addIndirectPassManager(PM);
+}
+
+// Walk Pass Manager stack and set LastUse markers if any
+// manager is transfering this priviledge to its parent manager
+void PMStack::handleLastUserOverflow() {
+
+  for(PMStack::iterator I = this->begin(), E = this->end(); I != E;) {
+
+    PMDataManager *Child = *I++;
+    if (I != E) {
+      PMDataManager *Parent = *I++;
+      PMTopLevelManager *TPM = Parent->getTopLevelManager();
+      std::vector<Pass *> &TLU = Child->getTransferredLastUses();
+      if (!TLU.empty()) {
+        Pass *P = dynamic_cast<Pass *>(Parent);
+        TPM->setLastUser(TLU, P);
+      }
+    }
+  }
+}
+
+/// Find appropriate Module Pass Manager in the PM Stack and
+/// add self into that manager. 
+void ModulePass::assignPassManager(PMStack &PMS) {
+
+  MPPassManager *MPP = NULL;
+
+  // Find Module Pass Manager
+  while(!PMS.empty()) {
+
+    MPP = dynamic_cast<MPPassManager *>(PMS.top());
+    if (MPP)
+      break;        // Found it
+    else
+      PMS.pop();    // Pop children pass managers
+  }
+
+  assert(MPP && "Unable to find Module Pass Manager");
+
+  MPP->addPassToManager(this);
+}
+
+/// Find appropriate Function Pass Manager or Call Graph Pass Manager
+/// in the PM Stack and add self into that manager. 
+void FunctionPass::assignPassManager(PMStack &PMS) {
+
+  FPPassManager *FPP = NULL;
+
+  // Find Module Pass Manager
+  while(!PMS.empty()) {
+
+    FPP = dynamic_cast<FPPassManager *>(PMS.top());
+    if (FPP || dynamic_cast<MPPassManager *>(PMS.top()))
+      break;        // Found it or it is not here
+    else
+      PMS.pop();    // Pop children pass managers
+  }
+
+  if (!FPP) {
+    /// Create new Function Pass Manager
+
+    /// Function Pass Manager does not live by itself
+    assert(!PMS.empty() && "Unable to create Function Pass Manager");
+
+    PMDataManager *PMD = PMS.top();
+    
+    /// PMD should be either Module Pass Manager or Call Graph Pass Manager
+    assert(dynamic_cast<MPPassManager *>(PMD) && 
+           "Unable to create Function Pass Manager");
+
+    FPP = new FPPassManager(PMD->getDepth() + 1);
+    PMD->addPassToManager(FPP, false);
+    PMS.push(FPP);
+  }
+
+
+  FPP->addPassToManager(this);
+}
+
+/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
+/// in the PM Stack and add self into that manager. 
+void BasicBlockPass::assignPassManager(PMStack &PMS) {
+
+  BBPassManager *BBP = NULL;
+
+  // Find Module Pass Manager
+  while(!PMS.empty()) {
+
+    BBP = dynamic_cast<BBPassManager *>(PMS.top());
+    if (BBP || dynamic_cast<FPPassManager *>(PMS.top()))
+      break;        // Found it or it is not here
+    else
+      PMS.pop();    // Pop children pass managers
+  }
+
+  if (!BBP) {
+    /// Create new BasicBlock Pass Manager
+
+    /// BasicBlock Pass Manager does not live by itself
+    assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
+
+    PMDataManager *PMD = PMS.top();
+    
+    /// PMD should be Function Pass Manager
+    assert(dynamic_cast<FPPassManager *>(PMD) && 
+           "Unable to create BasicBlock Pass Manager");
+
+    BBP = new BBPassManager(PMD->getDepth() + 1);
+    PMD->addPassToManager(BBP, false);
+    PMS.push(BBP);
+  }
+
+  BBP->addPassToManager(this);
+}
+