X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManager.cpp;h=53f11499e4b975ded1f1cd243083d8cf9e3bd429;hb=3e2d76c946ba753c2b11af192a52e25b6f9b46ff;hp=8846ac590863ea2c902948bd451d50dbbb5415fb;hpb=b84619223051fd965cc64e70c8f6b70f7ae6ae85;p=oota-llvm.git diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 8846ac59086..53f11499e4b 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -14,7 +14,6 @@ #include "llvm/PassManagers.h" #include "llvm/PassManager.h" -#include "llvm/DebugInfoProbe.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CommandLine.h" @@ -26,9 +25,7 @@ #include "llvm/Support/PassNameParser.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Mutex.h" -#include "llvm/ADT/StringMap.h" #include -#include #include using namespace llvm; @@ -85,32 +82,28 @@ PrintAfterAll("print-after-all", /// This is a helper to determine whether to print IR before or /// after a pass. -static bool ShouldPrintBeforeOrAfterPass(const void *PassID, +static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI, PassOptionList &PassesToPrint) { - if (const llvm::PassInfo *PI = - PassRegistry::getPassRegistry()->getPassInfo(PassID)) { - for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { - const llvm::PassInfo *PassInf = PassesToPrint[i]; - if (PassInf) - if (PassInf->getPassArgument() == PI->getPassArgument()) { - return true; - } - } + for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) { + const llvm::PassInfo *PassInf = PassesToPrint[i]; + if (PassInf) + if (PassInf->getPassArgument() == PI->getPassArgument()) { + return true; + } } return false; } - /// This is a utility to check whether a pass should have IR dumped /// before it. -static bool ShouldPrintBeforePass(const void *PassID) { - return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore); +static bool ShouldPrintBeforePass(const PassInfo *PI) { + return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore); } /// This is a utility to check whether a pass should have IR dumped /// after it. -static bool ShouldPrintAfterPass(const void *PassID) { - return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter); +static bool ShouldPrintAfterPass(const PassInfo *PI) { + return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter); } } // End of llvm namespace @@ -193,7 +186,7 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::dbgs() << std::string(Offset*2, ' ') << "BasicBlockPass Manager\n"; + llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); BP->dumpPassStructure(Offset + 1); @@ -224,6 +217,7 @@ namespace llvm { class FunctionPassManagerImpl : public Pass, public PMDataManager, public PMTopLevelManager { + virtual void anchor(); private: bool wasRun; public: @@ -264,27 +258,15 @@ public: 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(); } - void addTopLevelPass(Pass *P) { - 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. - AnalysisResolver *AR = new AnalysisResolver(*this); - P->setResolver(AR); - initializeAnalysisImpl(P); - addImmutablePass(IP); - recordAvailableAnalysis(IP); - } else { - P->assignPassManager(activeStack, PMT_FunctionPassManager); - } - - } - FPPassManager *getContainedManager(unsigned N) { assert(N < PassManagers.size() && "Pass number out of range!"); FPPassManager *FP = static_cast(PassManagers[N]); @@ -292,6 +274,8 @@ public: } }; +void FunctionPassManagerImpl::anchor() {} + char FunctionPassManagerImpl::ID = 0; //===----------------------------------------------------------------------===// @@ -349,7 +333,7 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::dbgs() << std::string(Offset*2, ' ') << "ModulePass Manager\n"; + llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); MP->dumpPassStructure(Offset + 1); @@ -385,6 +369,7 @@ char MPPassManager::ID = 0; class PassManagerImpl : public Pass, public PMDataManager, public PMTopLevelManager { + virtual void anchor(); public: static char ID; @@ -414,22 +399,11 @@ public: Info.setPreservesAll(); } - void addTopLevelPass(Pass *P) { - 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. - AnalysisResolver *AR = new AnalysisResolver(*this); - P->setResolver(AR); - initializeAnalysisImpl(P); - addImmutablePass(IP); - recordAvailableAnalysis(IP); - } else { - P->assignPassManager(activeStack, PMT_ModulePassManager); - } - } - 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!"); @@ -438,25 +412,13 @@ public: } }; +void PassManagerImpl::anchor() {} + char PassManagerImpl::ID = 0; } // End of llvm namespace namespace { -//===----------------------------------------------------------------------===// -// DebugInfoProbe - -static DebugInfoProbeInfo *TheDebugProbe; -static void createDebugInfoProbe() { - if (TheDebugProbe) return; - - // Constructed the first time this is called. This guarantees that the - // object will be constructed, if -enable-debug-info-probe is set, - // before static globals, thus it will be destroyed before them. - static ManagedStatic DIP; - TheDebugProbe = &*DIP; -} - //===----------------------------------------------------------------------===// /// TimingInfo Class - This class is used to calculate information about the /// amount of time each pass takes to execute. This only happens when @@ -516,8 +478,7 @@ PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) { /// Set pass P as the last user of the given analysis passes. void -PMTopLevelManager::setLastUser(const SmallVectorImpl &AnalysisPasses, - Pass *P) { +PMTopLevelManager::setLastUser(ArrayRef AnalysisPasses, Pass *P) { unsigned PDepth = 0; if (P->getResolver()) PDepth = P->getResolver()->getPMDataManager().getDepth(); @@ -632,6 +593,26 @@ void PMTopLevelManager::schedulePass(Pass *P) { 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 () == @@ -655,7 +636,32 @@ void PMTopLevelManager::schedulePass(Pass *P) { } // Now all required passes are available. - addTopLevelPass(P); + 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 @@ -1183,7 +1189,7 @@ void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, assert(PassDebugging >= Details); if (Set.empty()) return; - dbgs() << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; + dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; for (unsigned i = 0; i != Set.size(); ++i) { if (i) dbgs() << ','; const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]); @@ -1225,8 +1231,7 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { } Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { - assert(0 && "Unable to find on the fly pass"); - return NULL; + llvm_unreachable("Unable to find on the fly pass"); } // Destructor @@ -1352,31 +1357,13 @@ FunctionPassManager::~FunctionPassManager() { delete FPM; } -/// addImpl - Add a pass to the queue of passes to run, without -/// checking whether to add a printer pass. -void FunctionPassManager::addImpl(Pass *P) { - FPM->add(P); -} - /// 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'. void FunctionPassManager::add(Pass *P) { - // If this is a not a function pass, don't add a printer for it. - const void *PassID = P->getPassID(); - if (P->getPassKind() == PT_Function) - if (ShouldPrintBeforePass(PassID)) - addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") - + P->getPassName() + " ***")); - - addImpl(P); - - if (P->getPassKind() == PT_Function) - if (ShouldPrintAfterPass(PassID)) - addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") - + P->getPassName() + " ***")); + FPM->add(P); } /// run - Execute all of the passes scheduled for execution. Keep @@ -1456,7 +1443,6 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() { bool FunctionPassManagerImpl::run(Function &F) { bool Changed = false; TimingInfo::createTheTimeInfo(); - createDebugInfoProbe(); initializeAllAnalysisInfo(); for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) @@ -1475,7 +1461,7 @@ bool FunctionPassManagerImpl::run(Function &F) { char FPPassManager::ID = 0; /// Print passes managed by this manager void FPPassManager::dumpPassStructure(unsigned Offset) { - llvm::dbgs() << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; + dbgs().indent(Offset*2) << "FunctionPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); FP->dumpPassStructure(Offset + 1); @@ -1504,16 +1490,13 @@ bool FPPassManager::runOnFunction(Function &F) { dumpRequiredSet(FP); initializeAnalysisImpl(FP); - if (TheDebugProbe) - TheDebugProbe->initialize(FP, F); + { PassManagerPrettyStackEntry X(FP, F); TimeRegion PassTimer(getPassTimer(FP)); LocalChanged |= FP->runOnFunction(F); } - if (TheDebugProbe) - TheDebugProbe->finalize(FP, F); Changed |= LocalChanged; if (LocalChanged) @@ -1635,9 +1618,11 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { FPP->add(RequiredPass); // Register P as the last user of RequiredPass. - SmallVector LU; - LU.push_back(RequiredPass); - FPP->setLastUser(LU, P); + if (RequiredPass) { + SmallVector LU; + LU.push_back(RequiredPass); + FPP->setLastUser(LU, P); + } } /// Return function pass corresponding to PassInfo PI, that is @@ -1661,7 +1646,6 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ bool PassManagerImpl::run(Module &M) { bool Changed = false; TimingInfo::createTheTimeInfo(); - createDebugInfoProbe(); dumpArguments(); dumpPasses(); @@ -1686,27 +1670,12 @@ PassManager::~PassManager() { delete PM; } -/// addImpl - Add a pass to the queue of passes to run, without -/// checking whether to add a printer pass. -void PassManager::addImpl(Pass *P) { - PM->add(P); -} - /// 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) { - const void* PassID = P->getPassID(); - if (ShouldPrintBeforePass(PassID)) - addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ") - + P->getPassName() + " ***")); - - addImpl(P); - - if (ShouldPrintAfterPass(PassID)) - addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ") - + P->getPassName() + " ***")); + PM->add(P); } /// run - Execute all of the passes scheduled for execution. Keep track of @@ -1774,8 +1743,8 @@ void PMStack::push(PMDataManager *PM) { PM->setDepth(this->top()->getDepth()+1); } else { - assert(PM->getPassManagerType() == PMT_ModulePassManager - || PM->getPassManagerType() == PMT_FunctionPassManager + assert((PM->getPassManagerType() == PMT_ModulePassManager + || PM->getPassManagerType() == PMT_FunctionPassManager) && "pushing bad pass manager to PMStack"); PM->setDepth(1); } @@ -1787,10 +1756,10 @@ void PMStack::push(PMDataManager *PM) { void PMStack::dump() const { for (std::vector::const_iterator I = S.begin(), E = S.end(); I != E; ++I) - printf("%s ", (*I)->getAsPass()->getPassName()); + dbgs() << (*I)->getAsPass()->getPassName() << ' '; if (!S.empty()) - printf("\n"); + dbgs() << '\n'; } /// Find appropriate Module Pass Manager in the PM Stack and @@ -1816,7 +1785,7 @@ void ModulePass::assignPassManager(PMStack &PMS, void FunctionPass::assignPassManager(PMStack &PMS, PassManagerType PreferredType) { - // Find Module Pass Manager + // Find Function Pass Manager while (!PMS.empty()) { if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager) PMS.pop();