diff options
author | Edwin Török <edwintorok@gmail.com> | 2009-06-29 18:49:09 +0000 |
---|---|---|
committer | Edwin Török <edwintorok@gmail.com> | 2009-06-29 18:49:09 +0000 |
commit | 0f48d6fc7e949c1f0b4a6a6fda946bf64f22cdcf (patch) | |
tree | 56539d6317c9e4dae91160a7e433aa721e1a8598 /lib | |
parent | 3bf01f0569aa24a038c6e479cf495c0c1e2c0802 (diff) | |
download | external_llvm-0f48d6fc7e949c1f0b4a6a6fda946bf64f22cdcf.tar.gz external_llvm-0f48d6fc7e949c1f0b4a6a6fda946bf64f22cdcf.tar.bz2 external_llvm-0f48d6fc7e949c1f0b4a6a6fda946bf64f22cdcf.zip |
Call doInitialization(), releaseMemory(), and doFinalization() for on-the-fly passes as well.
Also don't call finalizers for LoopPass if initialization was not called.
Add a unittest that tests that these methods are called, in the proper
order, and the correct number of times.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74438 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/LoopPass.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/PassManager.cpp | 40 |
2 files changed, 42 insertions, 1 deletions
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp index 08c25f4cea..ee03556f27 100644 --- a/lib/Analysis/LoopPass.cpp +++ b/lib/Analysis/LoopPass.cpp @@ -195,6 +195,9 @@ bool LPPassManager::runOnFunction(Function &F) { for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) addLoopIntoQueue(*I, LQ); + if (LQ.empty()) // No loops, skip calling finalizers + return false; + // Initialization for (std::deque<Loop *>::const_iterator I = LQ.begin(), E = LQ.end(); I != E; ++I) { diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 86cf10e673..24fb35c215 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -165,11 +165,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 @@ -179,6 +181,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); @@ -1290,6 +1296,17 @@ 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(); + } + } +} + // 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) { @@ -1306,6 +1323,7 @@ bool FunctionPassManagerImpl::run(Function &F) { for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) getContainedManager(Index)->cleanup(); + wasRun = true; return Changed; } @@ -1404,6 +1422,14 @@ bool MPPassManager::runOnModule(Module &M) { bool Changed = false; + // Initialize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::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); @@ -1430,6 +1456,17 @@ MPPassManager::runOnModule(Module &M) { recordAvailableAnalysis(MP); removeDeadPasses(MP, M.getModuleIdentifier().c_str(), ON_MODULE_MSG); } + + // Finalize on-the-fly passes + for (std::map<Pass *, FunctionPassManagerImpl *>::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; } @@ -1466,6 +1503,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<PMTopLevelManager *>(FPP))->findAnalysisPass(PI); } |