Skip to content
PassManager.cpp 61.8 KiB
Newer Older
         E = RequiredPasses.end(); I != E; ++I) {
    Pass *PRequired = *I;
    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);
Dan Gohman's avatar
Dan Gohman committed
    } else
      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.
  if (P->getAsPMDataManager() == 0)
    LastUses.push_back(P);
  TPM->setLastUser(LastUses, P);

  if (!TransferLastUses.empty()) {
    Pass *My_PM = getAsPass();
    TPM->setLastUser(TransferLastUses, My_PM);
    TransferLastUses.clear();
  }
  // Now, take care of required analyses that are not available.
Dan Gohman's avatar
Dan Gohman committed
  for (SmallVectorImpl<AnalysisID>::iterator
Dan Gohman's avatar
Dan Gohman committed
         I = ReqAnalysisNotAvailable.begin(),
         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);


/// 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,
  AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
  const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
Dan Gohman's avatar
Dan Gohman committed
  for (AnalysisUsage::VectorType::const_iterator
         I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
    if (Pass *AnalysisPass = findAnalysisPass(*I, true))
Dan Gohman's avatar
Dan Gohman committed
      RP.push_back(AnalysisPass);
      RP_NotAvail.push_back(*I);
  const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
  for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
         E = IDs.end(); I != E; ++I) {
    if (Pass *AnalysisPass = findAnalysisPass(*I, true))
Dan Gohman's avatar
Dan Gohman committed
      RP.push_back(AnalysisPass);
      RP_NotAvail.push_back(*I);
// 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);
      // 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.
  std::map<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);
Dan Gohman's avatar
Dan Gohman committed

// Print list of passes that are last used by P.
void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{

  SmallVector<Pass *, 12> LUses;

  // If this is a on the fly manager then it does not have TPM.
  if (!TPM)
    return;

  TPM->collectLastUses(LUses, P);
Dan Gohman's avatar
Dan Gohman committed

  for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(),
         E = LUses.end(); I != E; ++I) {
David Greene's avatar
David Greene committed
    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())
      PMD->dumpPassArguments();
    else
      if (const PassInfo *PI =
            PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
        if (!PI->isAnalysisGroup())
David Greene's avatar
David Greene committed
          dbgs() << " -" << PI->getPassArgument();
Chris Lattner's avatar
Chris Lattner committed
void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
                                 enum PassDebuggingString S2,
Daniel Dunbar's avatar
Daniel Dunbar committed
                                 StringRef Msg) {
  if (PassDebugging < Executions)
David Greene's avatar
David Greene committed
  dbgs() << (void*)this << std::string(getDepth()*2+1, ' ');
  switch (S1) {
  case EXECUTION_MSG:
David Greene's avatar
David Greene committed
    dbgs() << "Executing Pass '" << P->getPassName();
David Greene's avatar
David Greene committed
    dbgs() << "Made Modification '" << P->getPassName();
David Greene's avatar
David Greene committed
    dbgs() << " Freeing Pass '" << P->getPassName();
    break;
  default:
    break;
  }
  switch (S2) {
  case ON_BASICBLOCK_MSG:
David Greene's avatar
David Greene committed
    dbgs() << "' on BasicBlock '" << Msg << "'...\n";
David Greene's avatar
David Greene committed
    dbgs() << "' on Function '" << Msg << "'...\n";
David Greene's avatar
David Greene committed
    dbgs() << "' on Module '"  << Msg << "'...\n";
Tobias Grosser's avatar
Tobias Grosser committed
  case ON_REGION_MSG:
    dbgs() << "' on Region '"  << Msg << "'...\n";
    break;
David Greene's avatar
David Greene committed
    dbgs() << "' on Loop '" << Msg << "'...\n";
David Greene's avatar
David Greene committed
    dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
void PMDataManager::dumpRequiredSet(const Pass *P) const {
Dan Gohman's avatar
Dan Gohman committed

  AnalysisUsage analysisUsage;
  P->getAnalysisUsage(analysisUsage);
  dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
}

void PMDataManager::dumpPreservedSet(const Pass *P) const {
Dan Gohman's avatar
Dan Gohman committed

  AnalysisUsage analysisUsage;
  P->getAnalysisUsage(analysisUsage);
  dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
}

Daniel Dunbar's avatar
Daniel Dunbar committed
void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
                                   const AnalysisUsage::VectorType &Set) const {
  assert(PassDebugging >= Details);
  if (Set.empty())
    return;
  dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
  for (unsigned i = 0; i != Set.size(); ++i) {
David Greene's avatar
David Greene committed
    if (i) dbgs() << ',';
    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();
David Greene's avatar
David Greene committed
  dbgs() << '\n';
/// 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();
  }
Dan Gohman's avatar
Dan Gohman committed
  // 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
Dan Gohman's avatar
Dan Gohman committed
  // checks whether any lower level manager will be able to provide this
  // analysis info on demand or not.
David Greene's avatar
David Greene committed
  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);
}

