X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManager.cpp;h=add056b280ba9f36d388807ee490dd056e21e67f;hb=693a74e4ee34e2058dab7121c17c98ec59258a8a;hp=3498fcf62f9c40bdc952244ac45b619eb8fe2467;hpb=27aaab2bd3c220d8466b34f6b959f74e1caac69b;p=oota-llvm.git diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 3498fcf62f9..add056b280b 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -13,6 +13,7 @@ #include "llvm/PassManager.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/Support/Streams.h" @@ -86,6 +87,33 @@ using namespace llvm; 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_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; //===----------------------------------------------------------------------===// @@ -125,7 +153,20 @@ public: /// then return NULL. Pass *findAnalysisPass(AnalysisID AID); + inline void clearManagers() { + PassManagers.clear(); + } + virtual ~PMTopLevelManager() { + + for (std::vector::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + delete *I; + + for (std::vector::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; + PassManagers.clear(); } @@ -149,6 +190,10 @@ public: IndirectPassManagers.push_back(Manager); } + // Print passes managed by this top level manager. + void dumpPasses(); + void dumpArguments(); + private: /// Collection of pass managers @@ -179,6 +224,15 @@ public: initializeAnalysisInfo(); } + virtual ~PMDataManager() { + + for (std::vector::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); @@ -190,7 +244,7 @@ public: 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. @@ -231,6 +285,42 @@ public: unsigned getDepth() { return Depth; } + // Print list of passes that are last used by P. + void dumpLastUses(Pass *P, unsigned Offset) { + + std::vector LUses; + + assert (TPM && "Top Level Manager is missing"); + TPM->collectLastUses(LUses, P); + + for (std::vector::iterator I = LUses.begin(), + E = LUses.end(); I != E; ++I) { + llvm::cerr << "--" << std::string(Offset*2, ' '); + (*I)->dumpPassStructure(0); + } + } + + void dumpPassArguments() { + for(std::vector::iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) { + if (PMDataManager *PMD = dynamic_cast(*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 @@ -255,16 +345,16 @@ private: }; //===----------------------------------------------------------------------===// -// 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); @@ -283,15 +373,24 @@ public: 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::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 { @@ -349,22 +448,32 @@ public: Info.setPreservesAll(); } + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; + for (std::vector::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; } @@ -380,6 +489,16 @@ public: Info.setPreservesAll(); } + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset) { + llvm::cerr << std::string(Offset*2, ' ') << "ModulePass Manager\n"; + for (std::vector::iterator I = passVectorBegin(), + E = passVectorEnd(); I != E; ++I) { + (*I)->dumpPassStructure(Offset + 1); + dumpLastUses(*I, Offset+1); + } + } + private: // Active Pass Manager FunctionPassManagerImpl_New *activeFunctionPassManager; @@ -438,7 +557,7 @@ private: bool addPass(Pass *p); // Active Pass Manager - ModulePassManager_New *activeManager; + ModulePassManager *activeManager; }; } // End of llvm namespace @@ -462,7 +581,6 @@ void PMTopLevelManager::setLastUser(std::vector &AnalysisPasses, LastUser[LUI->first] = P; } } - } /// Collect passes whose last user is P @@ -539,6 +657,35 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { 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::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::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) { + PMDataManager *PMD = dynamic_cast(*I); + assert(PMD && "This is not a PassManager"); + PMD->dumpPassArguments(); + } + cerr << "\n"; +} + //===----------------------------------------------------------------------===// // PMDataManager implementation @@ -595,13 +742,17 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { } /// Remove analysis passes that are not used any longer -void PMDataManager::removeDeadPasses(Pass *P) { +void PMDataManager::removeDeadPasses(Pass *P, std::string &Msg) { std::vector DeadPasses; TPM->collectLastUses(DeadPasses, P); for (std::vector::iterator I = DeadPasses.begin(), E = DeadPasses.end(); I != E; ++I) { + + std::string Msg1 = " Freeing Pass '"; + dumpPassInfo(*I, Msg1, Msg); + (*I)->releaseMemory(); std::map::iterator Pos = @@ -734,12 +885,12 @@ Pass *AnalysisResolver_New::getAnalysisToUpdate(AnalysisID ID, bool dir) const { } //===----------------------------------------------------------------------===// -// 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(P); if (!BP) @@ -759,27 +910,40 @@ BasicBlockPassManager_New::addPass(Pass *P) { /// 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::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(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::iterator itr = passVectorBegin(), @@ -792,7 +956,7 @@ inline bool BasicBlockPassManager_New::doInitialization(Module &M) { return Changed; } -inline bool BasicBlockPassManager_New::doFinalization(Module &M) { +inline bool BasicBlockPassManager::doFinalization(Module &M) { bool Changed = false; for (std::vector::iterator itr = passVectorBegin(), @@ -805,7 +969,7 @@ inline bool BasicBlockPassManager_New::doFinalization(Module &M) { return Changed; } -inline bool BasicBlockPassManager_New::doInitialization(Function &F) { +inline bool BasicBlockPassManager::doInitialization(Function &F) { bool Changed = false; for (std::vector::iterator itr = passVectorBegin(), @@ -818,7 +982,7 @@ inline bool BasicBlockPassManager_New::doInitialization(Function &F) { return Changed; } -inline bool BasicBlockPassManager_New::doFinalization(Function &F) { +inline bool BasicBlockPassManager::doFinalization(Function &F) { bool Changed = false; for (std::vector::iterator itr = passVectorBegin(), @@ -833,41 +997,47 @@ inline bool BasicBlockPassManager_New::doFinalization(Function &F) { //===----------------------------------------------------------------------===// -// 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(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"; @@ -879,13 +1049,13 @@ bool FunctionPassManager_New::run(Function &F) { /// 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()); } @@ -898,7 +1068,7 @@ bool FunctionPassManager_New::doFinalization() { 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(P)) { if (!activeBBPassManager || !activeBBPassManager->addPass(BP)) { @@ -909,7 +1079,7 @@ FunctionPassManagerImpl_New::addPass(Pass *P) { // Create and add new manager activeBBPassManager = - new BasicBlockPassManager_New(getDepth() + 1); + new BasicBlockPassManager(getDepth() + 1); // Inherit top level manager activeBBPassManager->setTopLevelManager(this->getTopLevelManager()); @@ -972,17 +1142,32 @@ bool FunctionPassManagerImpl_New::runOnModule(Module &M) { 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::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(P); Changed |= FP->runOnFunction(F); + + if (Changed) + dumpPassInfo(P, Msg3, Msg2); + removeNotPreservedAnalysis(P); recordAvailableAnalysis(P); - removeDeadPasses(P); + removeDeadPasses(P, Msg2); } return Changed; } @@ -1023,7 +1208,8 @@ bool FunctionPassManagerImpl_New::run(Function &F) { bool Changed = false; for (std::vector::iterator I = passManagersBegin(), E = passManagersEnd(); I != E; ++I) { - FunctionPass *FP = dynamic_cast(*I); + FunctionPassManagerImpl_New *FP = + dynamic_cast(*I); Changed |= FP->runOnFunction(F); } return Changed; @@ -1036,7 +1222,7 @@ bool FunctionPassManagerImpl_New::run(Function &F) { /// 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(P)) { @@ -1058,8 +1244,9 @@ ModulePassManager_New::addPass(Pass *P) { activeFunctionPassManager->setTopLevelManager(this->getTopLevelManager()); // Add new manager into top level manager's indirect passes list - PMDataManager *PMD = dynamic_cast(activeFunctionPassManager); - assert (PMD && "Manager is not Pass Manager"); + PMDataManager *PMD = + dynamic_cast(activeFunctionPassManager); + assert(PMD && "Manager is not Pass Manager"); TPM->addIndirectPassManager(PMD); // Add pass into new manager. This time it must succeed. @@ -1097,33 +1284,43 @@ ModulePassManager_New::addPass(Pass *P) { /// 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::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(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()); @@ -1143,9 +1340,14 @@ bool PassManagerImpl_New::addPass(Pass *P) { bool PassManagerImpl_New::run(Module &M) { bool Changed = false; + + dumpArguments(); + if (PassDebugging_New >= Structure) + dumpPasses(); + for (std::vector::iterator I = passManagersBegin(), E = passManagersEnd(); I != E; ++I) { - ModulePassManager_New *MP = dynamic_cast(*I); + ModulePassManager *MP = dynamic_cast(*I); Changed |= MP->runOnModule(M); } return Changed; @@ -1155,25 +1357,30 @@ bool PassManagerImpl_New::run(Module &M) { // 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