diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 4730a668a8d..90e614d6323 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -44,7 +44,10 @@ class Module; class AnalysisUsage; class PassInfo; class ImmutablePass; -template class PassManagerT; +template class PassManagerT; +class BasicBlockPassManager; +class FunctionPassManagerT; +class ModulePassManager; struct AnalysisResolver; // AnalysisID - Use the PassInfo to identify a pass... @@ -197,9 +200,10 @@ public: } private: - friend class PassManagerT; - friend class PassManagerT; - friend class PassManagerT; + template friend class PassManagerT; + friend class ModulePassManager; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; }; inline std::ostream &operator<<(std::ostream &OS, const Pass &P) { @@ -220,7 +224,7 @@ public: virtual bool runPass(Module &M) { return runOnModule(M); } virtual bool runPass(BasicBlock&) { return false; } - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); }; @@ -244,8 +248,9 @@ public: virtual bool runOnModule(Module &M) { return false; } private: - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + template friend class PassManagerT; + friend class ModulePassManager; + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); }; //===----------------------------------------------------------------------===// @@ -286,11 +291,12 @@ public: bool run(Function &F); private: - friend class PassManagerT; - friend class PassManagerT; - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + template friend class PassManagerT; + friend class ModulePassManager; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); + virtual void addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU); }; @@ -344,10 +350,11 @@ struct BasicBlockPass : public FunctionPass { virtual bool runPass(BasicBlock &BB); private: - friend class PassManagerT; - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); - virtual void addToPassManager(PassManagerT *PM,AnalysisUsage &AU); + template friend class PassManagerT; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; + virtual void addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU); + virtual void addToPassManager(BasicBlockPassManager *PM,AnalysisUsage &AU); }; /// If the user specifies the -time-passes argument on an LLVM tool command line diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h index 85062873087..47b49adeb85 100644 --- a/include/llvm/PassManager.h +++ b/include/llvm/PassManager.h @@ -23,10 +23,12 @@ class Pass; class ModulePass; class Module; class ModuleProvider; -template class PassManagerT; +class ModulePassManager; +class FunctionPassManagerT; +class BasicBlockPassManager; class PassManager { - PassManagerT *PM; // This is a straightforward Pimpl class + ModulePassManager *PM; // This is a straightforward Pimpl class public: PassManager(); ~PassManager(); @@ -49,7 +51,7 @@ class ImmutablePass; class Function; class FunctionPassManager { - PassManagerT *PM; // This is a straightforward Pimpl class + FunctionPassManagerT *PM; // This is a straightforward Pimpl class ModuleProvider *MP; public: FunctionPassManager(ModuleProvider *P); diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index dc547ae47c6..94b1d4795e4 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -78,7 +78,7 @@ void AnalysisUsage::setPreservesCFG() { // PassManager implementation - The PassManager class is a simple Pimpl class // that wraps the PassManagerT template. // -PassManager::PassManager() : PM(new PassManagerT()) {} +PassManager::PassManager() : PM(new ModulePassManager()) {} PassManager::~PassManager() { delete PM; } void PassManager::add(Pass *P) { ModulePass *MP = dynamic_cast(P); @@ -93,7 +93,7 @@ bool PassManager::run(Module &M) { return PM->runOnModule(M); } // is like PassManager, but only deals in FunctionPasses. // FunctionPassManager::FunctionPassManager(ModuleProvider *P) : - PM(new PassManagerT()), MP(P) {} + PM(new FunctionPassManagerT()), MP(P) {} FunctionPassManager::~FunctionPassManager() { delete PM; } void FunctionPassManager::add(FunctionPass *P) { PM->add(P); } void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); } @@ -194,7 +194,7 @@ void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg, // Pass Implementation // -void ModulePass::addToPassManager(PassManagerT *PM, AnalysisUsage &AU) { +void ModulePass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -231,7 +231,7 @@ void Pass::dump() const { //===----------------------------------------------------------------------===// // ImmutablePass Implementation // -void ImmutablePass::addToPassManager(PassManagerT *PM, +void ImmutablePass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -264,12 +264,12 @@ bool FunctionPass::run(Function &F) { return Changed | doFinalization(*F.getParent()); } -void FunctionPass::addToPassManager(PassManagerT *PM, +void FunctionPass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } -void FunctionPass::addToPassManager(PassManagerT *PM, +void FunctionPass::addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -302,12 +302,12 @@ bool BasicBlockPass::runPass(BasicBlock &BB) { return Changed; } -void BasicBlockPass::addToPassManager(PassManagerT *PM, +void BasicBlockPass::addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } -void BasicBlockPass::addToPassManager(PassManagerT *PM, +void BasicBlockPass::addToPassManager(BasicBlockPassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index f93e760d66b..bc8ceea6eef 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -123,10 +123,70 @@ public: static TimingInfo *TheTimeInfo; -//===----------------------------------------------------------------------===// -// Declare the PassManagerTraits which will be specialized... -// -template class PassManagerTraits; // Do not define. +// FIXME:I'm not sure if this is the best way, but this was the only way I +// could get around the recursive template issues. -- Saem +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 PassManager, 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; +}; //===----------------------------------------------------------------------===// @@ -134,32 +194,26 @@ template class PassManagerTraits; // Do not define. // deletes all passes contained inside of the PassManagerT, so you shouldn't // delete passes manually, and all passes should be dynamically allocated. // -template -class PassManagerT : public PassManagerTraits,public AnalysisResolver{ - // TODO:Edit these to reflect changes for world sanitisation - typedef PassManagerTraits Traits; - typedef typename Traits::PassClass PassClass; - typedef typename Traits::SubPassClass SubPassClass; - typedef typename Traits::BatcherClass BatcherClass; - typedef typename Traits::ParentClass ParentClass; - -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) || defined(__HP_aCC) - friend PassClass; - friend SubPassClass; -#else - // TODO:Redefine when sanitising - friend class PassManagerTraits::PassClass; - friend class PassManagerTraits::SubPassClass; -#endif - // TODO:Redefine this when santising - friend class PassManagerTraits; +template 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 Passes; // List of passes to run + std::vector Passes; // List of passes to run std::vector ImmutablePasses; // List of immutable passes // The parent of this pass manager... @@ -181,6 +235,18 @@ class PassManagerT : public PassManagerTraits,public AnalysisResolver{ std::map 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) {} virtual ~PassManagerT() { // Delete all of the contained passes... @@ -221,7 +287,7 @@ public: LastUserOf[I->second].push_back(I->first); // Output debug information... - if (Parent == 0) PMDebug::PerformPassStartupStuff(this); + if (Parent == 0) PMDebug::PerformPassStartupStuff((dynamic_cast(this))); // Run all of the passes for (unsigned i = 0, e = Passes.size(); i < e; ++i) { @@ -337,7 +403,7 @@ public: 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::iterator I = Passes.begin(), E = Passes.end(); I != E; ++I) { @@ -425,7 +491,7 @@ public: // frees the analysis AFTER this pass manager runs. // if (Parent) { - Parent->markPassUsed(P, this); + Parent->markPassUsed(P, dynamic_cast(this)); } else { assert(getAnalysisOrNullUp(P) && dynamic_cast(getAnalysisOrNullUp(P)) && @@ -473,7 +539,7 @@ public: // depends on the class of the pass, and is critical to laying out passes in // an optimal order.. // - P->addToPassManager(this, AnUsage); + P->addToPassManager(dynamic_cast(this), AnUsage); } // add - H4x0r an ImmutablePass into a PassManager that might not be @@ -566,14 +632,14 @@ private: // For now assume that our results are never used... LastUseOf[P] = P; } - + // For FunctionPass subclasses, we must be sure to batch the FunctionPass's // together in a BatcherClass object so that all of the analyses are run // 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); + Batcher = new BatcherClass((dynamic_cast(this))); // The Batcher will queue the passes up MP->addToPassManager(Batcher, AnUsage); } @@ -627,48 +693,33 @@ public: // Initialize the immutable pass... IP->initializePass(); } - - // TODO: Once the world has been sanitised, the pure virtuals below can be - // brought in. + }; - //===----------------------------------------------------------------------===// // BasicBlockPassManager // // This pass manager is used to group together all of the BasicBlockPass's // into a single unit. // -class BasicBlockPassManager { +class BasicBlockPassManager : public BasicBlockPass, + public BBTraits, + public PassManagerT { public: - // 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 PassManagerT SubPassClass; - - // BatcherClass - The type to use for collation of subtypes... This class is - // never instantiated for the PassManager, but it must be an - // instance of PassClass to typecheck. - // - typedef PassClass BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef PassManagerT ParentClass; - - // PMType - The type of the passmanager that subclasses this class - typedef PassManagerT PMType; - + BasicBlockPassManager(BBTraits::ParentClass* PC) : + PassManagerT(PC) { + } + + BasicBlockPassManager(BasicBlockPassManager* BBPM) : + PassManagerT(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() {} // getPMName() - Return the name of the unit the PassManager operates on for @@ -688,84 +739,27 @@ public: } }; - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This pass manager is used to group together all of the BasicBlockPass's -// into a single unit. -// -template<> class PassManagerTraits : public BasicBlockPass, - public BasicBlockPassManager { -public: - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, BasicBlock *M) { - return BasicBlockPassManager::runPass(P,M); - } - - // Forwarded - virtual bool doInitialization(Module &M) { - return BasicBlockPassManager::doInitialization(M); - } - - // Forwarded - virtual bool doInitialization(Function &F) { - return BasicBlockPassManager::doInitialization(F); - } - - // Forwarded - virtual bool runOnBasicBlock(BasicBlock &BB) { - return BasicBlockPassManager::runOnBasicBlock(BB); - } - - // Forwarded - virtual bool doFinalization(Function &F) { - return BasicBlockPassManager::doFinalization(F); - } - - // Forwarded - virtual bool doFinalization(Module &M) { - return BasicBlockPassManager::doFinalization(M); - } - - // Forwarded - virtual const char *getPassName() const { - return BasicBlockPassManager::getPassName(); - } - - // Forwarded - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - BasicBlockPassManager::getAnalysisUsage(AU); - } - -}; - - //===----------------------------------------------------------------------===// // FunctionPassManager // // This pass manager is used to group together all of the FunctionPass's // into a single unit. // -class FunctionPassManagerT { +class FunctionPassManagerT : public FunctionPass, + public FTraits, + public PassManagerT { public: - // 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 BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef PassManagerT ParentClass; - - // PMType - The type of the passmanager that subclasses this class - typedef PassManagerT PMType; + FunctionPassManagerT() : PassManagerT(0) {} + + // Parent constructor + FunctionPassManagerT(FTraits::ParentClass* PC) : PassManagerT(PC) {} + + FunctionPassManagerT(FunctionPassManagerT* FPM) : + PassManagerT(FPM->Parent) { + } virtual ~FunctionPassManagerT() {} - + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "Function"; } @@ -783,73 +777,32 @@ public: } // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Function *F) { + virtual bool runPass(FTraits::PassClass *P, Function *F) { return P->runOnFunction(*F); } }; -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This pass manager is used to group together all of the FunctionPass's -// into a single unit. -// -template<> class PassManagerTraits : public FunctionPass, - public FunctionPassManagerT { -public: - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Function *F) { - return FunctionPassManagerT::runPass(P,F); - } - - // Forwarded - virtual bool doInitialization(Module &M) { - return FunctionPassManagerT::doInitialization(M); - } - - // Forwarded - virtual bool runOnFunction(Function &F) { - return FunctionPassManagerT::runOnFunction(F); - } - - // Forwarded - virtual bool doFinalization(Module &M) { - return FunctionPassManagerT::doFinalization(M); - } - - // Forwarded - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - FunctionPassManagerT::getAnalysisUsage(AU); - } - - // Forwarded - virtual const char *getPassName() const { - return FunctionPassManagerT::getPassName(); - } -}; - //===----------------------------------------------------------------------===// // ModulePassManager // // This is the top level PassManager implementation that holds generic passes. // -class ModulePassManager { +class ModulePassManager : public ModulePass, + public MTraits, + public PassManagerT { public: - // 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 PassManagerT BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef AnalysisResolver ParentClass; + ModulePassManager() : PassManagerT(0) {} + + // Batcher Constructor + ModulePassManager(MTraits::ParentClass* PC) : PassManagerT(PC) {} + + ModulePassManager(ModulePassManager* MPM) : + PassManagerT((MPM->Parent)) { + } virtual ~ModulePassManager() {} - + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPassName() const { return "Module Pass Manager"; } @@ -862,36 +815,10 @@ public: virtual bool runOnModule(Module &M); // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } + virtual bool runPass(MTraits::PassClass *P, Module *M) { return P->runOnModule(*M); } }; - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This is the top level PassManager implementation that holds generic passes. -// -template<> class PassManagerTraits : public ModulePass, - public ModulePassManager { -public: - // Forwarded - static bool runPass(PassClass *P, Module *M) { - return ModulePassManager::runPass(P,M); - } - - // Forwarded - bool runOnModule(Module &M) { - return ModulePassManager::runOnModule(M); - } - - // Forwarded - virtual const char *getPassName() const { - return ModulePassManager::getPassName(); - } -}; - - //===----------------------------------------------------------------------===// // PassManagerTraits Method Implementations // @@ -900,34 +827,34 @@ public: // inline bool BasicBlockPassManager::runOnBasicBlock(BasicBlock &BB) { - return ((PMType*)this)->runOnUnit(&BB); + return ((BBTraits::PMType*)this)->runOnUnit(&BB); } 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(M); + for (unsigned i = 0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((BBTraits::PMType*)this)->Passes[i]->doInitialization(M); return Changed; } inline bool BasicBlockPassManager::doInitialization(Function &F) { 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(F); return Changed; } 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 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; } @@ -935,20 +862,20 @@ inline bool BasicBlockPassManager::doFinalization(Module &M) { // inline bool FunctionPassManagerT::runOnFunction(Function &F) { - return ((PMType*)this)->runOnUnit(&F); + return ((FTraits::PMType*)this)->runOnUnit(&F); } inline bool FunctionPassManagerT::doInitialization(Module &M) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doInitialization(M); + for (unsigned i=0, e = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((FTraits::PMType*)this)->Passes[i]->doInitialization(M); return Changed; } 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; } @@ -956,7 +883,7 @@ inline bool FunctionPassManagerT::doFinalization(Module &M) { // bool ModulePassManager::runOnModule(Module &M) { - return ((PassManagerT*)this)->runOnUnit(&M); + return ((PassManagerT*)this)->runOnUnit(&M); }