X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManager.cpp;h=f2c9ea3b997e56acd49a6aa8a67e6f6737de3c44;hb=d9221d75f02a81eec9c22473b4f2a809d83bf60a;hp=47999152c1d2336566a4336faa6e2c233c28b527;hpb=d6752d1666fc040c368caba23372c116c1ed75c1;p=oota-llvm.git diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 47999152c1d..f2c9ea3b997 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -17,9 +17,11 @@ #include "llvm/Support/Timer.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/System/Mutex.h" +#include "llvm/System/Threading.h" #include "llvm/Analysis/Dominators.h" #include "llvm-c/Core.h" #include @@ -65,6 +67,15 @@ PassDebugging("debug-pass", cl::Hidden, clEnumValEnd)); } // End of llvm namespace +/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions +/// or higher is specified. +bool PMDataManager::isPassDebuggingExecutionsOrMore() const { + return PassDebugging >= Executions; +} + + + + void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { if (V == 0 && M == 0) OS << "Releasing pass '"; @@ -132,7 +143,7 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "BasicBlockPass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "BasicBlockPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); BP->dumpPassStructure(Offset + 1); @@ -163,11 +174,13 @@ namespace llvm { class FunctionPassManagerImpl : public Pass, public PMDataManager, public PMTopLevelManager { +private: + bool wasRun; public: static char ID; explicit FunctionPassManagerImpl(int Depth) : Pass(&ID), PMDataManager(Depth), - PMTopLevelManager(TLM_Function) { } + PMTopLevelManager(TLM_Function), wasRun(false) { } /// 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 @@ -177,6 +190,10 @@ public: schedulePass(P); } + // Prepare for running an on the fly pass, freeing memory if needed + // from a previous run. + void releaseMemoryOnTheFly(); + /// 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(Function &F); @@ -266,12 +283,14 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "ModulePass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "ModulePass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); MP->dumpPassStructure(Offset + 1); - if (FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]) - FPP->dumpPassStructure(Offset + 2); + std::map::const_iterator I = + OnTheFlyManagers.find(MP); + if (I != OnTheFlyManagers.end()) + I->second->dumpPassStructure(Offset + 2); dumpLastUses(MP, Offset+1); } } @@ -355,6 +374,9 @@ namespace { /// amount of time each pass takes to execute. This only happens when /// -time-passes is enabled on the command line. /// + +static ManagedStatic > TimingInfoMutex; + class VISIBILITY_HIDDEN TimingInfo { std::map TimingData; TimerGroup TG; @@ -379,15 +401,18 @@ public: if (dynamic_cast(P)) return; + sys::SmartScopedLock Lock(*TimingInfoMutex); 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; + sys::SmartScopedLock Lock(*TimingInfoMutex); std::map::iterator I = TimingData.find(P); assert(I != TimingData.end() && "passStarted/passEnded not nested right!"); I->second.stopTimer(); @@ -587,11 +612,11 @@ void PMTopLevelManager::dumpArguments() const { if (PassDebugging < Arguments) return; - cerr << "Pass Arguments: "; + errs() << "Pass Arguments: "; for (SmallVector::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) (*I)->dumpPassArguments(); - cerr << "\n"; + errs() << "\n"; } void PMTopLevelManager::initializeAllAnalysisInfo() { @@ -701,13 +726,13 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) { DominatorTree OtherDT; OtherDT.getBase().recalculate(F); if (DT->compare(OtherDT)) { - cerr << "Dominator Information for " << F.getNameStart() << "\n"; - cerr << "Pass '" << P.getPassName() << "'\n"; - cerr << "----- Valid -----\n"; + errs() << "Dominator Information for " << F.getName() << "\n"; + errs() << "Pass '" << P.getPassName() << "'\n"; + errs() << "----- Valid -----\n"; OtherDT.dump(); - cerr << "----- Invalid -----\n"; + errs() << "----- Invalid -----\n"; DT->dump(); - assert(0 && "Invalid dominator info"); + llvm_unreachable("Invalid dominator info"); } DominanceFrontier *DF = P.getAnalysisIfAvailable(); @@ -718,13 +743,13 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) { std::vector DTRoots = DT->getRoots(); OtherDF.calculate(*DT, DT->getNode(DTRoots[0])); if (DF->compare(OtherDF)) { - cerr << "Dominator Information for " << F.getNameStart() << "\n"; - cerr << "Pass '" << P.getPassName() << "'\n"; - cerr << "----- Valid -----\n"; + errs() << "Dominator Information for " << F.getName() << "\n"; + errs() << "Pass '" << P.getPassName() << "'\n"; + errs() << "----- Valid -----\n"; OtherDF.dump(); - cerr << "----- Invalid -----\n"; + errs() << "----- Invalid -----\n"; DF->dump(); - assert(0 && "Invalid dominator info"); + llvm_unreachable("Invalid dominator info"); } } @@ -744,8 +769,8 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { // Remove this analysis if (PassDebugging >= Details) { Pass *S = Info->second; - cerr << " -- '" << P->getPassName() << "' is not preserving '"; - cerr << S->getPassName() << "'\n"; + errs() << " -- '" << P->getPassName() << "' is not preserving '"; + errs() << S->getPassName() << "'\n"; } AvailableAnalysis.erase(Info); } @@ -772,7 +797,7 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { } /// Remove analysis passes that are not used any longer -void PMDataManager::removeDeadPasses(Pass *P, const char *Msg, +void PMDataManager::removeDeadPasses(Pass *P, const StringRef &Msg, enum PassDebuggingString DBG_STR) { SmallVector DeadPasses; @@ -784,9 +809,9 @@ void PMDataManager::removeDeadPasses(Pass *P, const char *Msg, TPM->collectLastUses(DeadPasses, P); if (PassDebugging >= Details && !DeadPasses.empty()) { - cerr << " -*- '" << P->getPassName(); - cerr << "' is the last user of following pass instances."; - cerr << " Free these instances\n"; + errs() << " -*- '" << P->getPassName(); + errs() << "' is the last user of following pass instances."; + errs() << " Free these instances\n"; } for (SmallVector::iterator I = DeadPasses.begin(), @@ -866,7 +891,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { // Keep track of higher level analysis used by this manager. HigherLevelAnalysis.push_back(PRequired); } else - assert(0 && "Unable to accomodate Required Pass"); + llvm_unreachable("Unable to accomodate Required Pass"); } // Set P as P's last user until someone starts using P. @@ -978,7 +1003,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ for (SmallVector::iterator I = LUses.begin(), E = LUses.end(); I != E; ++I) { - llvm::cerr << "--" << std::string(Offset*2, ' '); + llvm::errs() << "--" << std::string(Offset*2, ' '); (*I)->dumpPassStructure(0); } } @@ -991,44 +1016,44 @@ void PMDataManager::dumpPassArguments() const { else if (const PassInfo *PI = (*I)->getPassInfo()) if (!PI->isAnalysisGroup()) - cerr << " -" << PI->getPassArgument(); + errs() << " -" << PI->getPassArgument(); } } void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, enum PassDebuggingString S2, - const char *Msg) { + const StringRef &Msg) { if (PassDebugging < Executions) return; - cerr << (void*)this << std::string(getDepth()*2+1, ' '); + errs() << (void*)this << std::string(getDepth()*2+1, ' '); switch (S1) { case EXECUTION_MSG: - cerr << "Executing Pass '" << P->getPassName(); + errs() << "Executing Pass '" << P->getPassName(); break; case MODIFICATION_MSG: - cerr << "Made Modification '" << P->getPassName(); + errs() << "Made Modification '" << P->getPassName(); break; case FREEING_MSG: - cerr << " Freeing Pass '" << P->getPassName(); + errs() << " Freeing Pass '" << P->getPassName(); break; default: break; } switch (S2) { case ON_BASICBLOCK_MSG: - cerr << "' on BasicBlock '" << Msg << "'...\n"; + errs() << "' on BasicBlock '" << Msg << "'...\n"; break; case ON_FUNCTION_MSG: - cerr << "' on Function '" << Msg << "'...\n"; + errs() << "' on Function '" << Msg << "'...\n"; break; case ON_MODULE_MSG: - cerr << "' on Module '" << Msg << "'...\n"; + errs() << "' on Module '" << Msg << "'...\n"; break; case ON_LOOP_MSG: - cerr << "' on Loop " << Msg << "'...\n"; + errs() << "' on Loop '" << Msg << "'...\n"; break; case ON_CG_MSG: - cerr << "' on Call Graph " << Msg << "'...\n"; + errs() << "' on Call Graph Nodes '" << Msg << "'...\n"; break; default: break; @@ -1053,17 +1078,17 @@ void PMDataManager::dumpPreservedSet(const Pass *P) const { dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); } -void PMDataManager::dumpAnalysisUsage(const char *Msg, const Pass *P, +void PMDataManager::dumpAnalysisUsage(const StringRef &Msg, const Pass *P, const AnalysisUsage::VectorType &Set) const { assert(PassDebugging >= Details); if (Set.empty()) return; - cerr << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; + errs() << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; for (unsigned i = 0; i != Set.size(); ++i) { - if (i) cerr << ","; - cerr << " " << Set[i]->getPassName(); + if (i) errs() << ','; + errs() << ' ' << Set[i]->getPassName(); } - cerr << "\n"; + errs() << '\n'; } /// Add RequiredPass into list of lower level passes required by pass P. @@ -1086,10 +1111,10 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { // checks whether any lower level manager will be able to provide this // analysis info on demand or not. #ifndef NDEBUG - cerr << "Unable to schedule '" << RequiredPass->getPassName(); - cerr << "' required by '" << P->getPassName() << "'\n"; + errs() << "Unable to schedule '" << RequiredPass->getPassName(); + errs() << "' required by '" << P->getPassName() << "'\n"; #endif - assert(0 && "Unable to schedule pass"); + llvm_unreachable("Unable to schedule pass"); } // Destructor @@ -1127,7 +1152,7 @@ bool BBPassManager::runOnFunction(Function &F) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); - dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getNameStart()); + dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); dumpRequiredSet(BP); initializeAnalysisImpl(BP); @@ -1143,13 +1168,13 @@ bool BBPassManager::runOnFunction(Function &F) { if (Changed) dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, - I->getNameStart()); + I->getName()); dumpPreservedSet(BP); verifyPreservedAnalysis(BP); removeNotPreservedAnalysis(BP); recordAvailableAnalysis(BP); - removeDeadPasses(BP, I->getNameStart(), ON_BASICBLOCK_MSG); + removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); } return Changed |= doFinalization(F); @@ -1232,8 +1257,7 @@ void FunctionPassManager::add(Pass *P) { bool FunctionPassManager::run(Function &F) { std::string errstr; if (MP->materializeFunction(&F, &errstr)) { - cerr << "Error reading bitcode file: " << errstr << "\n"; - abort(); + llvm_report_error("Error reading bitcode file: " + errstr); } return FPM->run(F); } @@ -1282,6 +1306,18 @@ void FPPassManager::cleanup() { } } +void FunctionPassManagerImpl::releaseMemoryOnTheFly() { + if (!wasRun) + return; + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { + FPPassManager *FPPM = getContainedManager(Index); + for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) { + FPPM->getContainedPass(Index)->releaseMemory(); + } + } + wasRun = false; +} + // Execute all the passes managed by this top level manager. // Return true if any function is modified by a pass. bool FunctionPassManagerImpl::run(Function &F) { @@ -1298,6 +1334,7 @@ bool FunctionPassManagerImpl::run(Function &F) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) getContainedManager(Index)->cleanup(); + wasRun = true; return Changed; } @@ -1307,7 +1344,7 @@ bool FunctionPassManagerImpl::run(Function &F) { char FPPassManager::ID = 0; /// Print passes managed by this manager void FPPassManager::dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); FP->dumpPassStructure(Offset + 1); @@ -1331,7 +1368,7 @@ bool FPPassManager::runOnFunction(Function &F) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); - dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getNameStart()); + dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); dumpRequiredSet(FP); initializeAnalysisImpl(FP); @@ -1345,13 +1382,13 @@ bool FPPassManager::runOnFunction(Function &F) { } if (Changed) - dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getNameStart()); + dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); dumpPreservedSet(FP); verifyPreservedAnalysis(FP); removeNotPreservedAnalysis(FP); recordAvailableAnalysis(FP); - removeDeadPasses(FP, F.getNameStart(), ON_FUNCTION_MSG); + removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); // If dominator information is available then verify the info if requested. verifyDomInfo(*FP, F); @@ -1396,6 +1433,14 @@ bool MPPassManager::runOnModule(Module &M) { bool Changed = false; + // Initialize on-the-fly passes + for (std::map::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + Changed |= FPP->doInitialization(M); + } + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); @@ -1422,6 +1467,17 @@ MPPassManager::runOnModule(Module &M) { recordAvailableAnalysis(MP); removeDeadPasses(MP, M.getModuleIdentifier().c_str(), ON_MODULE_MSG); } + + // Finalize on-the-fly passes + for (std::map::iterator + I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end(); + I != E; ++I) { + FunctionPassManagerImpl *FPP = I->second; + // We don't know when is the last time an on-the-fly pass is run, + // so we need to releaseMemory / finalize here + FPP->releaseMemoryOnTheFly(); + Changed |= FPP->doFinalization(M); + } return Changed; } @@ -1458,6 +1514,7 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, const PassInfo *PI, Function &F){ FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; assert(FPP && "Unable to find on the fly pass"); + FPP->releaseMemoryOnTheFly(); FPP->run(F); return (dynamic_cast(FPP))->findAnalysisPass(PI); } @@ -1533,13 +1590,13 @@ void TimingInfo::createTheTimeInfo() { } /// If TimingInfo is enabled then start pass timer. -void StartPassTimer(Pass *P) { +void llvm::StartPassTimer(Pass *P) { if (TheTimeInfo) TheTimeInfo->passStarted(P); } /// If TimingInfo is enabled then stop pass timer. -void StopPassTimer(Pass *P) { +void llvm::StopPassTimer(Pass *P) { if (TheTimeInfo) TheTimeInfo->passEnded(P); }