diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h index 53dfa6bab0f..c75bc21a036 100644 --- a/include/llvm/PassManager.h +++ b/include/llvm/PassManager.h @@ -143,6 +143,29 @@ private: BasicBlockPassManager_New *activeBBPassManager; }; +/// FunctionPassManager_New manages FunctionPasses. +/// It batches all Module passes passes and function pass managers together and +/// sequence them to process one module. +class ModulePassManager_New: public Pass { + +public: + ModulePassManager_New() { activeFunctionPassManager = NULL; } + + /// Add a pass into a passmanager queue. + bool addPass(Pass *p); + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool runOnModule(Module &M); + +private: + // Collection of pass that are not yet scheduled + std::vector PassVector; + + // Active Pass Manager + FunctionPassManager_New *activeFunctionPassManager; +}; + } // End llvm namespace #endif diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 450a515c40b..31849a0ac0b 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -85,7 +85,7 @@ FunctionPassManager_New::addPass (Pass *P) { return false; // TODO: Check if it suitable to manage P using this FunctionPassManager - // or we need another instance of BasicBlockPassManager + // or we need another instance of FunctionPassManager PassVector.push_back(FP); activeBBPassManager = NULL; @@ -110,3 +110,56 @@ FunctionPassManager_New::runOnModule(Module &M) { } +// ModulePassManager implementation + +/// Add P into pass vector if it is manageble. If P is a FunctionPass +/// then use FunctionPassManager_New to manage it. Return FALSE if P +/// is not manageable by this manager. +bool +ModulePassManager_New::addPass (Pass *P) { + + // If P is FunctionPass then use function pass maanager. + if (FunctionPass *FP = dynamic_cast(P)) { + + activeFunctionPassManager = NULL; + + if (!activeFunctionPassManager + || !activeFunctionPassManager->addPass(P)) { + + activeFunctionPassManager = new FunctionPassManager_New(); + + PassVector.push_back(activeFunctionPassManager); + assert (!activeFunctionPassManager->addPass(FP) && + "Unable to add Pass"); + } + return true; + } + + ModulePass *MP = dynamic_cast(P); + if (!MP) + return false; + + // TODO: Check if it suitable to manage P using this ModulePassManager + // or we need another instance of ModulePassManager + + PassVector.push_back(MP); + activeFunctionPassManager = NULL; + return true; +} + + +/// Execute all of the passes scheduled for execution by invoking +/// runOnModule method. Keep track of whether any of the passes modifies +/// the module, and if so, return true. +bool +ModulePassManager_New::runOnModule(Module &M) { + bool Changed = false; + for (std::vector::iterator itr = PassVector.begin(), + e = PassVector.end(); itr != e; ++itr) { + Pass *P = *itr; + ModulePass *MP = dynamic_cast(P); + Changed |= MP->runOnModule(M); + } + return Changed; +} +