-//===- 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<Module> 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 <string>
};
+//===----------------------------------------------------------------------===//
+// 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<Pass*, double> 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...
//
template<typename UnitType>
class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{
- typedef typename PassManagerTraits<UnitType>::PassClass PassClass;
- typedef typename PassManagerTraits<UnitType>::SubPassClass SubPassClass;
- typedef typename PassManagerTraits<UnitType>::BatcherClass BatcherClass;
- typedef typename PassManagerTraits<UnitType>::ParentClass ParentClass;
- typedef PassManagerTraits<UnitType> Traits;
+ typedef PassManagerTraits<UnitType> Traits;
+ typedef typename Traits::PassClass PassClass;
+ typedef typename Traits::SubPassClass SubPassClass;
+ typedef typename Traits::BatcherClass BatcherClass;
+ typedef typename Traits::ParentClass ParentClass;
- friend typename PassManagerTraits<UnitType>::PassClass;
- friend typename PassManagerTraits<UnitType>::SubPassClass;
- friend class PassManagerTraits<UnitType>;
+ friend typename Traits::PassClass;
+ friend typename Traits::SubPassClass;
+ friend class Traits;
std::vector<PassClass*> Passes; // List of pass's to run
#ifndef NDEBUG
// All Required analyses should be available to the pass as it runs!
- for (vector<AnalysisID>::const_iterator
+ for (std::vector<AnalysisID>::const_iterator
I = AnUsage.getRequiredSet().begin(),
E = AnUsage.getRequiredSet().end(); I != E; ++I) {
assert(getAnalysisOrNullUp(*I) && "Analysis used but not available!");
#endif
// Run the sub pass!
- bool Changed = Traits::runPass(P, M);
+ startPass(P);
+ bool Changed = runPass(P, M);
+ endPass(P);
MadeChanges |= Changed;
if (Changed)
return I->second;
}
+ // {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)
// 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
// 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();
+ }
};
// runPass - Specify how the pass should be run on the UnitType
static bool runPass(PassClass *P, Function *F) {
- return P->runOnFunction(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 "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);
+ virtual bool doInitialization(Module &M);
+ virtual bool runOnFunction(Function &F);
+ virtual bool doFinalization(Module &M);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
};
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"; }
+
+ // TimingInformation - This data member maintains timing information for each
+ // of the passes that is executed.
+ //
+ TimingInfo *TimeInfo;
- // run - Implement the Pass interface...
- virtual bool run(Module *M) {
- return ((PassManagerT<Module>*)this)->runOnUnit(M);
+ // 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<Module>*)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) {}
};
// PassManagerTraits<BasicBlock> Implementations
//
-inline bool PassManagerTraits<BasicBlock>::doInitialization(Module *M) {
+inline bool PassManagerTraits<BasicBlock>::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<BasicBlock>::runOnBasicBlock(BasicBlock *BB) {
- return ((PMType*)this)->runOnUnit(BB);
+inline bool PassManagerTraits<BasicBlock>::runOnBasicBlock(BasicBlock &BB) {
+ return ((PMType*)this)->runOnUnit(&BB);
}
-inline bool PassManagerTraits<BasicBlock>::doFinalization(Module *M) {
+inline bool PassManagerTraits<BasicBlock>::doFinalization(Module &M) {
bool Changed = false;
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
((PMType*)this)->Passes[i]->doFinalization(M);
// PassManagerTraits<Function> Implementations
//
-inline bool PassManagerTraits<Function>::doInitialization(Module *M) {
+inline bool PassManagerTraits<Function>::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<Function>::runOnFunction(Function *F) {
- return ((PMType*)this)->runOnUnit(F);
+inline bool PassManagerTraits<Function>::runOnFunction(Function &F) {
+ return ((PMType*)this)->runOnUnit(&F);
}
-inline bool PassManagerTraits<Function>::doFinalization(Module *M) {
+inline bool PassManagerTraits<Function>::doFinalization(Module &M) {
bool Changed = false;
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
((PMType*)this)->Passes[i]->doFinalization(M);