X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManager.cpp;h=e1f8afe3b0ea069f77589a5e26e8ac05ab080731;hb=51cd9d6e073932fcb37f1857c66249d6c7d368ee;hp=edcdf7ffe390adb963fa9247990481af6fbe7a73;hpb=2bb7d0647e5b3f79ad9b6e7efd0dd99f24a0ca69;p=oota-llvm.git diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index edcdf7ffe39..e1f8afe3b0e 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Devang Patel and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -19,6 +19,7 @@ #include "llvm/ModuleProvider.h" #include "llvm/Support/Streams.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm-c/Core.h" #include #include #include @@ -65,7 +66,7 @@ class VISIBILITY_HIDDEN BBPassManager : public PMDataManager, public: static char ID; - BBPassManager(int Depth) + explicit BBPassManager(int Depth) : PMDataManager(Depth), FunctionPass((intptr_t)&ID) {} /// Execute all of the passes scheduled for execution. Keep track of @@ -83,7 +84,7 @@ public: bool doFinalization(Function &F); virtual const char *getPassName() const { - return "BasicBlock Pass Manager"; + return "BasicBlock Pass Manager"; } // Print passes managed by this manager @@ -121,7 +122,7 @@ class FunctionPassManagerImpl : public Pass, public PMTopLevelManager { public: static char ID; - FunctionPassManagerImpl(int Depth) : + explicit FunctionPassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth), PMTopLevelManager(TLM_Function) { } @@ -179,13 +180,14 @@ char FunctionPassManagerImpl::ID = 0; // MPPassManager // /// MPPassManager manages ModulePasses and function pass managers. -/// It batches all Module passes passes and function pass managers together and -/// sequence them to process one module. +/// It batches all Module passes and function pass managers together and +/// sequences them to process one module. class MPPassManager : public Pass, public PMDataManager { public: static char ID; - MPPassManager(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth) { } + explicit MPPassManager(int Depth) : + Pass((intptr_t)&ID), PMDataManager(Depth) { } // Delete on the fly managers. virtual ~MPPassManager() { @@ -260,8 +262,9 @@ class PassManagerImpl : public Pass, public: static char ID; - PassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth), - PMTopLevelManager(TLM_Pass) { } + explicit PassManagerImpl(int Depth) : + Pass((intptr_t)&ID), PMDataManager(Depth), + PMTopLevelManager(TLM_Pass) { } /// 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 @@ -357,10 +360,10 @@ public: } }; -static TimingInfo *TheTimeInfo; - } // End of anon namespace +static TimingInfo *TheTimeInfo; + //===----------------------------------------------------------------------===// // PMTopLevelManager implementation @@ -423,6 +426,13 @@ void PMTopLevelManager::schedulePass(Pass *P) { // Give pass a chance to prepare the stage. P->preparePassManager(activeStack); + // If P is an analysis pass and it is available then do not + // generate the analysis again. Stale analysis info should not be + // available at this point. + if (P->getPassInfo() && + P->getPassInfo()->isAnalysis() && findAnalysisPass(P->getPassInfo())) + return; + AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); const std::vector &RequiredSet = AnUsage.getRequiredSet(); @@ -453,10 +463,9 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { Pass *P = NULL; // Check pass managers - for (std::vector::iterator I = PassManagers.begin(), + for (std::vector::iterator I = PassManagers.begin(), E = PassManagers.end(); P == NULL && I != E; ++I) { - PMDataManager *PMD = dynamic_cast(*I); - assert(PMD && "This is not a PassManager"); + PMDataManager *PMD = *I; P = PMD->findAnalysisPass(AID, false); } @@ -473,7 +482,8 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { // If Pass not found then check the interfaces implemented by Immutable Pass if (!P) { - const std::vector &ImmPI = PI->getInterfacesImplemented(); + const std::vector &ImmPI = + PI->getInterfacesImplemented(); if (std::find(ImmPI.begin(), ImmPI.end(), AID) != ImmPI.end()) P = *I; } @@ -493,9 +503,13 @@ void PMTopLevelManager::dumpPasses() const { ImmutablePasses[i]->dumpPassStructure(0); } - for (std::vector::const_iterator I = PassManagers.begin(), + // Every class that derives from PMDataManager also derives from Pass + // (sometimes indirectly), but there's no inheritance relationship + // between PMDataManager and Pass, so we have to dynamic_cast to get + // from a PMDataManager* to a Pass*. + for (std::vector::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) - (*I)->dumpPassStructure(1); + dynamic_cast(*I)->dumpPassStructure(1); } void PMTopLevelManager::dumpArguments() const { @@ -504,10 +518,9 @@ void PMTopLevelManager::dumpArguments() const { return; cerr << "Pass Arguments: "; - for (std::vector::const_iterator I = PassManagers.begin(), + for (std::vector::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) { - PMDataManager *PMD = dynamic_cast(*I); - assert(PMD && "This is not a PassManager"); + PMDataManager *PMD = *I; PMD->dumpPassArguments(); } cerr << "\n"; @@ -515,10 +528,9 @@ void PMTopLevelManager::dumpArguments() const { void PMTopLevelManager::initializeAllAnalysisInfo() { - for (std::vector::iterator I = PassManagers.begin(), + 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"); + PMDataManager *PMD = *I; PMD->initializeAnalysisInfo(); } @@ -530,34 +542,18 @@ void PMTopLevelManager::initializeAllAnalysisInfo() { /// Destructor PMTopLevelManager::~PMTopLevelManager() { - for (std::vector::iterator I = PassManagers.begin(), + 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(); } //===----------------------------------------------------------------------===// // PMDataManager implementation -/// Return true IFF pass P's required analysis set does not required new -/// manager. -bool PMDataManager::manageablePass(Pass *P) { - - // TODO - // If this pass is not preserving information that is required by a - // pass maintained by higher level pass manager then do not insert - // this pass into current manager. Use new manager. For example, - // For example, If FunctionPass F is not preserving ModulePass Info M1 - // that is used by another ModulePass M2 then do not insert F in - // current function pass manager. - return true; -} - /// Augement AvailableAnalysis by adding analysis made available by pass P. void PMDataManager::recordAvailableAnalysis(Pass *P) { @@ -586,8 +582,9 @@ bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) { for (std::vector::iterator I = HigherLevelAnalysis.begin(), E = HigherLevelAnalysis.end(); I != E; ++I) { Pass *P1 = *I; - if (!dynamic_cast(P1) - && std::find(PreservedSet.begin(), PreservedSet.end(), P1->getPassInfo()) == + if (!dynamic_cast(P1) && + std::find(PreservedSet.begin(), PreservedSet.end(), + P1->getPassInfo()) == PreservedSet.end()) return false; } @@ -624,9 +621,15 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { std::map::iterator Info = I++; if (!dynamic_cast(Info->second) && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == - PreservedSet.end()) + PreservedSet.end()) { // Remove this analysis AvailableAnalysis.erase(Info); + if (PassDebugging >= Details) { + Pass *S = Info->second; + cerr << " -- " << P->getPassName() << " is not preserving "; + cerr << S->getPassName() << "\n"; + } + } } // Check inherited analysis also. If P is not preserving analysis @@ -640,8 +643,8 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { I = InheritedAnalysis[Index]->begin(), E = InheritedAnalysis[Index]->end(); I != E; ) { std::map::iterator Info = I++; - if (!dynamic_cast(Info->second) - && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == + if (!dynamic_cast(Info->second) && + std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == PreservedSet.end()) // Remove this analysis InheritedAnalysis[Index]->erase(Info); @@ -662,6 +665,12 @@ 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"; + } + for (SmallVector::iterator I = DeadPasses.begin(), E = DeadPasses.end(); I != E; ++I) { @@ -917,7 +926,21 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { TPM->dumpArguments(); TPM->dumpPasses(); } - assert (0 && "Unable to handle Pass that requires lower level Analysis pass"); + + // Module Level pass may required Function Level analysis info + // (e.g. dominator info). Pass manager uses on the fly function pass manager + // to provide this on demand. In that case, in Pass manager terminology, + // module level pass is requiring lower level analysis info managed by + // lower level pass manager. + + // When Pass manager is not able to order required analysis info, Pass manager + // 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"; +#endif + assert (0 && "Unable to schedule pass"); } // Destructor @@ -927,7 +950,6 @@ PMDataManager::~PMDataManager() { E = PassVector.end(); I != E; ++I) delete *I; - PassVector.clear(); } //===----------------------------------------------------------------------===// @@ -972,7 +994,8 @@ BBPassManager::runOnFunction(Function &F) { if (TheTimeInfo) TheTimeInfo->passEnded(BP); if (Changed) - dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, I->getNameStart()); + dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, + I->getNameStart()); dumpAnalysisSetInfo("Preserved", BP, AnUsage.getPreservedSet()); verifyPreservedAnalysis(BP); @@ -1039,8 +1062,7 @@ FunctionPassManager::FunctionPassManager(ModuleProvider *P) { // FPM is the top level manager. FPM->setTopLevelManager(FPM); - PMDataManager *PMD = dynamic_cast(FPM); - AnalysisResolver *AR = new AnalysisResolver(*PMD); + AnalysisResolver *AR = new AnalysisResolver(*FPM); FPM->setResolver(AR); MP = P; @@ -1153,6 +1175,9 @@ bool FPPassManager::runOnFunction(Function &F) { if (F.isDeclaration()) return false; + + // Collect inherited analysis from Module level pass manager. + populateInheritedAnalysis(TPM->activeStack); for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); @@ -1229,7 +1254,8 @@ MPPassManager::runOnModule(Module &M) { AnalysisUsage AnUsage; MP->getAnalysisUsage(AnUsage); - dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier().c_str()); + dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, + M.getModuleIdentifier().c_str()); dumpAnalysisSetInfo("Required", MP, AnUsage.getRequiredSet()); initializeAnalysisImpl(MP); @@ -1239,7 +1265,8 @@ MPPassManager::runOnModule(Module &M) { if (TheTimeInfo) TheTimeInfo->passEnded(MP); if (Changed) - dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, M.getModuleIdentifier().c_str()); + dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, + M.getModuleIdentifier().c_str()); dumpAnalysisSetInfo("Preserved", MP, AnUsage.getPreservedSet()); verifyPreservedAnalysis(MP); @@ -1392,10 +1419,9 @@ void PMStack::pop() { } // Push PM on the stack and set its top level manager. -void PMStack::push(Pass *P) { +void PMStack::push(PMDataManager *PM) { PMDataManager *Top = NULL; - PMDataManager *PM = dynamic_cast(P); assert (PM && "Unable to push. Pass Manager expected"); if (this->empty()) { @@ -1464,6 +1490,7 @@ void FunctionPass::assignPassManager(PMStack &PMS, // [1] Create new Function Pass Manager FPP = new FPPassManager(PMD->getDepth() + 1); + FPP->populateInheritedAnalysis(PMS); // [2] Set up new manager's top level manager PMTopLevelManager *TPM = PMD->getTopLevelManager(); @@ -1471,14 +1498,13 @@ void FunctionPass::assignPassManager(PMStack &PMS, // [3] Assign manager to manage this new manager. This may create // and push new managers into PMS - Pass *P = dynamic_cast(FPP); // If Call Graph Pass Manager is active then use it to manage // this new Function Pass manager. if (PMD->getPassManagerType() == PMT_CallGraphPassManager) - P->assignPassManager(PMS, PMT_CallGraphPassManager); + FPP->assignPassManager(PMS, PMT_CallGraphPassManager); else - P->assignPassManager(PMS); + FPP->assignPassManager(PMS); // [4] Push new manager into PMS PMS.push(FPP); @@ -1517,8 +1543,7 @@ void BasicBlockPass::assignPassManager(PMStack &PMS, // [3] Assign manager to manage this new manager. This may create // and push new managers into PMS - Pass *P = dynamic_cast(BBP); - P->assignPassManager(PMS); + BBP->assignPassManager(PMS); // [4] Push new manager into PMS PMS.push(BBP); @@ -1528,4 +1553,34 @@ void BasicBlockPass::assignPassManager(PMStack &PMS, BBP->add(this); } +PassManagerBase::~PassManagerBase() {} + +/*===-- C Bindings --------------------------------------------------------===*/ + +LLVMPassManagerRef LLVMCreatePassManager() { + return wrap(new PassManager()); +} + +LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) { + return wrap(new FunctionPassManager(unwrap(P))); +} + +int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { + return unwrap(PM)->run(*unwrap(M)); +} + +int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) { + return unwrap(FPM)->doInitialization(); +} + +int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) { + return unwrap(FPM)->run(*unwrap(F)); +} + +int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) { + return unwrap(FPM)->doFinalization(); +} +void LLVMDisposePassManager(LLVMPassManagerRef PM) { + delete unwrap(PM); +}