#include "llvm/PassManager.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Support/Streams.h"
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<enum PassDebugLevel>
+PassDebugging_New("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));
+} // End of llvm namespace
+
+#ifndef USE_OLD_PASSMANAGER
+namespace llvm {
+
class PMDataManager;
//===----------------------------------------------------------------------===//
/// then return NULL.
Pass *findAnalysisPass(AnalysisID AID);
+ inline void clearManagers() {
+ PassManagers.clear();
+ }
+
virtual ~PMTopLevelManager() {
+
+ for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I)
+ delete *I;
+
+ for (std::vector<ImmutablePass *>::iterator
+ I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
+ delete *I;
+
PassManagers.clear();
}
IndirectPassManagers.push_back(Manager);
}
+ // Print passes managed by this top level manager.
+ void dumpPasses();
+ void dumpArguments();
+
private:
/// Collection of pass managers
initializeAnalysisInfo();
}
+ virtual ~PMDataManager() {
+
+ for (std::vector<Pass *>::iterator I = PassVector.begin(),
+ E = PassVector.end(); I != E; ++I)
+ delete *I;
+
+ PassVector.clear();
+ }
+
/// Return true IFF pass P's required analysis set does not required new
/// manager.
bool manageablePass(Pass *P);
void removeNotPreservedAnalysis(Pass *P);
/// Remove dead passes
- void removeDeadPasses(Pass *P);
+ void removeDeadPasses(Pass *P, std::string &Msg);
/// Add pass P into the PassVector. Update
/// AvailableAnalysis appropriately if ProcessAnalysis is true.
unsigned getDepth() { return Depth; }
+ // Print list of passes that are last used by P.
+ void dumpLastUses(Pass *P, unsigned Offset) {
+
+ std::vector<Pass *> LUses;
+
+ assert (TPM && "Top Level Manager is missing");
+ TPM->collectLastUses(LUses, P);
+
+ for (std::vector<Pass *>::iterator I = LUses.begin(),
+ E = LUses.end(); I != E; ++I) {
+ llvm::cerr << "--" << std::string(Offset*2, ' ');
+ (*I)->dumpPassStructure(0);
+ }
+ }
+
+ void dumpPassArguments() {
+ for(std::vector<Pass *>::iterator I = PassVector.begin(),
+ E = PassVector.end(); I != E; ++I) {
+ if (PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I))
+ PMD->dumpPassArguments();
+ else
+ if (const PassInfo *PI = (*I)->getPassInfo())
+ if (!PI->isAnalysisGroup())
+ cerr << " -" << PI->getPassArgument();
+ }
+ }
+
+ void dumpPassInfo(Pass *P, std::string &Msg1, std::string &Msg2) {
+ if (PassDebugging_New < Executions)
+ return;
+ cerr << (void*)this << std::string(getDepth()*2+1, ' ');
+ cerr << Msg1;
+ cerr << P->getPassName();
+ cerr << Msg2;
+ }
+
protected:
// Collection of pass whose last user asked this manager to claim
};
//===----------------------------------------------------------------------===//
-// BasicBlockPassManager_New
+// BasicBlockPassManager
//
-/// BasicBlockPassManager_New manages BasicBlockPass. It batches all the
+/// BasicBlockPassManager manages BasicBlockPass. It batches all the
/// pass together and sequence them to process one basic block before
/// processing next basic block.
-class BasicBlockPassManager_New : public PMDataManager,
+class BasicBlockPassManager : public PMDataManager,
public FunctionPass {
public:
- BasicBlockPassManager_New(int D) : PMDataManager(D) { }
+ BasicBlockPassManager(int D) : PMDataManager(D) { }
/// Add a pass into a passmanager queue.
bool addPass(Pass *p);
bool doFinalization(Module &M);
bool doFinalization(Function &F);
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::cerr << std::string(Offset*2, ' ') << "BasicBLockPass Manager\n";
+ for (std::vector<Pass *>::iterator I = passVectorBegin(),
+ E = passVectorEnd(); I != E; ++I) {
+ (*I)->dumpPassStructure(Offset + 1);
+ dumpLastUses(*I, Offset+1);
+ }
+ }
};
//===----------------------------------------------------------------------===//
// FunctionPassManagerImpl_New
//
-/// FunctionPassManagerImpl_New manages FunctionPasses and BasicBlockPassManagers.
-/// It batches all function passes and basic block pass managers together and
-/// sequence them to process one function at a time before processing next
-/// function.
+/// FunctionPassManagerImpl_New manages FunctionPasses and
+/// BasicBlockPassManagers. It batches all function passes and basic block pass
+/// managers together and sequence them to process one function at a time before
+/// processing next function.
class FunctionPassManagerImpl_New : public ModulePass,
public PMDataManager,
public PMTopLevelManager {
Info.setPreservesAll();
}
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n";
+ for (std::vector<Pass *>::iterator I = passVectorBegin(),
+ E = passVectorEnd(); I != E; ++I) {
+ (*I)->dumpPassStructure(Offset + 1);
+ dumpLastUses(*I, Offset+1);
+ }
+ }
+
private:
// Active Pass Managers
- BasicBlockPassManager_New *activeBBPassManager;
+ BasicBlockPassManager *activeBBPassManager;
};
//===----------------------------------------------------------------------===//
-// ModulePassManager_New
+// ModulePassManager
//
-/// ModulePassManager_New manages ModulePasses and function pass managers.
+/// ModulePassManager manages ModulePasses and function pass managers.
/// It batches all Module passes passes and function pass managers together and
/// sequence them to process one module.
-class ModulePassManager_New : public Pass,
+class ModulePassManager : public Pass,
public PMDataManager {
public:
- ModulePassManager_New(int D) : PMDataManager(D) {
+ ModulePassManager(int D) : PMDataManager(D) {
activeFunctionPassManager = NULL;
}
Info.setPreservesAll();
}
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::cerr << std::string(Offset*2, ' ') << "ModulePass Manager\n";
+ for (std::vector<Pass *>::iterator I = passVectorBegin(),
+ E = passVectorEnd(); I != E; ++I) {
+ (*I)->dumpPassStructure(Offset + 1);
+ dumpLastUses(*I, Offset+1);
+ }
+ }
+
private:
// Active Pass Manager
FunctionPassManagerImpl_New *activeFunctionPassManager;
bool addPass(Pass *p);
// Active Pass Manager
- ModulePassManager_New *activeManager;
+ ModulePassManager *activeManager;
};
} // End of llvm namespace
LastUser[LUI->first] = P;
}
}
-
}
/// Collect passes whose last user is P
return P;
}
+// Print passes managed by this top level manager.
+void PMTopLevelManager::dumpPasses() {
+
+ // Print out the immutable passes
+ for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
+ ImmutablePasses[i]->dumpPassStructure(0);
+ }
+
+ for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I)
+ (*I)->dumpPassStructure(1);
+
+}
+
+void PMTopLevelManager::dumpArguments() {
+
+ if (PassDebugging_New < Arguments)
+ return;
+
+ cerr << "Pass Arguments: ";
+ for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I) {
+ PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I);
+ assert(PMD && "This is not a PassManager");
+ PMD->dumpPassArguments();
+ }
+ cerr << "\n";
+}
+
//===----------------------------------------------------------------------===//
// PMDataManager implementation
}
/// Remove analysis passes that are not used any longer
-void PMDataManager::removeDeadPasses(Pass *P) {
+void PMDataManager::removeDeadPasses(Pass *P, std::string &Msg) {
std::vector<Pass *> DeadPasses;
TPM->collectLastUses(DeadPasses, P);
for (std::vector<Pass *>::iterator I = DeadPasses.begin(),
E = DeadPasses.end(); I != E; ++I) {
+
+ std::string Msg1 = " Freeing Pass '";
+ dumpPassInfo(*I, Msg1, Msg);
+
(*I)->releaseMemory();
std::map<AnalysisID, Pass*>::iterator Pos =
}
//===----------------------------------------------------------------------===//
-// BasicBlockPassManager_New implementation
+// BasicBlockPassManager implementation
/// Add pass P into PassVector and return true. If this pass is not
/// manageable by this manager then return false.
bool
-BasicBlockPassManager_New::addPass(Pass *P) {
+BasicBlockPassManager::addPass(Pass *P) {
BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
if (!BP)
/// runOnBasicBlock method. Keep track of whether any of the passes modifies
/// the function, and if so, return true.
bool
-BasicBlockPassManager_New::runOnFunction(Function &F) {
+BasicBlockPassManager::runOnFunction(Function &F) {
+
+ if (F.isExternal())
+ return false;
bool Changed = doInitialization(F);
initializeAnalysisInfo();
+ std::string Msg1 = "Executing Pass '";
+ std::string Msg3 = "' Made Modification '";
+
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
-
+ std::string Msg2 = "' on BasicBlock '" + (*I).getName() + "'...\n";
+ dumpPassInfo(P, Msg1, Msg2);
+ initializeAnalysisImpl(P);
+
BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
Changed |= BP->runOnBasicBlock(*I);
+
+ if (Changed)
+ dumpPassInfo(P, Msg3, Msg2);
+
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
- removeDeadPasses(P);
+ removeDeadPasses(P, Msg2);
}
return Changed | doFinalization(F);
}
// Implement doInitialization and doFinalization
-inline bool BasicBlockPassManager_New::doInitialization(Module &M) {
+inline bool BasicBlockPassManager::doInitialization(Module &M) {
bool Changed = false;
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
return Changed;
}
-inline bool BasicBlockPassManager_New::doFinalization(Module &M) {
+inline bool BasicBlockPassManager::doFinalization(Module &M) {
bool Changed = false;
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
return Changed;
}
-inline bool BasicBlockPassManager_New::doInitialization(Function &F) {
+inline bool BasicBlockPassManager::doInitialization(Function &F) {
bool Changed = false;
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
return Changed;
}
-inline bool BasicBlockPassManager_New::doFinalization(Function &F) {
+inline bool BasicBlockPassManager::doFinalization(Function &F) {
bool Changed = false;
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
//===----------------------------------------------------------------------===//
-// FunctionPassManager_New implementation
+// FunctionPassManager implementation
/// Create new Function pass manager
-FunctionPassManager_New::FunctionPassManager_New() {
- FPM = new FunctionPassManagerImpl_New(0);
-}
-
-FunctionPassManager_New::FunctionPassManager_New(ModuleProvider *P) {
+FunctionPassManager::FunctionPassManager(ModuleProvider *P) {
FPM = new FunctionPassManagerImpl_New(0);
// FPM is the top level manager.
FPM->setTopLevelManager(FPM);
+
+ PMDataManager *PMD = dynamic_cast<PMDataManager *>(FPM);
+ AnalysisResolver_New *AR = new AnalysisResolver_New(*PMD);
+ FPM->setResolver(AR);
+
+ FPM->addPassManager(FPM);
MP = P;
}
+FunctionPassManager::~FunctionPassManager() {
+ // Note : FPM maintains one entry in PassManagers vector.
+ // This one entry is FPM itself. This is not ideal. One
+ // alternative is have one additional layer between
+ // FunctionPassManager and FunctionPassManagerImpl.
+ // Meanwhile, to avoid going into infinte loop, first
+ // remove FPM from its PassMangers vector.
+ FPM->clearManagers();
+ delete FPM;
+}
+
/// add - Add a pass to the queue of passes to run. This passes
/// ownership of the Pass to the PassManager. When the
/// PassManager_X is destroyed, the pass will be destroyed as well, so
/// there is no need to delete the pass. (TODO delete passes.)
/// This implies that all passes MUST be allocated with 'new'.
-void FunctionPassManager_New::add(Pass *P) {
+void FunctionPassManager::add(Pass *P) {
FPM->add(P);
}
-/// 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 FunctionPassManager_New::runOnModule(Module &M) {
- return FPM->runOnModule(M);
-}
-
/// 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 FunctionPassManager_New::run(Function &F) {
+bool FunctionPassManager::run(Function &F) {
std::string errstr;
if (MP->materializeFunction(&F, &errstr)) {
cerr << "Error reading bytecode file: " << errstr << "\n";
/// doInitialization - Run all of the initializers for the function passes.
///
-bool FunctionPassManager_New::doInitialization() {
+bool FunctionPassManager::doInitialization() {
return FPM->doInitialization(*MP->getModule());
}
/// doFinalization - Run all of the initializers for the function passes.
///
-bool FunctionPassManager_New::doFinalization() {
+bool FunctionPassManager::doFinalization() {
return FPM->doFinalization(*MP->getModule());
}
bool
FunctionPassManagerImpl_New::addPass(Pass *P) {
- // If P is a BasicBlockPass then use BasicBlockPassManager_New.
+ // If P is a BasicBlockPass then use BasicBlockPassManager.
if (BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P)) {
if (!activeBBPassManager || !activeBBPassManager->addPass(BP)) {
// Create and add new manager
activeBBPassManager =
- new BasicBlockPassManager_New(getDepth() + 1);
+ new BasicBlockPassManager(getDepth() + 1);
// Inherit top level manager
activeBBPassManager->setTopLevelManager(this->getTopLevelManager());
bool FunctionPassManagerImpl_New::runOnFunction(Function &F) {
bool Changed = false;
+
+ if (F.isExternal())
+ return false;
+
initializeAnalysisInfo();
+ std::string Msg1 = "Executing Pass '";
+ std::string Msg3 = "' Made Modification '";
+
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
-
+
+ std::string Msg2 = "' on Function '" + F.getName() + "'...\n";
+ dumpPassInfo(P, Msg1, Msg2);
+
+ initializeAnalysisImpl(P);
FunctionPass *FP = dynamic_cast<FunctionPass*>(P);
Changed |= FP->runOnFunction(F);
+
+ if (Changed)
+ dumpPassInfo(P, Msg3, Msg2);
+
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
- removeDeadPasses(P);
+ removeDeadPasses(P, Msg2);
}
return Changed;
}
bool Changed = false;
for (std::vector<Pass *>::iterator I = passManagersBegin(),
E = passManagersEnd(); I != E; ++I) {
- FunctionPass *FP = dynamic_cast<FunctionPass *>(*I);
+ FunctionPassManagerImpl_New *FP =
+ dynamic_cast<FunctionPassManagerImpl_New *>(*I);
Changed |= FP->runOnFunction(F);
}
return Changed;
/// then use FunctionPassManagerImpl_New to manage it. Return false if P
/// is not manageable by this manager.
bool
-ModulePassManager_New::addPass(Pass *P) {
+ModulePassManager::addPass(Pass *P) {
// If P is FunctionPass then use function pass maanager.
if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P)) {
activeFunctionPassManager->setTopLevelManager(this->getTopLevelManager());
// Add new manager into top level manager's indirect passes list
- PMDataManager *PMD = dynamic_cast<PMDataManager *>(activeFunctionPassManager);
- assert (PMD && "Manager is not Pass Manager");
+ PMDataManager *PMD =
+ dynamic_cast<PMDataManager *>(activeFunctionPassManager);
+ assert(PMD && "Manager is not Pass Manager");
TPM->addIndirectPassManager(PMD);
// Add pass into new manager. This time it must succeed.
/// runOnModule method. Keep track of whether any of the passes modifies
/// the module, and if so, return true.
bool
-ModulePassManager_New::runOnModule(Module &M) {
+ModulePassManager::runOnModule(Module &M) {
bool Changed = false;
initializeAnalysisInfo();
+ std::string Msg1 = "Executing Pass '";
+ std::string Msg3 = "' Made Modification '";
+
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
+ std::string Msg2 = "' on Module '" + M.getModuleIdentifier() + "'...\n";
+ dumpPassInfo(P, Msg1, Msg2);
+
+ initializeAnalysisImpl(P);
ModulePass *MP = dynamic_cast<ModulePass*>(P);
Changed |= MP->runOnModule(M);
+
+ if (Changed)
+ dumpPassInfo(P, Msg3, Msg2);
+
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
- removeDeadPasses(P);
+ removeDeadPasses(P, Msg2);
}
return Changed;
}
//===----------------------------------------------------------------------===//
// PassManagerImpl implementation
-
-// PassManager_New implementation
+//
/// Add P into active pass manager or use new module pass manager to
/// manage it.
bool PassManagerImpl_New::addPass(Pass *P) {
if (!activeManager || !activeManager->addPass(P)) {
- activeManager = new ModulePassManager_New(getDepth() + 1);
+ activeManager = new ModulePassManager(getDepth() + 1);
// Inherit top level manager
activeManager->setTopLevelManager(this->getTopLevelManager());
bool PassManagerImpl_New::run(Module &M) {
bool Changed = false;
+
+ dumpArguments();
+ if (PassDebugging_New >= Structure)
+ dumpPasses();
+
for (std::vector<Pass *>::iterator I = passManagersBegin(),
E = passManagersEnd(); I != E; ++I) {
- ModulePassManager_New *MP = dynamic_cast<ModulePassManager_New *>(*I);
+ ModulePassManager *MP = dynamic_cast<ModulePassManager *>(*I);
Changed |= MP->runOnModule(M);
}
return Changed;
// PassManager implementation
/// Create new pass manager
-PassManager_New::PassManager_New() {
+PassManager::PassManager() {
PM = new PassManagerImpl_New(0);
// PM is the top level manager
PM->setTopLevelManager(PM);
}
+PassManager::~PassManager() {
+ delete PM;
+}
+
/// 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
-PassManager_New::add(Pass *P) {
+PassManager::add(Pass *P) {
PM->add(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
-PassManager_New::run(Module &M) {
+PassManager::run(Module &M) {
return PM->run(M);
}
+#endif