-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// FunctionPassManagerImpl
-//
-/// FunctionPassManagerImpl manages FPPassManagers
-class FunctionPassManagerImpl : public Pass,
- public PMDataManager,
- public PMTopLevelManager {
- virtual void anchor();
-private:
- bool wasRun;
-public:
- static char ID;
- explicit FunctionPassManagerImpl() :
- Pass(PT_PassManager, ID), PMDataManager(),
- PMTopLevelManager(new FPPassManager()), 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
- /// 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 add(Pass *P) {
- schedulePass(P);
- }
-
- /// createPrinterPass - Get a function printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintFunctionPass(Banner, &O);
- }
-
- // 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);
-
- /// doInitialization - Run all of the initializers for the function passes.
- ///
- bool doInitialization(Module &M);
-
- /// doFinalization - Run all of the finalizers for the function passes.
- ///
- bool doFinalization(Module &M);
-
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
- virtual PassManagerType getTopLevelPassManagerType() {
- return PMT_FunctionPassManager;
- }
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- FPPassManager *getContainedManager(unsigned N) {
- assert(N < PassManagers.size() && "Pass number out of range!");
- FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
- return FP;
- }
-};
-
-void FunctionPassManagerImpl::anchor() {}
-
-char FunctionPassManagerImpl::ID = 0;
-
-//===----------------------------------------------------------------------===//
-// MPPassManager
-//
-/// MPPassManager manages ModulePasses and function pass managers.
-/// 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;
- explicit MPPassManager() :
- Pass(PT_PassManager, ID), PMDataManager() { }
-
- // Delete on the fly managers.
- virtual ~MPPassManager() {
- for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
- I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
- I != E; ++I) {
- FunctionPassManagerImpl *FPP = I->second;
- delete FPP;
- }
- }
-
- /// createPrinterPass - Get a module printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintModulePass(&O, false, Banner);
- }
-
- /// 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 runOnModule(Module &M);
-
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
-
- /// doInitialization - Run all of the initializers for the module passes.
- ///
- bool doInitialization();
-
- /// doFinalization - Run all of the finalizers for the module passes.
- ///
- bool doFinalization();
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- /// 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.
- virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
-
- /// Return function pass corresponding to PassInfo PI, that is
- /// required by module pass MP. Instantiate analysis pass, by using
- /// its runOnFunction() for function F.
- virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F);
-
- virtual const char *getPassName() const {
- return "Module Pass Manager";
- }
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
-
- // Print passes managed by this manager
- void dumpPassStructure(unsigned Offset) {
- llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n";
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- ModulePass *MP = getContainedPass(Index);
- MP->dumpPassStructure(Offset + 1);
- std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I =
- OnTheFlyManagers.find(MP);
- if (I != OnTheFlyManagers.end())
- I->second->dumpPassStructure(Offset + 2);
- dumpLastUses(MP, Offset+1);
- }
- }
-
- ModulePass *getContainedPass(unsigned N) {
- assert(N < PassVector.size() && "Pass number out of range!");
- return static_cast<ModulePass *>(PassVector[N]);
- }
-
- virtual PassManagerType getPassManagerType() const {
- return PMT_ModulePassManager;
- }
-
- private:
- /// Collection of on the fly FPPassManagers. These managers manage
- /// function passes that are required by module passes.
- std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers;
-};
-
-char MPPassManager::ID = 0;
-//===----------------------------------------------------------------------===//
-// PassManagerImpl
-//
-
-/// PassManagerImpl manages MPPassManagers
-class PassManagerImpl : public Pass,
- public PMDataManager,
- public PMTopLevelManager {
- virtual void anchor();
-
-public:
- static char ID;
- explicit PassManagerImpl() :
- Pass(PT_PassManager, ID), PMDataManager(),
- PMTopLevelManager(new MPPassManager()) {}
-
- /// 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 add(Pass *P) {
- schedulePass(P);
- }
-
- /// createPrinterPass - Get a module printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintModulePass(&O, false, Banner);
- }
-
- /// 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(Module &M);
-
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
-
- /// doInitialization - Run all of the initializers for the module passes.
- ///
- bool doInitialization();
-
- /// doFinalization - Run all of the finalizers for the module passes.
- ///
- bool doFinalization();
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
- virtual PassManagerType getTopLevelPassManagerType() {
- return PMT_ModulePassManager;
- }
-
- MPPassManager *getContainedManager(unsigned N) {
- assert(N < PassManagers.size() && "Pass number out of range!");
- MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
- return MP;
- }
-};
-
-void PassManagerImpl::anchor() {}
-
-char PassManagerImpl::ID = 0;
-} // End of llvm namespace
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-/// TimingInfo Class - This class is used to calculate information about the
-/// amount of time each pass takes to execute. This only happens when
-/// -time-passes is enabled on the command line.
-///
-
-static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
-
-class TimingInfo {
- DenseMap<Pass*, Timer*> TimingData;
- TimerGroup TG;
-public:
- // Use 'create' member to get this.
- TimingInfo() : TG("... Pass execution timing report ...") {}
-
- // TimingDtor - Print out information about timing information
- ~TimingInfo() {
- // Delete all of the timers, which accumulate their info into the
- // TimerGroup.
- for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(),
- E = TimingData.end(); I != E; ++I)
- delete I->second;
- // TimerGroup is deleted next, printing the report.
- }
-
- // 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.
- static void createTheTimeInfo();
-
- /// getPassTimer - Return the timer for the specified pass if it exists.
- Timer *getPassTimer(Pass *P) {
- if (P->getAsPMDataManager())
- return 0;
-
- sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
- Timer *&T = TimingData[P];
- if (T == 0)
- T = new Timer(P->getPassName(), TG);
- return T;
- }
-};
-
-} // End of anon namespace
-
-static TimingInfo *TheTimeInfo;
-
-//===----------------------------------------------------------------------===//
-// PMTopLevelManager implementation
-
-/// Initialize top level manager. Create first pass manager.
-PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
- PMDM->setTopLevelManager(this);
- addPassManager(PMDM);
- activeStack.push(PMDM);
-}
-
-/// Set pass P as the last user of the given analysis passes.
-void
-PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
- unsigned PDepth = 0;
- if (P->getResolver())
- PDepth = P->getResolver()->getPMDataManager().getDepth();
-
- for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(),
- E = AnalysisPasses.end(); I != E; ++I) {
- Pass *AP = *I;
- LastUser[AP] = P;
-
- if (P == AP)
- continue;
-
- // Update the last users of passes that are required transitive by AP.
- AnalysisUsage *AnUsage = findAnalysisUsage(AP);
- const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
- SmallVector<Pass *, 12> LastUses;
- SmallVector<Pass *, 12> LastPMUses;
- for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
- E = IDs.end(); I != E; ++I) {
- Pass *AnalysisPass = findAnalysisPass(*I);
- assert(AnalysisPass && "Expected analysis pass to exist.");
- AnalysisResolver *AR = AnalysisPass->getResolver();
- assert(AR && "Expected analysis resolver to exist.");
- unsigned APDepth = AR->getPMDataManager().getDepth();
-
- if (PDepth == APDepth)
- LastUses.push_back(AnalysisPass);
- else if (PDepth > APDepth)
- LastPMUses.push_back(AnalysisPass);
- }
-
- setLastUser(LastUses, P);
-
- // If this pass has a corresponding pass manager, push higher level
- // analysis to this pass manager.
- if (P->getResolver())
- setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass());
-
-
- // If AP is the last user of other passes then make P last user of
- // such passes.
- for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(),
- LUE = LastUser.end(); LUI != LUE; ++LUI) {
- if (LUI->second == AP)
- // DenseMap iterator is not invalidated here because
- // this is just updating existing entries.
- LastUser[LUI->first] = P;
- }
- }
-}
-
-/// Collect passes whose last user is P
-void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
- Pass *P) {
- DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI =
- InversedLastUser.find(P);
- if (DMI == InversedLastUser.end())
- return;
-
- SmallPtrSet<Pass *, 8> &LU = DMI->second;
- for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(),
- E = LU.end(); I != E; ++I) {
- LastUses.push_back(*I);
- }
-
-}
-
-AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
- AnalysisUsage *AnUsage = NULL;
- DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P);
- if (DMI != AnUsageMap.end())
- AnUsage = DMI->second;
- else {
- AnUsage = new AnalysisUsage();
- P->getAnalysisUsage(*AnUsage);
- AnUsageMap[P] = AnUsage;
- }
- return AnUsage;
-}
-
-/// Schedule pass P for execution. Make sure that passes required by
-/// P are run before P is run. Update analysis info maintained by
-/// the manager. Remove dead passes. This is a recursive function.
-void PMTopLevelManager::schedulePass(Pass *P) {
-
- // TODO : Allocate function manager for this pass, other wise required set
- // may be inserted into previous function manager
-
- // 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.
- const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo(P->getPassID());
- if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
- delete P;
- return;
- }
-
- AnalysisUsage *AnUsage = findAnalysisUsage(P);
-
- bool checkAnalysis = true;
- while (checkAnalysis) {
- checkAnalysis = false;
-
- const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
- for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(),
- E = RequiredSet.end(); I != E; ++I) {
-
- Pass *AnalysisPass = findAnalysisPass(*I);
- if (!AnalysisPass) {
- const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
-
- if (PI == NULL) {
- // Pass P is not in the global PassRegistry
- dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n";
- dbgs() << "Verify if there is a pass dependency cycle." << "\n";
- dbgs() << "Required Passes:" << "\n";
- for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(),
- E = RequiredSet.end(); I2 != E && I2 != I; ++I2) {
- Pass *AnalysisPass2 = findAnalysisPass(*I2);
- if (AnalysisPass2) {
- dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
- }
- else {
- dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n";
- dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n";
- dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n";
- }
- }
- }
-
- assert(PI && "Expected required passes to be initialized");
- AnalysisPass = PI->createPass();
- if (P->getPotentialPassManagerType () ==
- AnalysisPass->getPotentialPassManagerType())
- // Schedule analysis pass that is managed by the same pass manager.
- schedulePass(AnalysisPass);
- else if (P->getPotentialPassManagerType () >
- AnalysisPass->getPotentialPassManagerType()) {
- // Schedule analysis pass that is managed by a new manager.
- schedulePass(AnalysisPass);
- // Recheck analysis passes to ensure that required analyses that
- // are already checked are still available.
- checkAnalysis = true;
- }
- else
- // Do not schedule this analysis. Lower level analsyis
- // passes are run on the fly.
- delete AnalysisPass;
- }
- }
- }
-
- // Now all required passes are available.
- if (ImmutablePass *IP = P->getAsImmutablePass()) {
- // P is a immutable pass and it will be managed by this
- // top level manager. Set up analysis resolver to connect them.
- PMDataManager *DM = getAsPMDataManager();
- AnalysisResolver *AR = new AnalysisResolver(*DM);
- P->setResolver(AR);
- DM->initializeAnalysisImpl(P);
- addImmutablePass(IP);
- DM->recordAvailableAnalysis(IP);
- return;
- }
-
- if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
- Pass *PP = P->createPrinterPass(
- dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***");
- PP->assignPassManager(activeStack, getTopLevelPassManagerType());
- }
-
- // Add the requested pass to the best available pass manager.
- P->assignPassManager(activeStack, getTopLevelPassManagerType());
-
- if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
- Pass *PP = P->createPrinterPass(
- dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***");
- PP->assignPassManager(activeStack, getTopLevelPassManagerType());
- }
-}
-
-/// Find the pass that implements Analysis AID. Search immutable
-/// passes and all pass managers. If desired pass is not found
-/// then return NULL.
-Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
-
- // Check pass managers
- for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
- E = PassManagers.end(); I != E; ++I)
- if (Pass *P = (*I)->findAnalysisPass(AID, false))
- return P;
-
- // Check other pass managers
- for (SmallVectorImpl<PMDataManager *>::iterator
- I = IndirectPassManagers.begin(),
- E = IndirectPassManagers.end(); I != E; ++I)
- if (Pass *P = (*I)->findAnalysisPass(AID, false))
- return P;
-
- // Check the immutable passes. Iterate in reverse order so that we find
- // the most recently registered passes first.
- for (SmallVector<ImmutablePass *, 8>::reverse_iterator I =
- ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) {
- AnalysisID PI = (*I)->getPassID();
- if (PI == AID)
- return *I;
-
- // If Pass not found then check the interfaces implemented by Immutable Pass
- const PassInfo *PassInf =
- PassRegistry::getPassRegistry()->getPassInfo(PI);
- assert(PassInf && "Expected all immutable passes to be initialized");
- const std::vector<const PassInfo*> &ImmPI =
- PassInf->getInterfacesImplemented();
- for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
- EE = ImmPI.end(); II != EE; ++II) {
- if ((*II)->getTypeInfo() == AID)
- return *I;
- }
- }
-
- return 0;
-}
-
-// Print passes managed by this top level manager.
-void PMTopLevelManager::dumpPasses() const {
-
- if (PassDebugging < Structure)
- return;
-
- // Print out the immutable passes
- for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
- ImmutablePasses[i]->dumpPassStructure(0);
- }
-
- // 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 getAsPass to get
- // from a PMDataManager* to a Pass*.
- for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
- E = PassManagers.end(); I != E; ++I)
- (*I)->getAsPass()->dumpPassStructure(1);