Newer
Older
unsigned RDepth = 0;
assert(PRequired->getResolver() && "Analysis Resolver is not set");
PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
RDepth = DM.getDepth();
if (PDepth == RDepth)
LastUses.push_back(PRequired);
else if (PDepth > RDepth) {
// Let the parent claim responsibility of last use
TransferLastUses.push_back(PRequired);
// Keep track of higher level analysis used by this manager.
HigherLevelAnalysis.push_back(PRequired);
llvm_unreachable("Unable to accommodate Required Pass");
}
// Set P as P's last user until someone starts using P.
// However, if P is a Pass Manager then it does not need
// to record its last user.
LastUses.push_back(P);
TPM->setLastUser(LastUses, P);
if (!TransferLastUses.empty()) {
TPM->setLastUser(TransferLastUses, My_PM);
TransferLastUses.clear();
}
// Now, take care of required analyses that are not available.
E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
Pass *AnalysisPass = PI->createPass();
this->addLowerLevelRequiredPass(P, AnalysisPass);
// Take a note of analysis required and made available by this pass.
// Remove the analysis not preserved by this pass
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
// Add pass
PassVector.push_back(P);
}
/// Populate RP with analysis pass that are required by
/// pass P and are available. Populate RP_NotAvail with analysis
/// pass that are required by pass P but are not available.
void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP,
SmallVectorImpl<AnalysisID> &RP_NotAvail,
Pass *P) {
AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
if (Pass *AnalysisPass = findAnalysisPass(*I, true))
else
const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
if (Pass *AnalysisPass = findAnalysisPass(*I, true))
else
// All Required analyses should be available to the pass as it runs! Here
// we fill in the AnalysisImpls member of the pass so that it can
// successfully use the getAnalysis() method to retrieve the
// implementations it needs.
//
void PMDataManager::initializeAnalysisImpl(Pass *P) {
AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
for (AnalysisUsage::VectorType::const_iterator
I = AnUsage->getRequiredSet().begin(),
E = AnUsage->getRequiredSet().end(); I != E; ++I) {
Pass *Impl = findAnalysisPass(*I, true);
if (Impl == 0)
// This may be analysis pass that is initialized on the fly.
// If that is not the case then it will raise an assert when it is used.
continue;
AnalysisResolver *AR = P->getResolver();
assert(AR && "Analysis Resolver is not set");
AR->addAnalysisImplsPair(*I, Impl);
}
}
/// Find the pass that implements Analysis AID. If desired pass is not found
/// then return NULL.
Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
// Check if AvailableAnalysis map has one entry.
Michael Ilseman
committed
DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID);
if (I != AvailableAnalysis.end())
return I->second;
// Search Parents through TopLevelManager
if (SearchParent)
return TPM->findAnalysisPass(AID);
return NULL;
// Print list of passes that are last used by P.
void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
// If this is a on the fly manager then it does not have TPM.
if (!TPM)
return;
for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(),
llvm::dbgs() << "--" << std::string(Offset*2, ' ');
(*I)->dumpPassStructure(0);
}
}
void PMDataManager::dumpPassArguments() const {
for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(),
E = PassVector.end(); I != E; ++I) {
if (PMDataManager *PMD = (*I)->getAsPMDataManager())
if (const PassInfo *PI =
PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
enum PassDebuggingString S2,
dbgs() << (void*)this << std::string(getDepth()*2+1, ' ');
switch (S1) {
case EXECUTION_MSG:
dbgs() << "Executing Pass '" << P->getPassName();
break;
case MODIFICATION_MSG:
dbgs() << "Made Modification '" << P->getPassName();
break;
case FREEING_MSG:
dbgs() << " Freeing Pass '" << P->getPassName();
break;
default:
break;
}
switch (S2) {
case ON_BASICBLOCK_MSG:
dbgs() << "' on BasicBlock '" << Msg << "'...\n";
break;
case ON_FUNCTION_MSG:
dbgs() << "' on Function '" << Msg << "'...\n";
break;
case ON_MODULE_MSG:
case ON_REGION_MSG:
dbgs() << "' on Region '" << Msg << "'...\n";
break;
case ON_LOOP_MSG:
break;
case ON_CG_MSG:
dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
break;
default:
break;
}
Chris Lattner
committed
void PMDataManager::dumpRequiredSet(const Pass *P) const {
if (PassDebugging < Details)
return;
AnalysisUsage analysisUsage;
P->getAnalysisUsage(analysisUsage);
dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
}
Chris Lattner
committed
void PMDataManager::dumpPreservedSet(const Pass *P) const {
if (PassDebugging < Details)
return;
AnalysisUsage analysisUsage;
P->getAnalysisUsage(analysisUsage);
dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
}
void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
Chris Lattner
committed
const AnalysisUsage::VectorType &Set) const {
assert(PassDebugging >= Details);
if (Set.empty())
return;
dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
Chris Lattner
committed
for (unsigned i = 0; i != Set.size(); ++i) {
const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
if (!PInf) {
// Some preserved passes, such as AliasAnalysis, may not be initialized by
// all drivers.
dbgs() << " Uninitialized Pass";
continue;
}
dbgs() << ' ' << PInf->getPassName();
Chris Lattner
committed
}
/// Add RequiredPass into list of lower level passes required by pass P.
/// RequiredPass is run on the fly by Pass Manager when P requests it
/// through getAnalysis interface.
/// This should be handled by specific pass manager.
void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
if (TPM) {
TPM->dumpArguments();
TPM->dumpPasses();
}
// 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
dbgs() << "Unable to schedule '" << RequiredPass->getPassName();
dbgs() << "' required by '" << P->getPassName() << "'\n";
llvm_unreachable("Unable to schedule pass");
Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
llvm_unreachable("Unable to find on the fly pass");
}
// Destructor
PMDataManager::~PMDataManager() {
for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(),
E = PassVector.end(); I != E; ++I)
delete *I;
}
//===----------------------------------------------------------------------===//
// NOTE: Is this the right place to define this method ?
// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
return PM.findAnalysisPass(ID, dir);
}
Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
Function &F) {
return PM.getOnTheFlyPass(P, AnalysisPI, F);
}
//===----------------------------------------------------------------------===//
/// Execute all of the passes scheduled for execution by invoking
/// runOnBasicBlock method. Keep track of whether any of the passes modifies
/// the function, and if so, return true.
Chris Lattner
committed
bool BBPassManager::runOnFunction(Function &F) {
if (F.isDeclaration())
bool Changed = doInitialization(F);
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
BasicBlockPass *BP = getContainedPass(Index);
bool LocalChanged = false;
dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName());
dumpRequiredSet(BP);
initializeAnalysisImpl(BP);
Chris Lattner
committed
{
// If the pass crashes, remember this.
PassManagerPrettyStackEntry X(BP, *I);
TimeRegion PassTimer(getPassTimer(BP));
LocalChanged |= BP->runOnBasicBlock(*I);
Chris Lattner
committed
}
Changed |= LocalChanged;
dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
dumpPreservedSet(BP);
removeNotPreservedAnalysis(BP);
recordAvailableAnalysis(BP);
removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG);
return doFinalization(F) || Changed;
// Implement doInitialization and doFinalization
bool BBPassManager::doInitialization(Module &M) {
bool Changed = false;
Chris Lattner
committed
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
Changed |= getContainedPass(Index)->doInitialization(M);
return Changed;
}
bool BBPassManager::doFinalization(Module &M) {
bool Changed = false;
Chris Lattner
committed
Changed |= getContainedPass(Index)->doFinalization(M);
return Changed;
}
bool BBPassManager::doInitialization(Function &F) {
bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
BasicBlockPass *BP = getContainedPass(Index);
Changed |= BP->doInitialization(F);
}
return Changed;
}
bool BBPassManager::doFinalization(Function &F) {
bool Changed = false;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
BasicBlockPass *BP = getContainedPass(Index);
Changed |= BP->doFinalization(F);
}
return Changed;
}
//===----------------------------------------------------------------------===//
// FunctionPassManager implementation
Devang Patel
committed
/// Create new Function pass manager
Jeffrey Yasskin
committed
FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
FPM = new FunctionPassManagerImpl();
// FPM is the top level manager.
FPM->setTopLevelManager(FPM);
AnalysisResolver *AR = new AnalysisResolver(*FPM);
Devang Patel
committed
}
FunctionPassManager::~FunctionPassManager() {
Devang Patel
committed
/// 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'.
Devang Patel
committed
}
/// 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::run(Function &F) {
if (F.isMaterializable()) {
std::string errstr;
Benjamin Kramer
committed
report_fatal_error("Error reading bitcode file: " + Twine(errstr));
return FPM->run(F);
/// doInitialization - Run all of the initializers for the function passes.
///
bool FunctionPassManager::doInitialization() {
Jeffrey Yasskin
committed
return FPM->doInitialization(*M);
}
/// doFinalization - Run all of the finalizers for the function passes.
///
bool FunctionPassManager::doFinalization() {
Jeffrey Yasskin
committed
return FPM->doFinalization(*M);
}
//===----------------------------------------------------------------------===//
// FunctionPassManagerImpl implementation
//
bool FunctionPassManagerImpl::doInitialization(Module &M) {
dumpArguments();
dumpPasses();
SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
E = IPV.end(); I != E; ++I) {
Changed |= (*I)->doInitialization(M);
}
Chris Lattner
committed
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
Changed |= getContainedManager(Index)->doInitialization(M);
return Changed;
}
bool FunctionPassManagerImpl::doFinalization(Module &M) {
Chris Lattner
committed
Changed |= getContainedManager(Index)->doFinalization(M);
SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
E = IPV.end(); I != E; ++I) {
Changed |= (*I)->doFinalization(M);
}
/// cleanup - After running all passes, clean up pass manager cache.
void FPPassManager::cleanup() {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
AnalysisResolver *AR = FP->getResolver();
assert(AR && "Analysis Resolver is not set");
AR->clearAnalysisImpls();
}
}
Torok Edwin
committed
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();
}
}
Torok Edwin
committed
}
// 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) {
bool Changed = false;
TimingInfo::createTheTimeInfo();
initializeAllAnalysisInfo();
Chris Lattner
committed
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
Changed |= getContainedManager(Index)->runOnFunction(F);
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
getContainedManager(Index)->cleanup();
Torok Edwin
committed
wasRun = true;
return Changed;
}
//===----------------------------------------------------------------------===//
// FPPassManager implementation
/// Print passes managed by this manager
void FPPassManager::dumpPassStructure(unsigned Offset) {
dbgs().indent(Offset*2) << "FunctionPass Manager\n";
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
FP->dumpPassStructure(Offset + 1);
dumpLastUses(FP, Offset+1);
}
}
/// Execute all of the passes scheduled for execution by invoking
/// runOnFunction method. Keep track of whether any of the passes modifies
bool FPPassManager::runOnFunction(Function &F) {
bool Changed = false;
// Collect inherited analysis from Module level pass manager.
populateInheritedAnalysis(TPM->activeStack);
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
bool LocalChanged = false;
dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
dumpRequiredSet(FP);
initializeAnalysisImpl(FP);
Chris Lattner
committed
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
Chris Lattner
committed
LocalChanged |= FP->runOnFunction(F);
Chris Lattner
committed
}
Changed |= LocalChanged;
if (LocalChanged)
dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
dumpPreservedSet(FP);
removeNotPreservedAnalysis(FP);
recordAvailableAnalysis(FP);
removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
}
return Changed;
}
bool FPPassManager::runOnModule(Module &M) {
bool Changed = false;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Bill Wendling
committed
Changed |= runOnFunction(*I);
return Changed;
bool FPPassManager::doInitialization(Module &M) {
bool Changed = false;
Chris Lattner
committed
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
Changed |= getContainedPass(Index)->doInitialization(M);
return Changed;
}
bool FPPassManager::doFinalization(Module &M) {
bool Changed = false;
for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
Chris Lattner
committed
Changed |= getContainedPass(Index)->doFinalization(M);
return Changed;
}
//===----------------------------------------------------------------------===//
/// Execute all of the passes scheduled for execution by invoking
/// runOnModule method. Keep track of whether any of the passes modifies
/// the module, and if so, return true.
bool
MPPassManager::runOnModule(Module &M) {
Torok Edwin
committed
// 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);
}
// Initialize module passes
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
Changed |= getContainedPass(Index)->doInitialization(M);
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
ModulePass *MP = getContainedPass(Index);
bool LocalChanged = false;
dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
dumpRequiredSet(MP);
initializeAnalysisImpl(MP);
Chris Lattner
committed
{
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
LocalChanged |= MP->runOnModule(M);
Chris Lattner
committed
}
Changed |= LocalChanged;
if (LocalChanged)
dumpPreservedSet(MP);
removeNotPreservedAnalysis(MP);
recordAvailableAnalysis(MP);
removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
Torok Edwin
committed
// Finalize module passes
Changed |= getContainedPass(Index)->doFinalization(M);
Torok Edwin
committed
// 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);
}
/// Add RequiredPass into list of lower level passes required by pass P.
/// RequiredPass is run on the fly by Pass Manager when P requests it
/// through getAnalysis interface.
void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
assert(P->getPotentialPassManagerType() == PMT_ModulePassManager &&
"Unable to handle Pass that requires lower level Analysis pass");
RequiredPass->getPotentialPassManagerType()) &&
"Unable to handle Pass that requires lower level Analysis pass");
FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
if (!FPP) {
FPP = new FunctionPassManagerImpl();
// FPP is the top level manager.
FPP->setTopLevelManager(FPP);
OnTheFlyManagers[P] = FPP;
}
FPP->add(RequiredPass);
// Register P as the last user of RequiredPass.
if (RequiredPass) {
SmallVector<Pass *, 1> LU;
LU.push_back(RequiredPass);
FPP->setLastUser(LU, P);
}
}
/// Return function pass corresponding to PassInfo PI, that is
/// required by module pass MP. Instantiate analysis pass, by using
/// its runOnFunction() for function F.
Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
assert(FPP && "Unable to find on the fly pass");
Torok Edwin
committed
FPP->releaseMemoryOnTheFly();
return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
}
//===----------------------------------------------------------------------===//
// PassManagerImpl implementation
Owen Anderson
committed
/// 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 PassManagerImpl::run(Module &M) {
SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
E = IPV.end(); I != E; ++I) {
Changed |= (*I)->doInitialization(M);
}
initializeAllAnalysisInfo();
Chris Lattner
committed
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
Changed |= getContainedManager(Index)->runOnModule(M);
for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
E = IPV.end(); I != E; ++I) {
Changed |= (*I)->doFinalization(M);
}
//===----------------------------------------------------------------------===//
// PassManager implementation
/// Create new pass manager
PassManager::PassManager() {
PM = new PassManagerImpl();
// PM is the top level manager
PM->setTopLevelManager(PM);
}
PassManager::~PassManager() {
/// 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'.
}
/// 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.
return PM->run(M);
}
//===----------------------------------------------------------------------===//
// TimingInfo implementation
bool llvm::TimePassesIsEnabled = false;
static cl::opt<bool,true>
EnableTiming("time-passes", cl::location(TimePassesIsEnabled),
cl::desc("Time each pass, printing elapsed time for each on exit"));
// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to
// a non null value (if the -time-passes option is enabled) or it leaves it
// null. It may be called multiple times.
void TimingInfo::createTheTimeInfo() {
if (!TimePassesIsEnabled || TheTimeInfo) return;
Sylvestre Ledru
committed
// Constructed the first time this is called, iff -time-passes is enabled.
// This guarantees that the object will be constructed before static globals,
// thus it will be destroyed before them.
static ManagedStatic<TimingInfo> TTI;
TheTimeInfo = &*TTI;
}
/// If TimingInfo is enabled then start pass timer.
Timer *llvm::getPassTimer(Pass *P) {
return TheTimeInfo->getPassTimer(P);
return 0;
}
//===----------------------------------------------------------------------===//
// PMStack implementation
//
// Pop Pass Manager from the stack and clear its analysis info.
void PMStack::pop() {
PMDataManager *Top = this->top();
Top->initializeAnalysisInfo();
S.pop_back();
}
// Push PM on the stack and set its top level manager.
void PMStack::push(PMDataManager *PM) {
assert(PM && "Unable to push. Pass Manager expected");
assert(PM->getDepth()==0 && "Pass Manager depth set too early");
assert(PM->getPassManagerType() > this->top()->getPassManagerType()
&& "pushing bad pass manager to PMStack");
PMTopLevelManager *TPM = this->top()->getTopLevelManager();
assert(TPM && "Unable to find top level manager");
TPM->addIndirectPassManager(PM);
PM->setTopLevelManager(TPM);
PM->setDepth(this->top()->getDepth()+1);
assert((PM->getPassManagerType() == PMT_ModulePassManager
|| PM->getPassManagerType() == PMT_FunctionPassManager)
&& "pushing bad pass manager to PMStack");
PM->setDepth(1);
}
S.push_back(PM);
}
// Dump content of the pass manager stack.
void PMStack::dump() const {
for (std::vector<PMDataManager *>::const_iterator I = S.begin(),
dbgs() << (*I)->getAsPass()->getPassName() << ' ';
if (!S.empty())
}
/// Find appropriate Module Pass Manager in the PM Stack and
/// add self into that manager.
void ModulePass::assignPassManager(PMStack &PMS,
Anton Korobeynikov
committed
PassManagerType PreferredType) {
PassManagerType TopPMType = PMS.top()->getPassManagerType();
if (TopPMType == PreferredType)
break; // We found desired pass manager
else if (TopPMType > PMT_ModulePassManager)
PMS.pop(); // Pop children pass managers
assert(!PMS.empty() && "Unable to find appropriate Pass Manager");
PMS.top()->add(this);
/// Find appropriate Function Pass Manager or Call Graph Pass Manager
void FunctionPass::assignPassManager(PMStack &PMS,
Anton Korobeynikov
committed
PassManagerType PreferredType) {
// Find Function Pass Manager
if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
PMS.pop();
// Create new Function Pass Manager if needed.
FPPassManager *FPP;
if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) {
FPP = (FPPassManager *)PMS.top();
} else {
assert(!PMS.empty() && "Unable to create Function Pass Manager");
PMDataManager *PMD = PMS.top();
FPP = new FPPassManager();
FPP->populateInheritedAnalysis(PMS);
// [2] Set up new manager's top level manager
PMTopLevelManager *TPM = PMD->getTopLevelManager();
TPM->addIndirectPassManager(FPP);
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
// [4] Push new manager into PMS
PMS.push(FPP);
}
// Assign FPP as the manager of this pass.
FPP->add(this);
/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
void BasicBlockPass::assignPassManager(PMStack &PMS,
Anton Korobeynikov
committed
PassManagerType PreferredType) {
// Basic Pass Manager is a leaf pass manager. It does not handle
// any other pass manager.
PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) {
BBP = (BBPassManager *)PMS.top();
} else {
// If leaf manager is not Basic Block Pass manager then create new
// basic Block Pass manager.
assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
PMDataManager *PMD = PMS.top();
// [1] Create new Basic Block Manager
BBP = new BBPassManager();
// [2] Set up new manager's top level manager
// Basic Block Pass Manager does not live by itself
PMTopLevelManager *TPM = PMD->getTopLevelManager();
TPM->addIndirectPassManager(BBP);
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
// [4] Push new manager into PMS
PMS.push(BBP);
}
// Assign BBP as the manager of this pass.
BBP->add(this);
PassManagerBase::~PassManagerBase() {}