From 97149737f27457b0411e49af3e4539688e29848f Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 11 Jan 2007 00:19:00 +0000 Subject: [PATCH] Robustify assingPassManager() for Module, Function and Basic Block Passes. Robustify PMStack.push() Add dump() routine to print PMStack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33062 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Pass.h | 6 +- lib/VMCore/PassManager.cpp | 110 ++++++++++++++++++++++++------------- 2 files changed, 77 insertions(+), 39 deletions(-) diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index b3ac33485d5..7599b678ec8 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -52,6 +52,7 @@ class FunctionPassManagerT; class ModulePassManager; class PMStack; class AnalysisResolver; +class PMDataManager; // AnalysisID - Use the PassInfo to identify a pass... typedef const PassInfo* AnalysisID; @@ -106,6 +107,7 @@ public: void print(std::ostream *O, const Module *M) const { if (O) print(*O, M); } void dump() const; // dump - call print(std::cerr, 0); + virtual void assignPassManager(PMStack &PMS) {} // Access AnalysisResolver inline void setResolver(AnalysisResolver *AR) { Resolver = AR; } inline AnalysisResolver *getResolver() { return Resolver; } @@ -329,7 +331,6 @@ public: /// /// PMStack is just a wrapper around standard deque that overrides pop() and /// push() methods. -class PMDataManager; class PMStack { public: typedef std::deque::reverse_iterator iterator; @@ -340,9 +341,10 @@ public: void pop(); inline PMDataManager *top() { return S.back(); } - void push(PMDataManager *PM); + void push(Pass *P); inline bool empty() { return S.empty(); } + void dump(); private: std::deque S; }; diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 46ad33bf964..62e453399b6 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -1616,14 +1616,39 @@ void PMStack::pop() { } // Push PM on the stack and set its top level manager. -void PMStack::push(PMDataManager *PM) { +void PMStack::push(Pass *P) { - PMDataManager *Top = this->top(); + PMDataManager *Top = NULL; + PMDataManager *PM = dynamic_cast(P); + assert (PM && "Unable to push. Pass Manager expected"); - // Inherit top level manager - PMTopLevelManager *TPM = Top->getTopLevelManager(); - PM->setTopLevelManager(TPM); - TPM->addIndirectPassManager(PM); + if (this->empty()) { + Top = PM; + } + else { + Top = this->top(); + PMTopLevelManager *TPM = Top->getTopLevelManager(); + + assert (TPM && "Unable to find top level manager"); + TPM->addIndirectPassManager(PM); + PM->setTopLevelManager(TPM); + } + + AnalysisResolver *AR = new AnalysisResolver(*Top); + P->setResolver(AR); + + S.push_back(PM); +} + +// Dump content of the pass manager stack. +void PMStack::dump() { + for(std::deque::iterator I = S.begin(), + E = S.end(); I != E; ++I) { + Pass *P = dynamic_cast(*I); + printf ("%s ", P->getPassName()); + } + if (!S.empty()) + printf ("\n"); } // Walk Pass Manager stack and set LastUse markers if any @@ -1662,7 +1687,6 @@ void ModulePass::assignPassManager(PMStack &PMS) { } assert(MPP && "Unable to find Module Pass Manager"); - MPP->addPassToManager(this); } @@ -1672,34 +1696,42 @@ void FunctionPass::assignPassManager(PMStack &PMS) { FPPassManager *FPP = NULL; - // Find Module Pass Manager + // Find Module Pass Manager (TODO : Or Call Graph Pass Manager) while(!PMS.empty()) { FPP = dynamic_cast(PMS.top()); - if (FPP || dynamic_cast(PMS.top())) - break; // Found it or it is not here + if (FPP) + break; // Found Function Pass Manager + else if (dynamic_cast(PMS.top())) + PMS.pop(); // Pop Basic Block Pass Manager + // TODO : else if Pop Loop Pass Manager else - PMS.pop(); // Pop children pass managers + break; // PMS.top() is either Module Pass Manager or Call Graph + // Pass Manager } + // Create new Function Pass Manager 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(PMD) && - "Unable to create Function Pass Manager"); + // [1] Create new Function Pass Manager FPP = new FPPassManager(PMD->getDepth() + 1); - PMD->addPassToManager(FPP, false); + + // [2] Set up new manager's top level manager + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(FPP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + Pass *P = dynamic_cast(FPP); + P->assignPassManager(PMS); + + // [4] Push new manager into PMS PMS.push(FPP); } - + // Assign FPP as the manager of this pass. FPP->addPassToManager(this); } @@ -1709,33 +1741,37 @@ void BasicBlockPass::assignPassManager(PMStack &PMS) { BBPassManager *BBP = NULL; - // Find Module Pass Manager - while(!PMS.empty()) { - + // Basic Pass Manager is a leaf pass manager. It does not handle + // any other pass manager. + if (!PMS.empty()) { BBP = dynamic_cast(PMS.top()); - if (BBP || dynamic_cast(PMS.top())) - break; // Found it or it is not here - else - PMS.pop(); // Pop children pass managers } + // If leaf manager is not Basic Block Pass manager then create new + // basic Block Pass manager. + 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(PMD) && - "Unable to create BasicBlock Pass Manager"); + // [1] Create new Basic Block Manager BBP = new BBPassManager(PMD->getDepth() + 1); - PMD->addPassToManager(BBP, false); + + // [2] Set up new manager's top level manager + // Basic Block Pass Manager does not live by itself + PMTopLevelManager *TPM = PMD->getTopLevelManager(); + TPM->addIndirectPassManager(BBP); + + // [3] Assign manager to manage this new manager. This may create + // and push new managers into PMS + Pass *P = dynamic_cast(BBP); + P->assignPassManager(PMS); + + // [4] Push new manager into PMS PMS.push(BBP); } + // Assign BBP as the manager of this pass. BBP->addPassToManager(this); }