Dan Gohman's avatar
Dan Gohman committed
Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
                                     Function &F) {
  return PM.getOnTheFlyPass(P, AnalysisPI, F);
}

//===----------------------------------------------------------------------===//
// BBPassManager implementation
Dan Gohman's avatar
Dan Gohman committed
/// 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.
bool BBPassManager::runOnFunction(Function &F) {
  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);
      dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName());
      {
        // If the pass crashes, remember this.
        PassManagerPrettyStackEntry X(BP, *I);
        TimeRegion PassTimer(getPassTimer(BP));

        LocalChanged |= BP->runOnBasicBlock(*I);
Dan Gohman's avatar
Dan Gohman committed
      if (LocalChanged)
Dan Gohman's avatar
Dan Gohman committed
        dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
Devang Patel's avatar
Devang Patel committed
      verifyPreservedAnalysis(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) {
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
    Changed |= getContainedPass(Index)->doInitialization(M);
bool BBPassManager::doFinalization(Module &M) {
Pedro Artigas's avatar
 
Pedro Artigas committed
  for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
    Changed |= getContainedPass(Index)->doFinalization(M);
bool BBPassManager::doInitialization(Function &F) {
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
    BasicBlockPass *BP = getContainedPass(Index);
    Changed |= BP->doInitialization(F);
  }

  return Changed;
}

bool BBPassManager::doFinalization(Function &F) {
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
    BasicBlockPass *BP = getContainedPass(Index);
//===----------------------------------------------------------------------===//
// FunctionPassManager implementation
FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
  FPM = new FunctionPassManagerImpl();
Devang Patel's avatar
Devang Patel committed
  // FPM is the top level manager.
  FPM->setTopLevelManager(FPM);
  AnalysisResolver *AR = new AnalysisResolver(*FPM);
Devang Patel's avatar
Devang Patel committed
  FPM->setResolver(AR);
FunctionPassManager::~FunctionPassManager() {
/// 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'.
Dan Gohman's avatar
Dan Gohman committed
void FunctionPassManager::add(Pass *P) {
/// 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;
Chris Lattner's avatar
Chris Lattner committed
    if (F.Materialize(&errstr))
      report_fatal_error("Error reading bitcode file: " + Twine(errstr));
/// doInitialization - Run all of the initializers for the function passes.
///
bool FunctionPassManager::doInitialization() {
/// doFinalization - Run all of the finalizers for the function passes.
bool FunctionPassManager::doFinalization() {
//===----------------------------------------------------------------------===//
// FunctionPassManagerImpl implementation
//
bool FunctionPassManagerImpl::doInitialization(Module &M) {
  bool Changed = false;

Pedro Artigas's avatar
 
Pedro Artigas committed
  SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
  for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
       E = IPV.end(); I != E; ++I) {
    Changed |= (*I)->doInitialization(M);
  }

  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
    Changed |= getContainedManager(Index)->doInitialization(M);
bool FunctionPassManagerImpl::doFinalization(Module &M) {
  bool Changed = false;

Pedro Artigas's avatar
 
Pedro Artigas committed
  for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
    Changed |= getContainedManager(Index)->doFinalization(M);
Pedro Artigas's avatar
 
Pedro Artigas committed
  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();
 }
}

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) {
  bool Changed = false;
  TimingInfo::createTheTimeInfo();

  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
    Changed |= getContainedManager(Index)->runOnFunction(F);

  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
    getContainedManager(Index)->cleanup();

  return Changed;
}

//===----------------------------------------------------------------------===//
// FPPassManager implementation
Devang Patel's avatar
Devang Patel committed
char FPPassManager::ID = 0;
/// 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);
Dan Gohman's avatar
Dan Gohman committed
/// Execute all of the passes scheduled for execution by invoking
/// runOnFunction method.  Keep track of whether any of the passes modifies
/// the function, and if so, return true.
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);
    dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
      TimeRegion PassTimer(getPassTimer(FP));
      LocalChanged |= FP->runOnFunction(F);
    Changed |= LocalChanged;
    if (LocalChanged)
      dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
Devang Patel's avatar
Devang Patel committed
    verifyPreservedAnalysis(FP);
    removeNotPreservedAnalysis(FP);
    recordAvailableAnalysis(FP);
    removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
bool FPPassManager::runOnModule(Module &M) {
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
bool FPPassManager::doInitialization(Module &M) {
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
    Changed |= getContainedPass(Index)->doInitialization(M);
bool FPPassManager::doFinalization(Module &M) {
Pedro Artigas's avatar
 
Pedro Artigas committed

  for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
    Changed |= getContainedPass(Index)->doFinalization(M);
//===----------------------------------------------------------------------===//
// MPPassManager implementation
Dan Gohman's avatar
Dan Gohman committed
/// Execute all of the passes scheduled for execution by invoking
/// runOnModule method.  Keep track of whether any of the passes modifies
Devang Patel's avatar
Devang Patel committed
/// the module, and if so, return true.
bool
MPPassManager::runOnModule(Module &M) {
Devang Patel's avatar
Devang Patel committed
  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);
  }

  // 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);
    dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
      TimeRegion PassTimer(getPassTimer(MP));

      LocalChanged |= MP->runOnModule(M);
    Changed |= LocalChanged;
    if (LocalChanged)
Dan Gohman's avatar
Dan Gohman committed
      dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
                   M.getModuleIdentifier());
Dan Gohman's avatar
Dan Gohman committed

Devang Patel's avatar
Devang Patel committed
    verifyPreservedAnalysis(MP);
    removeNotPreservedAnalysis(MP);
    recordAvailableAnalysis(MP);
    removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
Pedro Artigas's avatar
 
Pedro Artigas committed
  for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
    Changed |= getContainedPass(Index)->doFinalization(M);

  // 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);
  }
Devang Patel's avatar
Devang Patel committed
  return Changed;
}

/// 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");
Dan Gohman's avatar
Dan Gohman committed
  assert((P->getPotentialPassManagerType() <
          RequiredPass->getPotentialPassManagerType()) &&
         "Unable to handle Pass that requires lower level Analysis pass");
  FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
    FPP = new FunctionPassManagerImpl();
    // FPP is the top level manager.
    FPP->setTopLevelManager(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);
  }
Dan Gohman's avatar
Dan Gohman committed
/// 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");
Dan Gohman's avatar
Dan Gohman committed

  return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
//===----------------------------------------------------------------------===//
// PassManagerImpl implementation
Devang Patel's avatar
Devang Patel 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) {
Devang Patel's avatar
Devang Patel committed
  bool Changed = false;
Devang Patel's avatar
Devang Patel committed
  TimingInfo::createTheTimeInfo();

  dumpPasses();
Pedro Artigas's avatar
 
Pedro Artigas committed
  SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
  for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
       E = IPV.end(); I != E; ++I) {
    Changed |= (*I)->doInitialization(M);
  }

  for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
    Changed |= getContainedManager(Index)->runOnModule(M);
Pedro Artigas's avatar
 
Pedro Artigas committed

  for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
       E = IPV.end(); I != E; ++I) {
    Changed |= (*I)->doFinalization(M);
  }

