X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManagerT.h;h=e88693fbfff23cda8d266364da38fae4c7169e5f;hb=d122f4b648571867c0f8f72290b6c1a0aac02ebb;hp=d990d89f5a11f4841937975f27e6cc49c74a88d4;hpb=2bfc0310ff816562bd2f07baa9086258d9ac403b;p=oota-llvm.git diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index d990d89f5a1..e88693fbfff 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -1,42 +1,110 @@ -//===- llvm/PassManager.h - Container for Passes -----------------*- C++ -*--=// +//===- PassManagerT.h - Container for Passes ---------------------*- C++ -*--=// // -// This file defines the PassManager class. This class is used to hold, +// 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 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_H -#define LLVM_PASSMANAGER_H +#ifndef LLVM_PASSMANAGER_T_H +#define LLVM_PASSMANAGER_T_H #include "llvm/Pass.h" -#include +#include "Support/CommandLine.h" +#include +#include +class Annotable; //===----------------------------------------------------------------------===// -// PMDebug class - a set of debugging functions that are enabled when compiling -// with -g on. If compiling at -O, all functions are inlined noops. +// 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"), + 0)); + +//===----------------------------------------------------------------------===// +// PMDebug class - a set of debugging functions, that are not to be +// instantiated by the template. // struct PMDebug { -#ifdef NDEBUG - inline static void PrintPassStructure(Pass *) {} - inline static void PrintPassInformation(unsigned,const char*,Pass*,Value*) {} - inline static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P, - const Pass::AnalysisSet &) {} -#else - // If compiled in debug mode, these functions can be enabled by setting - // -debug-pass on the command line of the tool being used. - // - static void PrintPassStructure(Pass *P); - static void PrintPassInformation(unsigned,const char*,Pass *, Value *); + static void PerformPassStartupStuff(Pass *P) { + // If debugging is enabled, print out argument information... + if (PassDebugging >= Arguments) { + std::cerr << "Pass Arguments: "; + PrintArgumentInformation(P); + std::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 *, Annotable *); static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P, - const Pass::AnalysisSet&); -#endif + 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. +// +struct TimeRecord { // TimeRecord - Data we collect and print for each pass + double Elapsed; // Wall clock time elapsed in seconds + double UserTime; // User time elapsed + double SystemTime; // System time elapsed + unsigned long MaxRSS; // Maximum resident set size (in bytes) + unsigned long RSSTemp; // Temp for calculating maxrss + + TimeRecord() : Elapsed(0), UserTime(0), SystemTime(0), MaxRSS(0) {} + void passStart(const TimeRecord &T); + void passEnd(const TimeRecord &T); + void sum(const TimeRecord &TR); + bool operator<(const TimeRecord &TR) const; + + void print(const char *PassName, const TimeRecord &TotalTime) const; +}; + +class TimingInfo { + std::map TimingData; + TimingInfo() {} // Private ctor, must use create member +public: + // Create method. If Timing is enabled, this creates and returns a new timing + // object, otherwise it returns null. + // + static TimingInfo *create(); + + // TimingDtor - Print out information about timing information + ~TimingInfo(); + + void passStarted(Pass *P); + void passEnded(Pass *P); +}; //===----------------------------------------------------------------------===// // Declare the PassManagerTraits which will be specialized... @@ -51,17 +119,17 @@ template class PassManagerTraits; // Do not define. // template class PassManagerT : public PassManagerTraits,public AnalysisResolver{ - typedef typename PassManagerTraits::PassClass PassClass; - typedef typename PassManagerTraits::SubPassClass SubPassClass; - typedef typename PassManagerTraits::BatcherClass BatcherClass; - typedef typename PassManagerTraits::ParentClass ParentClass; - typedef PassManagerTraits Traits; + typedef PassManagerTraits Traits; + typedef typename Traits::PassClass PassClass; + typedef typename Traits::SubPassClass SubPassClass; + typedef typename Traits::BatcherClass BatcherClass; + typedef typename Traits::ParentClass ParentClass; - friend typename PassManagerTraits::PassClass; - friend typename PassManagerTraits::SubPassClass; - friend class PassManagerTraits; + friend typename Traits::PassClass; + friend typename Traits::SubPassClass; + friend class Traits; - std::vector Passes; // List of pass's to run + std::vector Passes; // List of passes to run // The parent of this pass manager... ParentClass * const Parent; @@ -85,8 +153,8 @@ public: PassManagerT(ParentClass *Par = 0) : Parent(Par), Batcher(0) {} ~PassManagerT() { // Delete all of the contained passes... - for (std::vector::iterator I = Passes.begin(), E = Passes.end(); - I != E; ++I) + for (typename std::vector::iterator + I = Passes.begin(), E = Passes.end(); I != E; ++I) delete *I; } @@ -105,67 +173,108 @@ public: // Output debug information... - if (Parent == 0) PMDebug::PrintPassStructure(this); + if (Parent == 0) PMDebug::PerformPassStartupStuff(this); // Run all of the passes for (unsigned i = 0, e = Passes.size(); i < e; ++i) { PassClass *P = Passes[i]; - PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, (Value*)M); + PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, + (Annotable*)M); // Get information about what analyses the pass uses... - std::vector Required, Destroyed, Provided; - P->getAnalysisUsageInfo(Required, Destroyed, Provided); - - PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P, Required); - -#ifndef NDEBUG - // All Required analyses should be available to the pass as it runs! - for (Pass::AnalysisSet::iterator I = Required.begin(), - E = Required.end(); I != E; ++I) { - assert(getAnalysisOrNullUp(*I) && "Analysis used but not available!"); + AnalysisUsage AnUsage; + P->getAnalysisUsage(AnUsage); + PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P, + AnUsage.getRequiredSet()); + + // 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. + // + 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) { + std::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())) + std::cerr << " Interface '" << (*I)->getPassName() + << "' implemented by '" << Impl->getPassName() << "'\n"; + } + P->AnalysisImpls.push_back(std::make_pair(*I, Impl)); } -#endif // Run the sub pass! - bool Changed = Traits::runPass(P, M); + startPass(P); + bool Changed = runPass(P, M); + endPass(P); MadeChanges |= Changed; if (Changed) PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P, - (Value*)M); - PMDebug::PrintAnalysisSetInfo(getDepth(), "Destroyed", P, Destroyed); - PMDebug::PrintAnalysisSetInfo(getDepth(), "Provided", P, Provided); - - // Erase all analyses in the destroyed set... - for (Pass::AnalysisSet::iterator I = Destroyed.begin(), - E = Destroyed.end(); I != E; ++I) - CurrentAnalyses.erase(*I); - - // Add all analyses in the provided set... - for (Pass::AnalysisSet::iterator I = Provided.begin(), - E = Provided.end(); I != E; ++I) - CurrentAnalyses[*I] = P; + (Annotable*)M); + PMDebug::PrintAnalysisSetInfo(getDepth(), "Preserved", P, + AnUsage.getPreservedSet()); + + + // Erase all analyses not in the preserved set... + if (!AnUsage.preservesAll()) { + 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 MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER + I = CurrentAnalyses.erase(I); // Analysis not preserved! +#else + // GCC 2.95.3 STL doesn't have correct erase member! + CurrentAnalyses.erase(I); + I = CurrentAnalyses.begin(); +#endif + } + } + + // Add the current pass to the set of passes that have been run, and are + // thus available to users. + // + 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; + } // Free memory for any passes that we are the last use of... 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, - (Value*)M); + (Annotable*)M); (*I)->releaseMemory(); } } return MadeChanges; } -#ifndef NDEBUG // dumpPassStructure - Implement the -debug-passes=PassStructure option virtual void dumpPassStructure(unsigned Offset = 0) { std::cerr << std::string(Offset*2, ' ') << Traits::getPMName() << " Pass Manager\n"; - for (std::vector::iterator I = Passes.begin(), E = Passes.end(); - I != E; ++I) { + for (typename std::vector::iterator + I = Passes.begin(), E = Passes.end(); I != E; ++I) { PassClass *P = *I; P->dumpPassStructure(Offset+1); @@ -173,32 +282,46 @@ public: for (std::map::iterator I = LastUseOf.begin(), E = LastUseOf.end(); I != E; ++I) { if (P == I->second) { - std::cerr << "Fr" << std::string(Offset*2, ' '); + std::cerr << "--" << std::string(Offset*2, ' '); I->first->dumpPassStructure(0); } } } } -#endif - Pass *getAnalysisOrNullDown(AnalysisID ID) const { + Pass *getAnalysisOrNullDown(const PassInfo *ID) const { std::map::const_iterator I = CurrentAnalyses.find(ID); - if (I == CurrentAnalyses.end()) { - if (Batcher) - return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); - return 0; - } - return I->second; + + if (I != CurrentAnalyses.end()) + return I->second; // Found it. + + if (Batcher) + return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); + return 0; } - Pass *getAnalysisOrNullUp(AnalysisID ID) const { + Pass *getAnalysisOrNullUp(const PassInfo *ID) const { std::map::const_iterator I = CurrentAnalyses.find(ID); - if (I == CurrentAnalyses.end()) { - if (Parent) - return Parent->getAnalysisOrNullUp(ID); - return 0; - } - return I->second; + if (I != CurrentAnalyses.end()) + return I->second; // Found it. + + if (Parent) // Try scanning... + return Parent->getAnalysisOrNullUp(ID); + return 0; + } + + // {start/end}Pass - Called when a pass is started, it just propogates + // information up to the top level PassManagerT object to tell it that a pass + // has started or ended. This is used to gather timing information about + // passes. + // + void startPass(Pass *P) { + if (Parent) Parent->startPass(P); + else PassStarted(P); + } + void endPass(Pass *P) { + if (Parent) Parent->endPass(P); + else PassEnded(P); } // markPassUsed - Inform higher level pass managers (and ourselves) @@ -206,8 +329,9 @@ public: // make sure that analyses are not free'd before we have to use // them... // - void markPassUsed(AnalysisID P, Pass *User) { - std::map::iterator I = CurrentAnalyses.find(P); + 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 } else { @@ -216,8 +340,7 @@ public: // parent that we (the passmanager) are using the analysis so that it // frees the analysis AFTER this pass manager runs. // - assert(Parent != 0 && "Pass available but not found! " - "Did your analysis pass 'Provide' itself?"); + assert(Parent != 0 && "Pass available but not found!"); Parent->markPassUsed(P, this); } } @@ -228,28 +351,35 @@ public: return 1 + Parent->getDepth(); } - // add - Add a pass to the queue of passes to run. This passes ownership of + 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... - std::vector Required, Destroyed, Provided; - P->getAnalysisUsageInfo(Required, Destroyed, Provided); + AnalysisUsage AnUsage; + P->getAnalysisUsage(AnUsage); + const std::vector &Required = AnUsage.getRequiredSet(); // Loop over all of the analyses used by this pass, - for (std::vector::iterator I = Required.begin(), - E = Required.end(); I != E; ++I) { + for (std::vector::const_iterator I = Required.begin(), + E = Required.end(); I != E; ++I) { if (getAnalysisOrNullDown(*I) == 0) - add((PassClass*)I->createPass()); + add((PassClass*)(*I)->createPass()); } // 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.. // - P->addToPassManager(this, Required, Destroyed, Provided); + P->addToPassManager(this, AnUsage); } private: @@ -262,15 +392,17 @@ private: // // 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 - // MethodPasses that are present. + // FunctionPass's that are present. // - void addPass(PassClass *P, Pass::AnalysisSet &Required, - Pass::AnalysisSet &Destroyed, Pass::AnalysisSet &Provided) { - // Providers are analysis classes which are forbidden to modify the module - // they are operating on, so they are allowed to be reordered to before the - // batcher... + 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 to pass to execute before the batcher + // does, which will potentially allow us to batch more passes! // - if (Batcher && Provided.empty()) + //const std::vector &ProvidedSet = AnUsage.getProvidedSet(); + if (Batcher /*&& ProvidedSet.empty()*/) closeBatcher(); // This pass cannot be batched! // Set the Resolver instance variable in the Pass so that it knows where to @@ -283,34 +415,53 @@ private: // 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::iterator I = Required.begin(), - E = Required.end(); I != E; ++I) + for (std::vector::const_iterator I = RequiredSet.begin(), + E = RequiredSet.end(); I != E; ++I) markPassUsed(*I, P); // Mark *I as used by P - // Erase all analyses in the destroyed set... - for (std::vector::iterator I = Destroyed.begin(), - E = Destroyed.end(); I != E; ++I) - CurrentAnalyses.erase(*I); + // Erase all analyses not in the preserved set... + if (!AnUsage.preservesAll()) { + 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 MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER + I = CurrentAnalyses.erase(I); // Analysis not preserved! +#else + CurrentAnalyses.erase(I);// GCC 2.95.3 STL doesn't have correct erase! + I = CurrentAnalyses.begin(); +#endif + } + } + + // Add this pass to the currently available set... + if (const PassInfo *PI = P->getPassInfo()) { + CurrentAnalyses[PI] = P; - // Add all analyses in the provided set... - for (std::vector::iterator I = Provided.begin(), - E = Provided.end(); I != E; ++I) - CurrentAnalyses[*I] = 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; + } // For now assume that our results are never used... LastUseOf[P] = P; } - // For MethodPass subclasses, we must be sure to batch the MethodPasses - // together in a MethodPassBatcher object so that all of the analyses are run - // together a method at a time. + // 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, Pass::AnalysisSet &Required, - Pass::AnalysisSet &Destroyed, Pass::AnalysisSet &Provided) { + void addPass(SubPassClass *MP, AnalysisUsage &AnUsage) { if (Batcher == 0) // If we don't have a batcher yet, make one now. Batcher = new BatcherClass(this); - // The Batcher will queue them passes up - MP->addToPassManager(Batcher, Required, Destroyed, Provided); + // The Batcher will queue the passes up + MP->addToPassManager(Batcher, AnUsage); } // closeBatcher - Terminate the batcher that is being worked on. @@ -347,7 +498,7 @@ template<> struct PassManagerTraits : public BasicBlockPass { typedef PassClass BatcherClass; // ParentClass - The type of the parent PassManager... - typedef PassManagerT ParentClass; + typedef PassManagerT ParentClass; // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; @@ -355,30 +506,39 @@ template<> struct PassManagerTraits : public BasicBlockPass { // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, BasicBlock *M) { // todo, init and finalize - return P->runOnBasicBlock(M); + return P->runOnBasicBlock(*M); } + // Dummy implementation of PassStarted/PassEnded + static void PassStarted(Pass *P) {} + static void PassEnded(Pass *P) {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "BasicBlock"; } + virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } // Implement the BasicBlockPass interface... - virtual bool doInitialization(Module *M); - virtual bool runOnBasicBlock(BasicBlock *BB); - virtual bool doFinalization(Module *M); + virtual bool doInitialization(Module &M); + virtual bool runOnBasicBlock(BasicBlock &BB); + virtual bool doFinalization(Module &M); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } }; //===----------------------------------------------------------------------===// -// PassManagerTraits Specialization +// PassManagerTraits Specialization // -// This pass manager is used to group together all of the MethodPass's +// This pass manager is used to group together all of the FunctionPass's // into a single unit. // -template<> struct PassManagerTraits : public MethodPass { +template<> struct PassManagerTraits : public FunctionPass { // PassClass - The type of passes tracked by this PassManager - typedef MethodPass PassClass; + typedef FunctionPass PassClass; // SubPassClass - The types of classes that should be collated together typedef BasicBlockPass SubPassClass; @@ -390,21 +550,30 @@ template<> struct PassManagerTraits : public MethodPass { typedef PassManagerT ParentClass; // PMType - The type of the passmanager that subclasses this class - typedef PassManagerT PMType; + typedef PassManagerT PMType; // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Method *M) { - return P->runOnMethod(M); + static bool runPass(PassClass *P, Function *F) { + return P->runOnFunction(*F); } + // Dummy implementation of PassStarted/PassEnded + static void PassStarted(Pass *P) {} + static void PassEnded(Pass *P) {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. - const char *getPMName() const { return "Method"; } + const char *getPMName() const { return "Function"; } + virtual const char *getPassName() const { return "Function Pass Manager"; } + + // Implement the FunctionPass interface... + virtual bool doInitialization(Module &M); + virtual bool runOnFunction(Function &F); + virtual bool doFinalization(Module &M); - // Implement the MethodPass interface... - virtual bool doInitialization(Module *M); - virtual bool runOnMethod(Method *M); - virtual bool doFinalization(Module *M); + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } }; @@ -419,25 +588,53 @@ template<> struct PassManagerTraits : public Pass { typedef Pass PassClass; // SubPassClass - The types of classes that should be collated together - typedef MethodPass SubPassClass; + typedef FunctionPass SubPassClass; // BatcherClass - The type to use for collation of subtypes... - typedef PassManagerT BatcherClass; + typedef PassManagerT BatcherClass; // ParentClass - The type of the parent PassManager... typedef AnalysisResolver ParentClass; // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Module *M) { return P->run(M); } + static bool runPass(PassClass *P, Module *M) { return P->run(*M); } // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "Module"; } + virtual const char *getPassName() const { return "Module Pass Manager"; } - // run - Implement the Pass interface... - virtual bool run(Module *M) { - return ((PassManagerT*)this)->runOnUnit(M); + // TimingInformation - This data member maintains timing information for each + // of the passes that is executed. + // + TimingInfo *TimeInfo; + + // PassStarted/Ended - This callback is notified any time a pass is started + // or stops. This is used to collect timing information about the different + // passes being executed. + // + void PassStarted(Pass *P) { + if (TimeInfo) TimeInfo->passStarted(P); + } + void PassEnded(Pass *P) { + if (TimeInfo) TimeInfo->passEnded(P); + } + + // run - Implement the PassManager interface... + bool run(Module &M) { + TimeInfo = TimingInfo::create(); + bool Result = ((PassManagerT*)this)->runOnUnit(&M); + if (TimeInfo) { + delete TimeInfo; + TimeInfo = 0; + } + return Result; } + + // PassManagerTraits constructor - Create a timing info object if the user + // specified timing info should be collected on the command line. + // + PassManagerTraits() : TimeInfo(0) {} }; @@ -448,18 +645,18 @@ template<> struct PassManagerTraits : public Pass { // PassManagerTraits Implementations // -inline bool PassManagerTraits::doInitialization(Module *M) { +inline bool PassManagerTraits::doInitialization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doInitialization(M); return Changed; } -inline bool PassManagerTraits::runOnBasicBlock(BasicBlock *BB) { - return ((PMType*)this)->runOnUnit(BB); +inline bool PassManagerTraits::runOnBasicBlock(BasicBlock &BB) { + return ((PMType*)this)->runOnUnit(&BB); } -inline bool PassManagerTraits::doFinalization(Module *M) { +inline bool PassManagerTraits::doFinalization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doFinalization(M); @@ -467,20 +664,20 @@ inline bool PassManagerTraits::doFinalization(Module *M) { } -// PassManagerTraits Implementations +// PassManagerTraits Implementations // -inline bool PassManagerTraits::doInitialization(Module *M) { +inline bool PassManagerTraits::doInitialization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doInitialization(M); return Changed; } -inline bool PassManagerTraits::runOnMethod(Method *M) { - return ((PMType*)this)->runOnUnit(M); +inline bool PassManagerTraits::runOnFunction(Function &F) { + return ((PMType*)this)->runOnUnit(&F); } -inline bool PassManagerTraits::doFinalization(Module *M) { +inline bool PassManagerTraits::doFinalization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doFinalization(M);