From cccd80dfa316019047f053c55f1b94f63b17c043 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 5 Jan 2007 20:16:23 +0000 Subject: [PATCH] Remove old pass manager. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32927 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Pass.h | 39 +- include/llvm/PassAnalysisSupport.h | 36 +- include/llvm/PassManager.h | 68 --- lib/VMCore/Pass.cpp | 175 ------ lib/VMCore/PassManager.cpp | 3 +- lib/VMCore/PassManagerT.h | 922 ----------------------------- 6 files changed, 5 insertions(+), 1238 deletions(-) diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index e70dfc1c9ab..6ecaf06057d 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -36,9 +36,6 @@ #include #include -//Use new Pass Manager. Disable old Pass Manager. -//#define USE_OLD_PASSMANAGER 1 - namespace llvm { class Value; @@ -52,7 +49,6 @@ template class PassManagerT; class BasicBlockPassManager; class FunctionPassManagerT; class ModulePassManager; -struct AnalysisResolver; class AnalysisResolver_New; // AnalysisID - Use the PassInfo to identify a pass... @@ -64,8 +60,6 @@ typedef const PassInfo* AnalysisID; /// constrained passes described below. /// class Pass { - friend struct AnalysisResolver; - AnalysisResolver *Resolver; // AnalysisResolver this pass is owned by... AnalysisResolver_New *Resolver_New; // Used to resolve analysis const PassInfo *PassInfoCache; @@ -77,7 +71,7 @@ class Pass { void operator=(const Pass&); // DO NOT IMPLEMENT Pass(const Pass &); // DO NOT IMPLEMENT public: - Pass() : Resolver(0), Resolver_New(0), PassInfoCache(0) {} + Pass() : Resolver_New(0), PassInfoCache(0) {} virtual ~Pass() {} // Destructor is virtual so we can be subclassed /// getPassName - Return a nice clean name for a pass. This usually @@ -204,12 +198,8 @@ public: virtual bool runPass(Module &M) { return runOnModule(M); } virtual bool runPass(BasicBlock&) { return false; } -#ifdef USE_OLD_PASSMANAGER - virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); -#else // Force out-of-line virtual method. virtual ~ModulePass(); -#endif }; @@ -232,15 +222,8 @@ public: /// virtual bool runOnModule(Module &M) { return false; } -#ifdef USE_OLD_PASSMANAGER -private: - template friend class PassManagerT; - friend class ModulePassManager; - virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); -#else // Force out-of-line virtual method. virtual ~ImmutablePass(); -#endif }; //===----------------------------------------------------------------------===// @@ -280,15 +263,6 @@ public: /// bool run(Function &F); -#ifdef USE_OLD_PASSMANAGER -protected: - 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); -#endif }; @@ -342,17 +316,6 @@ public: virtual bool runPass(Module &M) { return false; } virtual bool runPass(BasicBlock &BB); -#ifdef USE_OLD_PASSMANAGER -private: - template friend class PassManagerT; - friend class FunctionPassManagerT; - friend class BasicBlockPassManager; - virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { - FunctionPass::addToPassManager(PM, AU); - } - virtual void addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU); - virtual void addToPassManager(BasicBlockPassManager *PM,AnalysisUsage &AU); -#endif }; /// If the user specifies the -time-passes argument on an LLVM tool command line diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index 7dbaa893695..f591400d272 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -175,8 +175,6 @@ struct AnalysisResolver { void startPass(Pass *P) {} void endPass(Pass *P) {} -protected: - void setAnalysisResolver(Pass *P, AnalysisResolver *AR); }; /// getAnalysisToUpdate() - This function is used by subclasses @@ -189,19 +187,12 @@ protected: /// template AnalysisType *Pass::getAnalysisToUpdate() const { -#ifdef USE_OLD_PASSMANAGER - assert(Resolver && "Pass not resident in a PassManager object!"); -#else assert(Resolver_New && "Pass not resident in a PassManager object!"); -#endif + const PassInfo *PI = getClassPassInfo(); if (PI == 0) return 0; -#ifdef USE_OLD_PASSMANAGER - return dynamic_cast(Resolver->getAnalysisToUpdate(PI)); -#else return dynamic_cast (Resolver_New->getAnalysisToUpdate(PI, true)); -#endif } /// getAnalysis() - This function is used by subclasses to get @@ -210,34 +201,14 @@ AnalysisType *Pass::getAnalysisToUpdate() const { /// template AnalysisType &Pass::getAnalysis() const { -#ifdef USE_OLD_PASSMANAGER - assert(Resolver && "Pass has not been inserted into a PassManager object!"); -#else - assert(Resolver_New&&"Pass has not been inserted into a PassManager object!"); -#endif + assert(Resolver_New &&"Pass has not been inserted into a PassManager object!"); + return getAnalysisID(getClassPassInfo()); } template AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const { assert(PI && "getAnalysis for unregistered pass!"); -#ifdef USE_OLD_PASSMANAGER - assert(Resolver && "Pass has not been inserted into a PassManager object!"); - - // PI *must* appear in AnalysisImpls. Because the number of passes used - // should be a small number, we just do a linear search over a (dense) - // vector. - Pass *ResultPass = 0; - for (unsigned i = 0; ; ++i) { - assert(i != AnalysisImpls.size() && - "getAnalysis*() called on an analysis that was not " - "'required' by pass!"); - if (AnalysisImpls[i].first == PI) { - ResultPass = AnalysisImpls[i].second; - break; - } - } -#else assert(Resolver_New&&"Pass has not been inserted into a PassManager object!"); // PI *must* appear in AnalysisImpls. Because the number of passes used // should be a small number, we just do a linear search over a (dense) @@ -247,7 +218,6 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const { "getAnalysis*() called on an analysis that was not " "'required' by pass!"); -#endif // Because the AnalysisType may not be a subclass of pass (for // AnalysisGroups), we must use dynamic_cast here to potentially adjust the // return pointer (because the class may multiply inherit, once from pass, diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h index 21ef01698f4..f1178e07d3b 100644 --- a/include/llvm/PassManager.h +++ b/include/llvm/PassManager.h @@ -26,72 +26,6 @@ class ModulePass; class Module; class ModuleProvider; -#ifdef USE_OLD_PASSMANAGER - -class ModulePassManager; -class FunctionPassManagerT; -class BasicBlockPassManager; - -class PassManager { - ModulePassManager *PM; // This is a straightforward Pimpl class -public: - PassManager(); - ~PassManager(); - - /// add - Add a pass to the queue of passes to run. This passes ownership of - /// the Pass to the PassManager. When the PassManager is destroyed, the pass - /// will be destroyed as well, so there is no need to delete the pass. This - /// implies that all passes MUST be allocated with 'new'. - /// - void add(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 run(Module &M); -}; - -class FunctionPass; -class ImmutablePass; -class Function; - -class FunctionPassManager { - FunctionPassManagerT *PM; // This is a straightforward Pimpl class - ModuleProvider *MP; -public: - FunctionPassManager(ModuleProvider *P); - ~FunctionPassManager(); - - /// add - Add a pass to the queue of passes to run. This passes - /// ownership of the FunctionPass to the PassManager. When the - /// PassManager is destroyed, the pass will be destroyed as well, so - /// there is no need to delete the pass. This implies that all - /// passes MUST be allocated with 'new'. - /// - void add(FunctionPass *P); - - /// add - ImmutablePasses are not FunctionPasses, so we have a - /// special hack to get them into a FunctionPassManager. - /// - void add(ImmutablePass *IP); - - /// doInitialization - Run all of the initializers for the function passes. - /// - bool doInitialization(); - - /// run - Execute all of the passes scheduled for execution. Keep - /// track of whether any of the passes modifies the function, and if - /// so, return true. - /// - bool run(Function &F); - - /// doFinalization - Run all of the initializers for the function passes. - /// - bool doFinalization(); -}; - -#else - class ModulePassManager; class PassManagerImpl; class FunctionPassManagerImpl; @@ -155,8 +89,6 @@ private: ModuleProvider *MP; }; -#endif - } // End llvm namespace #endif diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index a3c3d7aa818..56e3acb99e6 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -14,9 +14,6 @@ //===----------------------------------------------------------------------===// #include "llvm/PassManager.h" -#ifdef USE_OLD_PASSMANAGER -#include "PassManagerT.h" // PassManagerT implementation -#endif #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/ADT/STLExtras.h" @@ -31,157 +28,16 @@ using namespace llvm; AnalysisResolver::~AnalysisResolver() { } -void AnalysisResolver::setAnalysisResolver(Pass *P, AnalysisResolver *AR) { - assert(P->Resolver == 0 && "Pass already in a PassManager!"); - P->Resolver = AR; -} - -#ifdef USE_OLD_PASSMANAGER -//===----------------------------------------------------------------------===// -// PassManager implementation - The PassManager class is a simple Pimpl class -// that wraps the PassManagerT template. -// -PassManager::PassManager() : PM(new ModulePassManager()) {} -PassManager::~PassManager() { delete PM; } -void PassManager::add(Pass *P) { - ModulePass *MP = dynamic_cast(P); - assert(MP && "Not a modulepass?"); - PM->add(MP); -} -bool PassManager::run(Module &M) { return PM->runOnModule(M); } - -//===----------------------------------------------------------------------===// -// FunctionPassManager implementation - The FunctionPassManager class -// is a simple Pimpl class that wraps the PassManagerT template. It -// is like PassManager, but only deals in FunctionPasses. -// -FunctionPassManager::FunctionPassManager(ModuleProvider *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); } - -/// doInitialization - Run all of the initializers for the function passes. -/// -bool FunctionPassManager::doInitialization() { - return PM->doInitialization(*MP->getModule()); -} - -bool FunctionPassManager::run(Function &F) { - std::string errstr; - if (MP->materializeFunction(&F, &errstr)) { - cerr << "Error reading bytecode file: " << errstr << "\n"; - abort(); - } - return PM->runOnFunction(F); -} - -/// doFinalization - Run all of the initializers for the function passes. -/// -bool FunctionPassManager::doFinalization() { - return PM->doFinalization(*MP->getModule()); -} - - -//===----------------------------------------------------------------------===// -// TimingInfo Class - This class is used to calculate information about the -// amount of time each pass takes to execute. This only happens with -// -time-passes is enabled on the command line. -// -bool llvm::TimePassesIsEnabled = false; -static cl::opt -EnableTiming("time-passes", cl::location(TimePassesIsEnabled), - cl::desc("Time each pass, printing elapsed time for each on exit")); - -// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to -// a non null value (if the -time-passes option is enabled) or it leaves it -// null. It may be called multiple times. -void TimingInfo::createTheTimeInfo() { - if (!TimePassesIsEnabled || TheTimeInfo) return; - - // Constructed the first time this is called, iff -time-passes is enabled. - // This guarantees that the object will be constructed before static globals, - // thus it will be destroyed before them. - static ManagedStatic TTI; - TheTimeInfo = &*TTI; -} - -void PMDebug::PrintArgumentInformation(const Pass *P) { - // Print out passes in pass manager... - if (const AnalysisResolver *PM = dynamic_cast(P)) { - for (unsigned i = 0, e = PM->getNumContainedPasses(); i != e; ++i) - PrintArgumentInformation(PM->getContainedPass(i)); - - } else { // Normal pass. Print argument information... - // Print out arguments for registered passes that are _optimizations_ - if (const PassInfo *PI = P->getPassInfo()) - if (!PI->isAnalysisGroup()) - cerr << " -" << PI->getPassArgument(); - } -} - -void PMDebug::PrintPassInformation(unsigned Depth, const char *Action, - Pass *P, Module *M) { - if (PassDebugging >= Executions) { - cerr << (void*)P << std::string(Depth*2+1, ' ') << Action << " '" - << P->getPassName(); - if (M) cerr << "' on Module '" << M->getModuleIdentifier() << "'\n"; - cerr << "'...\n"; - } -} - -void PMDebug::PrintPassInformation(unsigned Depth, const char *Action, - Pass *P, Function *F) { - if (PassDebugging >= Executions) { - cerr << (void*)P << std::string(Depth*2+1, ' ') << Action << " '" - << P->getPassName(); - if (F) cerr << "' on Function '" << F->getName(); - cerr << "'...\n"; - } -} - -void PMDebug::PrintPassInformation(unsigned Depth, const char *Action, - Pass *P, BasicBlock *BB) { - if (PassDebugging >= Executions) { - cerr << (void*)P << std::string(Depth*2+1, ' ') << Action << " '" - << P->getPassName(); - if (BB) cerr << "' on BasicBlock '" << BB->getName(); - cerr << "'...\n"; - } -} - -void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg, - Pass *P, const std::vector &Set){ - if (PassDebugging >= Details && !Set.empty()) { - cerr << (void*)P << std::string(Depth*2+3, ' ') << Msg << " Analyses:"; - for (unsigned i = 0; i != Set.size(); ++i) { - if (i) cerr << ","; - cerr << " " << Set[i]->getPassName(); - } - cerr << "\n"; - } -} -#endif //===----------------------------------------------------------------------===// // Pass Implementation // -#ifdef USE_OLD_PASSMANAGER -void ModulePass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { - PM->addPass(this, AU); -} -#else // Force out-of-line virtual method. ModulePass::~ModulePass() { } -#endif bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const { -#ifdef USE_OLD_PASSMANAGER - return Resolver->getAnalysisToUpdate(AnalysisID) != 0; -#else return Resolver_New->getAnalysisToUpdate(AnalysisID, true) != 0; -#endif } // dumpPassStructure - Implement the -debug-passes=Structure option @@ -213,15 +69,8 @@ void Pass::dump() const { //===----------------------------------------------------------------------===// // ImmutablePass Implementation // -#ifdef USE_OLD_PASSMANAGER -void ImmutablePass::addToPassManager(ModulePassManager *PM, - AnalysisUsage &AU) { - PM->addPass(this, AU); -} -#else // Force out-of-line virtual method. ImmutablePass::~ImmutablePass() { } -#endif //===----------------------------------------------------------------------===// // FunctionPass Implementation @@ -250,18 +99,6 @@ bool FunctionPass::run(Function &F) { return Changed | doFinalization(*F.getParent()); } -#ifdef USE_OLD_PASSMANAGER -void FunctionPass::addToPassManager(ModulePassManager *PM, - AnalysisUsage &AU) { - PM->addPass(this, AU); -} - -void FunctionPass::addToPassManager(FunctionPassManagerT *PM, - AnalysisUsage &AU) { - PM->addPass(this, AU); -} -#endif - //===----------------------------------------------------------------------===// // BasicBlockPass Implementation // @@ -290,18 +127,6 @@ bool BasicBlockPass::runPass(BasicBlock &BB) { return Changed; } -#ifdef USE_OLD_PASSMANAGER -void BasicBlockPass::addToPassManager(FunctionPassManagerT *PM, - AnalysisUsage &AU) { - PM->addPass(this, AU); -} - -void BasicBlockPass::addToPassManager(BasicBlockPassManager *PM, - AnalysisUsage &AU) { - PM->addPass(this, AU); -} -#endif - //===----------------------------------------------------------------------===// // Pass Registration mechanism // diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 3d3858e4a4d..628d89933f9 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -118,7 +118,6 @@ PassDebugging_New("debug-pass", cl::Hidden, clEnumValEnd)); } // End of llvm namespace -#ifndef USE_OLD_PASSMANAGER namespace { //===----------------------------------------------------------------------===// @@ -1602,4 +1601,4 @@ void TimingInfo::createTheTimeInfo() { TheTimeInfo = &*TTI; } -#endif + diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index 68376e57373..e69de29bb2d 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -1,922 +0,0 @@ -//===- PassManagerT.h - Container for Passes --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PassManagerT class. This class is used to hold, -// maintain, and optimize execution of Pass's. The PassManager class ensures -// that analysis results are available before a pass runs, and that Pass's are -// destroyed when the PassManager is destroyed. -// -// The PassManagerT template is instantiated three times to do its job. The -// public PassManager class is a Pimpl around the PassManagerT interface -// to avoid having all of the PassManager clients being exposed to the -// implementation details herein. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PASSMANAGER_T_H -#define LLVM_PASSMANAGER_T_H - -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/LeakDetector.h" -#include "llvm/Support/Timer.h" -#include - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Pass debugging information. Often it is useful to find out what pass is -// running when a crash occurs in a utility. When this library is compiled with -// debugging on, a command line option (--debug-pass) is enabled that causes the -// pass name to be printed before it executes. -// - -// Different debug levels that can be enabled... -enum PassDebugLevel { - None, Arguments, Structure, Executions, Details -}; - -static cl::opt -PassDebugging("debug-pass", cl::Hidden, - cl::desc("Print PassManager debugging information"), - cl::values( - clEnumVal(None , "disable debug output"), - clEnumVal(Arguments , "print pass arguments to pass to 'opt'"), - clEnumVal(Structure , "print pass structure before run()"), - clEnumVal(Executions, "print pass name before it is executed"), - clEnumVal(Details , "print pass details when it is executed"), - clEnumValEnd)); - -//===----------------------------------------------------------------------===// -// PMDebug class - a set of debugging functions, that are not to be -// instantiated by the template. -// -struct PMDebug { - static void PerformPassStartupStuff(Pass *P) { - // If debugging is enabled, print out argument information... - if (PassDebugging >= Arguments) { - cerr << "Pass Arguments: "; - PrintArgumentInformation(P); - cerr << "\n"; - - // Print the pass execution structure - if (PassDebugging >= Structure) - P->dumpPassStructure(); - } - } - - static void PrintArgumentInformation(const Pass *P); - static void PrintPassInformation(unsigned,const char*,Pass *, Module *); - static void PrintPassInformation(unsigned,const char*,Pass *, Function *); - static void PrintPassInformation(unsigned,const char*,Pass *, BasicBlock *); - static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P, - const std::vector &); -}; - - -//===----------------------------------------------------------------------===// -// TimingInfo Class - This class is used to calculate information about the -// amount of time each pass takes to execute. This only happens when -// -time-passes is enabled on the command line. -// - -class TimingInfo { - std::map TimingData; - TimerGroup TG; - -public: - // Use 'create' member to get this. - TimingInfo() : TG("... Pass execution timing report ...") {} - - // TimingDtor - Print out information about timing information - ~TimingInfo() { - // Delete all of the timers... - TimingData.clear(); - // TimerGroup is deleted next, printing the report. - } - - // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non null value (if the -time-passes option is enabled) or it leaves it - // null. It may be called multiple times. - static void createTheTimeInfo(); - - void passStarted(Pass *P) { - if (dynamic_cast(P)) return; - std::map::iterator I = TimingData.find(P); - if (I == TimingData.end()) - I=TimingData.insert(std::make_pair(P, Timer(P->getPassName(), TG))).first; - I->second.startTimer(); - } - void passEnded(Pass *P) { - if (dynamic_cast(P)) return; - std::map::iterator I = TimingData.find(P); - assert (I != TimingData.end() && "passStarted/passEnded not nested right!"); - I->second.stopTimer(); - } -}; - -static TimingInfo *TheTimeInfo; - -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 BasicBlockPassManager, 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; -}; - - -//===----------------------------------------------------------------------===// -// PassManagerT - Container object for passes. The PassManagerT destructor -// 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 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 ImmutablePasses; // List of immutable passes - - // The parent of this pass manager... - ParentClass * const Parent; - - // The current batcher if one is in use, or null - BatcherClass *Batcher; - - // CurrentAnalyses - As the passes are being run, this map contains the - // analyses that are available to the current pass for use. This is accessed - // through the getAnalysis() function in this class and in Pass. - // - std::map CurrentAnalyses; - - // LastUseOf - This map keeps track of the last usage in our pipeline of a - // particular pass. When executing passes, the memory for .first is free'd - // after .second is run. - // - 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... - for (typename std::vector::iterator - I = Passes.begin(), E = Passes.end(); I != E; ++I) - delete *I; - - for (std::vector::iterator - I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - delete *I; - } - - // run - Run all of the queued passes on the specified module in an optimal - // way. - virtual bool runOnUnit(UnitType *M) { - closeBatcher(); - CurrentAnalyses.clear(); - - TimingInfo::createTheTimeInfo(); - - addImmutablePasses(); - - // LastUserOf - This contains the inverted LastUseOfMap... - std::map > LastUserOf; - for (std::map::iterator I = LastUseOf.begin(), - E = LastUseOf.end(); I != E; ++I) - LastUserOf[I->second].push_back(I->first); - - // Output debug information... - assert(dynamic_cast(this) && - "It wasn't the PassClass I thought it was"); - if (Parent == 0) - PMDebug::PerformPassStartupStuff((dynamic_cast(this))); - - return runPasses(M, LastUserOf); - } - - // dumpPassStructure - Implement the -debug-passes=Structure option - inline void dumpPassStructure(unsigned Offset = 0) { - // Print out the immutable passes... - - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) - ImmutablePasses[i]->dumpPassStructure(0); - - cerr << std::string(Offset*2, ' ') << this->getPMName() - << " Pass Manager\n"; - for (typename std::vector::iterator - I = Passes.begin(), E = Passes.end(); I != E; ++I) { - PassClass *P = *I; - P->dumpPassStructure(Offset+1); - - // Loop through and see which classes are destroyed after this one... - for (std::map::iterator I = LastUseOf.begin(), - E = LastUseOf.end(); I != E; ++I) { - if (P == I->second) { - cerr << "--" << std::string(Offset*2, ' '); - I->first->dumpPassStructure(0); - } - } - } - } - - Pass *getImmutablePassOrNull(const PassInfo *ID) const { - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { - const PassInfo *IPID = ImmutablePasses[i]->getPassInfo(); - if (IPID == ID) - return ImmutablePasses[i]; - - // This pass is the current implementation of all of the interfaces it - // implements as well. - // - const std::vector &II = - IPID->getInterfacesImplemented(); - for (unsigned j = 0, e = II.size(); j != e; ++j) - if (II[j] == ID) return ImmutablePasses[i]; - } - return 0; - } - - Pass *getAnalysisOrNullDown(const PassInfo *ID) const { - std::map::const_iterator I = CurrentAnalyses.find(ID); - - if (I != CurrentAnalyses.end()) - return I->second; // Found it. - - if (Pass *P = getImmutablePassOrNull(ID)) - return P; - - if (Batcher) - return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); - return 0; - } - - Pass *getAnalysisOrNullUp(const PassInfo *ID) const { - std::map::const_iterator I = CurrentAnalyses.find(ID); - if (I != CurrentAnalyses.end()) - return I->second; // Found it. - - if (Parent) // Try scanning... - return Parent->getAnalysisOrNullUp(ID); - else if (!ImmutablePasses.empty()) - return getImmutablePassOrNull(ID); - return 0; - } - - // markPassUsed - Inform higher level pass managers (and ourselves) - // that these analyses are being used by this pass. This is used to - // make sure that analyses are not free'd before we have to use - // them... - // - void markPassUsed(const PassInfo *P, Pass *User) { - std::map::const_iterator I = CurrentAnalyses.find(P); - - if (I != CurrentAnalyses.end()) { - LastUseOf[I->second] = User; // Local pass, extend the lifetime - - // Prolong live range of analyses that are needed after an analysis pass - // is destroyed, for querying by subsequent passes - AnalysisUsage AnUsage; - I->second->getAnalysisUsage(AnUsage); - const std::vector &IDs = AnUsage.getRequiredTransitiveSet(); - for (std::vector::const_iterator i = IDs.begin(), - e = IDs.end(); i != e; ++i) - markPassUsed(*i, User); - - } else { - // Pass not in current available set, must be a higher level pass - // available to us, propagate to parent pass manager... We tell the - // parent that we (the passmanager) are using the analysis so that it - // frees the analysis AFTER this pass manager runs. - // - if (Parent) { - assert(dynamic_cast(this) && - "It wasn't the Pass type I thought it was."); - Parent->markPassUsed(P, dynamic_cast(this)); - } else { - assert(getAnalysisOrNullUp(P) && - dynamic_cast(getAnalysisOrNullUp(P)) && - "Pass available but not found! " - "Perhaps this is a module pass requiring a function pass?"); - } - } - } - - // Return the number of parent PassManagers that exist - virtual unsigned getDepth() const { - if (Parent == 0) return 0; - return 1 + Parent->getDepth(); - } - - virtual unsigned getNumContainedPasses() const { return Passes.size(); } - - virtual const Pass *getContainedPass(unsigned N) const { - assert(N < Passes.size() && "Pass number out of range!"); - return Passes[N]; - } - - // add - Add a pass to the queue of passes to run. This gives ownership of - // the Pass to the PassManager. When the PassManager is destroyed, the pass - // will be destroyed as well, so there is no need to delete the pass. This - // implies that all passes MUST be new'd. - // - void add(PassClass *P) { - // Get information about what analyses the pass uses... - AnalysisUsage AnUsage; - P->getAnalysisUsage(AnUsage); - - addRequiredPasses(AnUsage.getRequiredSet()); - - // Tell the pass to add itself to this PassManager... the way it does so - // depends on the class of the pass, and is critical to laying out passes in - // an optimal order.. - // - assert(dynamic_cast(this) && - "It wasn't the right passmanager type."); - P->addToPassManager(static_cast(this), AnUsage); - } - - // add - H4x0r an ImmutablePass into a PassManager that might not be - // expecting one. - // - void add(ImmutablePass *P) { - // Get information about what analyses the pass uses... - AnalysisUsage AnUsage; - P->getAnalysisUsage(AnUsage); - - addRequiredPasses(AnUsage.getRequiredSet()); - - // Add the ImmutablePass to this PassManager. - addPass(P, AnUsage); - } - -private: - // addPass - These functions are used to implement the subclass specific - // behaviors present in PassManager. Basically the add(Pass*) method ends up - // reflecting its behavior into a Pass::addToPassManager call. Subclasses of - // Pass override it specifically so that they can reflect the type - // information inherent in "this" back to the PassManager. - // - // For generic Pass subclasses (which are interprocedural passes), we simply - // add the pass to the end of the pass list and terminate any accumulation of - // FunctionPass's that are present. - // - void addPass(PassClass *P, AnalysisUsage &AnUsage) { - const std::vector &RequiredSet = AnUsage.getRequiredSet(); - - // FIXME: If this pass being added isn't killed by any of the passes in the - // batcher class then we can reorder the pass to execute before the batcher - // does, which will potentially allow us to batch more passes! - // - if (Batcher) - closeBatcher(); // This pass cannot be batched! - - // Set the Resolver instance variable in the Pass so that it knows where to - // find this object... - // - setAnalysisResolver(P, this); - Passes.push_back(P); - - // Inform higher level pass managers (and ourselves) that these analyses are - // being used by this pass. This is used to make sure that analyses are not - // free'd before we have to use them... - // - for (std::vector::const_iterator I = RequiredSet.begin(), - E = RequiredSet.end(); I != E; ++I) - markPassUsed(*I, P); // Mark *I as used by P - - removeNonPreservedAnalyses(AnUsage); - - makeCurrentlyAvailable(P); - - // 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. - assert(dynamic_cast(this) && - "It wasn't the PassManager type I thought it was"); - Batcher = new BatcherClass((static_cast(this))); - } - - // The Batcher will queue the passes up - MP->addToPassManager(Batcher, AnUsage); - } - - // closeBatcher - Terminate the batcher that is being worked on. - void closeBatcher() { - if (Batcher) { - Passes.push_back(Batcher); - Batcher = 0; - } - } - - void addRequiredPasses(const std::vector &Required) { - for (std::vector::const_iterator I = Required.begin(), - E = Required.end(); I != E; ++I) { - if (getAnalysisOrNullDown(*I) == 0) { - Pass *AP = (*I)->createPass(); - if (ImmutablePass *IP = dynamic_cast (AP)) add(IP); - else if (PassClass *RP = dynamic_cast (AP)) add(RP); - else assert (0 && "Wrong kind of pass for this PassManager"); - } - } - } - -public: - // When an ImmutablePass is added, it gets added to the top level pass - // manager. - void addPass(ImmutablePass *IP, AnalysisUsage &AU) { - if (Parent) { // Make sure this request goes to the top level passmanager... - Parent->addPass(IP, AU); - return; - } - - // Set the Resolver instance variable in the Pass so that it knows where to - // find this object... - // - setAnalysisResolver(IP, this); - ImmutablePasses.push_back(IP); - - // All Required analyses should be available to the pass as it initializes! - // Here we fill in the AnalysisImpls member of the pass so that it can - // successfully use the getAnalysis() method to retrieve the implementations - // it needs. - // - IP->AnalysisImpls.clear(); - IP->AnalysisImpls.reserve(AU.getRequiredSet().size()); - for (std::vector::const_iterator - I = AU.getRequiredSet().begin(), - E = AU.getRequiredSet().end(); I != E; ++I) { - Pass *Impl = getAnalysisOrNullUp(*I); - if (Impl == 0) { - cerr << "Analysis '" << (*I)->getPassName() - << "' used but not available!"; - assert(0 && "Analysis used but not available!"); - } else if (PassDebugging == Details) { - if ((*I)->getPassName() != std::string(Impl->getPassName())) - cerr << " Interface '" << (*I)->getPassName() - << "' implemented by '" << Impl->getPassName() << "'\n"; - } - IP->AnalysisImpls.push_back(std::make_pair(*I, Impl)); - } - - // Initialize the immutable pass... - IP->initializePass(); - } -private: - - // Add any immutable passes to the CurrentAnalyses set... - inline void addImmutablePasses() { - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { - ImmutablePass *IPass = ImmutablePasses[i]; - if (const PassInfo *PI = IPass->getPassInfo()) { - CurrentAnalyses[PI] = IPass; - - const std::vector &II = PI->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) - CurrentAnalyses[II[i]] = IPass; - } - } - } - - // Run all of the passes - inline bool runPasses(UnitType *M, - std::map > &LastUserOf) { - bool MadeChanges = false; - - for (unsigned i = 0, e = Passes.size(); i < e; ++i) { - PassClass *P = Passes[i]; - - PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, M); - - // Get information about what analyses the pass uses... - AnalysisUsage AnUsage; - P->getAnalysisUsage(AnUsage); - PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P, - AnUsage.getRequiredSet()); - - initialiseAnalysisImpl(P, AnUsage); - - // Run the sub pass! - if (TheTimeInfo) TheTimeInfo->passStarted(P); - bool Changed = runPass(P, M); - if (TheTimeInfo) TheTimeInfo->passEnded(P); - MadeChanges |= Changed; - - // Check for memory leaks by the pass... - LeakDetector::checkForGarbage(std::string("after running pass '") + - P->getPassName() + "'"); - - if (Changed) - PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P, M); - PMDebug::PrintAnalysisSetInfo(getDepth(), "Preserved", P, - AnUsage.getPreservedSet()); - - // Erase all analyses not in the preserved set - removeNonPreservedAnalyses(AnUsage); - - makeCurrentlyAvailable(P); - - // free memory and remove dead passes from the CurrentAnalyses list... - removeDeadPasses(P, M, LastUserOf); - } - - return MadeChanges; - } - - // All Required analyses should be available to the pass as it runs! Here - // we fill in the AnalysisImpls member of the pass so that it can - // successfully use the getAnalysis() method to retrieve the - // implementations it needs. - // - inline void initialiseAnalysisImpl(PassClass *P, AnalysisUsage &AnUsage) { - P->AnalysisImpls.clear(); - P->AnalysisImpls.reserve(AnUsage.getRequiredSet().size()); - - for (std::vector::const_iterator - I = AnUsage.getRequiredSet().begin(), - E = AnUsage.getRequiredSet().end(); I != E; ++I) { - Pass *Impl = getAnalysisOrNullUp(*I); - if (Impl == 0) { - cerr << "Analysis '" << (*I)->getPassName() - << "' used but not available!"; - assert(0 && "Analysis used but not available!"); - } else if (PassDebugging == Details) { - if ((*I)->getPassName() != std::string(Impl->getPassName())) - cerr << " Interface '" << (*I)->getPassName() - << "' implemented by '" << Impl->getPassName() << "'\n"; - } - - P->AnalysisImpls.push_back(std::make_pair(*I, Impl)); - } - } - - inline void removeNonPreservedAnalyses(AnalysisUsage &AnUsage) { - if (!AnUsage.getPreservesAll()) { - const std::vector &PreservedSet = AnUsage.getPreservedSet(); - for (std::map::iterator I = CurrentAnalyses.begin(), - E = CurrentAnalyses.end(); I != E; ) - if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) != - PreservedSet.end()) - ++I; // This analysis is preserved, leave it in the available set... - else { - if (!dynamic_cast(I->second)) { - std::map::iterator J = I++; - CurrentAnalyses.erase(J); // Analysis not preserved! - } else { - ++I; - } - } - } - } - - inline void removeDeadPasses(Pass* P, UnitType *M, - std::map > &LastUserOf) { - std::vector &DeadPass = LastUserOf[P]; - for (std::vector::iterator I = DeadPass.begin(),E = DeadPass.end(); - I != E; ++I) { - PMDebug::PrintPassInformation(getDepth()+1, "Freeing Pass", *I, M); - if (TheTimeInfo) TheTimeInfo->passStarted(*I); - (*I)->releaseMemory(); - if (TheTimeInfo) TheTimeInfo->passEnded(*I); - } - - for (std::map::iterator I = CurrentAnalyses.begin(); - I != CurrentAnalyses.end(); ) { - std::vector::iterator DPI = std::find(DeadPass.begin(), - DeadPass.end(), I->second); - if (DPI != DeadPass.end()) { // This pass is dead now... remove it - std::map::iterator IDead = I++; - CurrentAnalyses.erase(IDead); - } else { - ++I; // Move on to the next element... - } - } - } - - inline void makeCurrentlyAvailable(Pass* P) { - if (const PassInfo *PI = P->getPassInfo()) { - CurrentAnalyses[PI] = P; - - // This pass is the current implementation of all of the interfaces it - // implements as well. - // - const std::vector &II = PI->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) - CurrentAnalyses[II[i]] = P; - } - } -}; - - - -//===----------------------------------------------------------------------===// -// BasicBlockPassManager -// -// This pass manager is used to group together all of the BasicBlockPass's -// into a single unit. -// -class BasicBlockPassManager : public BasicBlockPass, - public BBTraits, - public PassManagerT { -public: - BasicBlockPassManager(BBTraits::ParentClass* PC) : - PassManagerT(PC) { - } - - BasicBlockPassManager(BasicBlockPassManager* BBPM) : - PassManagerT(BBPM->Parent) { - } - - virtual bool runPass(Module &M) { return false; } - - virtual bool runPass(BasicBlock &BB) { return BasicBlockPass::runPass(BB); } - - // runPass - Specify how the pass should be run on the UnitType - virtual bool runPass(BBTraits::PassClass *P, BasicBlock *M) { - // TODO: init and finalize - return P->runOnBasicBlock(*M); - } - - virtual ~BasicBlockPassManager() {} - - virtual void dumpPassStructure(unsigned Offset = 0) { - PassManagerT::dumpPassStructure(Offset); - } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - virtual const char *getPMName() const { return "BasicBlock"; } - - virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } - - virtual bool doInitialization(Module &M); - virtual bool doInitialization(Function &F); - virtual bool runOnBasicBlock(BasicBlock &BB); - virtual bool doFinalization(Function &F); - virtual bool doFinalization(Module &M); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } -}; - -//===----------------------------------------------------------------------===// -// FunctionPassManager -// -// This pass manager is used to group together all of the FunctionPass's -// into a single unit. -// -class FunctionPassManagerT : public FunctionPass, - public FTraits, - public PassManagerT { -public: - FunctionPassManagerT() : PassManagerT(0) {} - - // Parent constructor - FunctionPassManagerT(FTraits::ParentClass* PC) : PassManagerT(PC) {} - - FunctionPassManagerT(FunctionPassManagerT* FPM) : - PassManagerT(FPM->Parent) { - } - - virtual ~FunctionPassManagerT() {} - - virtual void dumpPassStructure(unsigned Offset = 0) { - PassManagerT::dumpPassStructure(Offset); - } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - virtual const char *getPMName() const { return "Function"; } - - virtual const char *getPassName() const { return "Function Pass Manager"; } - - virtual bool runOnFunction(Function &F); - - virtual bool doInitialization(Module &M); - - virtual bool doFinalization(Module &M); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - - virtual bool runPass(Module &M) { return FunctionPass::runPass(M); } - virtual bool runPass(BasicBlock &BB) { return FunctionPass::runPass(BB); } - - // runPass - Specify how the pass should be run on the UnitType - virtual bool runPass(FTraits::PassClass *P, Function *F) { - return P->runOnFunction(*F); - } -}; - - -//===----------------------------------------------------------------------===// -// ModulePassManager -// -// This is the top level PassManager implementation that holds generic passes. -// -class ModulePassManager : public ModulePass, - public MTraits, - public PassManagerT { -public: - ModulePassManager() : PassManagerT(0) {} - - // Batcher Constructor - ModulePassManager(MTraits::ParentClass* PC) : PassManagerT(PC) {} - - ModulePassManager(ModulePassManager* MPM) : - PassManagerT((MPM->Parent)) { - } - - virtual ~ModulePassManager() {} - - virtual void dumpPassStructure(unsigned Offset = 0) { - PassManagerT::dumpPassStructure(Offset); - } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - virtual const char *getPassName() const { return "Module Pass Manager"; } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - virtual const char *getPMName() const { return "Module"; } - - // runOnModule - Implement the PassManager interface. - virtual bool runOnModule(Module &M); - - virtual bool runPass(Module &M) { return ModulePass::runPass(M); } - virtual bool runPass(BasicBlock &BB) { return ModulePass::runPass(BB); } - - // runPass - Specify how the pass should be run on the UnitType - virtual bool runPass(MTraits::PassClass *P, Module *M) { - return P->runOnModule(*M); - } -}; - -//===----------------------------------------------------------------------===// -// PassManager Method Implementations -// - -// BasicBlockPassManager Implementations -// - -inline bool BasicBlockPassManager::runOnBasicBlock(BasicBlock &BB) { - return ((BBTraits::PMType*)this)->runOnUnit(&BB); -} - -inline bool BasicBlockPassManager::doInitialization(Module &M) { - bool Changed = false; - 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 =((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 =((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 = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) - ((BBTraits::PMType*)this)->Passes[i]->doFinalization(M); - return Changed; -} - -// FunctionPassManagerT Implementations -// - -inline bool FunctionPassManagerT::runOnFunction(Function &F) { - return ((FTraits::PMType*)this)->runOnUnit(&F); -} - -inline bool FunctionPassManagerT::doInitialization(Module &M) { - bool Changed = false; - 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 = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i) - ((FTraits::PMType*)this)->Passes[i]->doFinalization(M); - return Changed; -} - -// ModulePassManager Implementations -// - -bool ModulePassManager::runOnModule(Module &M) { - return ((PassManagerT*)this)->runOnUnit(&M); -} - -} // End llvm namespace - -#endif -- 2.34.1