aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-01-08 19:29:38 +0000
committerDevang Patel <dpatel@apple.com>2007-01-08 19:29:38 +0000
commit09e6e4303f1aac10fea6860e7736c234fcbf56cc (patch)
tree5eb6932d5e59d58bd57674ee07583bfae76e8956
parent27376106d94017a72fc602bd9279a6f9fd3018da (diff)
downloadexternal_llvm-09e6e4303f1aac10fea6860e7736c234fcbf56cc.zip
external_llvm-09e6e4303f1aac10fea6860e7736c234fcbf56cc.tar.gz
external_llvm-09e6e4303f1aac10fea6860e7736c234fcbf56cc.tar.bz2
Add PMStack, a Pass Manager stack.
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
-rw-r--r--include/llvm/Pass.h34
-rw-r--r--lib/VMCore/PassManager.cpp138
2 files changed, 170 insertions, 2 deletions
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index 2c82e56..b3ac334 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -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.
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index faab37e..46ad33b 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -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);
+}
+