Devang Patel's avatar
Devang Patel committed
  return Changed;
}
//===----------------------------------------------------------------------===//
// PassManager implementation

  PM = new PassManagerImpl();
Devang Patel's avatar
Devang Patel committed
  // PM is the top level manager
  PM->setTopLevelManager(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::add(Pass *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::run(Module &M) {
Devang Patel's avatar
Devang Patel committed
//===----------------------------------------------------------------------===//
// TimingInfo Class - This class is used to calculate information about the
// amount of time each pass takes to execute.  This only happens with
// -time-passes is enabled on the command line.
//
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;

  // Constructed the first time this is called, iff -time-passes is enabled.
Devang Patel's avatar
Devang Patel committed
  // 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) {
Dan Gohman's avatar
Dan Gohman committed
  if (TheTimeInfo)
    return TheTimeInfo->getPassTimer(P);
//===----------------------------------------------------------------------===//
// 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");
  if (!this->empty()) {
    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);
  }
  else {
    assert((PM->getPassManagerType() == PMT_ModulePassManager
           || PM->getPassManagerType() == PMT_FunctionPassManager)
           && "pushing bad pass manager to PMStack");
    PM->setDepth(1);
// Dump content of the pass manager stack.
void PMStack::dump() const {
  for (std::vector<PMDataManager *>::const_iterator I = S.begin(),
         E = S.end(); I != E; ++I)
    dbgs() << (*I)->getAsPass()->getPassName() << ' ';
    dbgs() << '\n';
}

/// Find appropriate Module Pass Manager in the PM Stack and
Dan Gohman's avatar
Dan Gohman committed
/// add self into that manager.
void ModulePass::assignPassManager(PMStack &PMS,
  // Find Module Pass Manager
Dan Gohman's avatar
Dan Gohman committed
  while (!PMS.empty()) {
    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
Devang Patel's avatar
Devang Patel committed
  assert(!PMS.empty() && "Unable to find appropriate Pass Manager");
Devang Patel's avatar
Devang Patel committed
/// Find appropriate Function Pass Manager or Call Graph Pass Manager
Dan Gohman's avatar
Dan Gohman committed
/// in the PM Stack and add self into that manager.
void FunctionPass::assignPassManager(PMStack &PMS,
  // Find Function Pass Manager
  while (!PMS.empty()) {
    if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
      PMS.pop();
Dan Gohman's avatar
Dan Gohman committed
      break;
  // Create new Function Pass Manager if needed.
  FPPassManager *FPP;
  if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) {
    FPP = (FPPassManager *)PMS.top();
  } else {
Devang Patel's avatar
Devang Patel committed
    assert(!PMS.empty() && "Unable to create Function Pass Manager");
    PMDataManager *PMD = PMS.top();
Devang Patel's avatar
Devang Patel committed
    // [1] Create new Function Pass Manager
    FPP = new FPPassManager();
    FPP->populateInheritedAnalysis(PMS);
Devang Patel's avatar
Devang Patel committed
    // [2] Set up new manager's top level manager
    PMTopLevelManager *TPM = PMD->getTopLevelManager();
    TPM->addIndirectPassManager(FPP);
Devang Patel's avatar
Devang Patel committed
    // [3] Assign manager to manage this new manager. This may create
    // and push new managers into PMS
Devang Patel's avatar
Devang Patel committed
    FPP->assignPassManager(PMS, PMD->getPassManagerType());
Devang Patel's avatar
Devang Patel committed

    // [4] Push new manager into PMS
    PMS.push(FPP);
  }
Devang Patel's avatar
Devang Patel committed
  // Assign FPP as the manager of this pass.
  FPP->add(this);
Devang Patel's avatar
Devang Patel committed
/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
Dan Gohman's avatar
Dan Gohman committed
/// in the PM Stack and add self into that manager.
void BasicBlockPass::assignPassManager(PMStack &PMS,
  BBPassManager *BBP;
  // Basic Pass Manager is a leaf pass manager. It does not handle
  // any other pass manager.
Dan Gohman's avatar
Dan Gohman committed
  if (!PMS.empty() &&
      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.
Devang Patel's avatar
Devang Patel committed
    assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
    PMDataManager *PMD = PMS.top();

    // [1] Create new Basic Block Manager
    BBP = new BBPassManager();
Devang Patel's avatar
Devang Patel committed

    // [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
David Greene's avatar
 
David Greene committed
    BBP->assignPassManager(PMS, PreferredType);
Devang Patel's avatar
Devang Patel committed
    // [4] Push new manager into PMS
    PMS.push(BBP);
  }
Devang Patel's avatar
Devang Patel committed
  // Assign BBP as the manager of this pass.
  BBP->add(this);
PassManagerBase::~PassManagerBase() {}