diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index c94a098a842..29912b140d7 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/PassManager.h" - +#include "llvm/ADT/SmallVector.h" using namespace llvm; class llvm::PMDataManager; class llvm::PMStack; @@ -221,6 +221,19 @@ public: /// AvailableAnalysis appropriately if ProcessAnalysis is true. void add(Pass *P, bool ProcessAnalysis = true); + /// 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) { + assert (0 && + "Unable to handle Pass that requires lower level Analysis pass"); + } + + virtual Pass * getOnTheFlyPass(Pass *P, const PassInfo *PI, Function &F) { + assert (0 && "Unable to find on the fly pass"); + return NULL; + } + /// Initialize available analysis information. void initializeAnalysisInfo() { AvailableAnalysis.clear(); @@ -233,10 +246,12 @@ public: bool preserveHigherLevelAnalysis(Pass *P); - /// Populate RequiredPasses with the analysis pass that are required by - /// pass P. - void collectRequiredAnalysisPasses(std::vector &RequiredPasses, - Pass *P); + /// Populate RequiredPasses with analysis pass that are required by + /// pass P and are available. Populate ReqPassNotAvailable with analysis + /// pass that are required by pass P but are not available. + void collectRequiredAnalysis(SmallVector &RequiredPasses, + SmallVector &ReqPassNotAvailable, + Pass *P); /// 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 diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 37b8a5fbf3d..02a27c25273 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -190,6 +190,11 @@ public: 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); + virtual const char *getPassName() const { return "Module Pass Manager"; } @@ -400,9 +405,14 @@ void PMTopLevelManager::schedulePass(Pass *P) { Pass *AnalysisPass = findAnalysisPass(*I); if (!AnalysisPass) { - // Schedule this analysis run first. AnalysisPass = (*I)->createPass(); - schedulePass(AnalysisPass); + // Schedule this analysis run first only if it is not a lower level + // analysis pass. Lower level analsyis passes are run on the fly. + if (P->getPotentialPassManagerType () >= + AnalysisPass->getPotentialPassManagerType()) + schedulePass(AnalysisPass); + else + delete AnalysisPass; } } @@ -642,11 +652,14 @@ void PMDataManager::add(Pass *P, // At the moment, this pass is the last user of all required passes. std::vector LastUses; - std::vector RequiredPasses; + SmallVector RequiredPasses; + SmallVector ReqAnalysisNotAvailable; + unsigned PDepth = this->getDepth(); - collectRequiredAnalysisPasses(RequiredPasses, P); - for (std::vector::iterator I = RequiredPasses.begin(), + collectRequiredAnalysis(RequiredPasses, + ReqAnalysisNotAvailable, P); + for (SmallVector::iterator I = RequiredPasses.begin(), E = RequiredPasses.end(); I != E; ++I) { Pass *PRequired = *I; unsigned RDepth = 0; @@ -661,11 +674,16 @@ void PMDataManager::add(Pass *P, TransferLastUses.push_back(PRequired); // Keep track of higher level analysis used by this manager. HigherLevelAnalysis.push_back(PRequired); - } else { - // Note : This feature is not yet implemented - assert (0 && - "Unable to handle Pass that requires lower level Analysis pass"); - } + } else + assert (0 && "Unable to accomodate Required Pass"); + } + + // Now, take care of required analysises that are not available. + for (SmallVector::iterator + I = ReqAnalysisNotAvailable.begin(), + E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { + Pass *AnalysisPass = (*I)->createPass(); + this->addLowerLevelRequiredPass(P, AnalysisPass); } // Set P as P's last user until someone starts using P. @@ -691,27 +709,34 @@ void PMDataManager::add(Pass *P, PassVector.push_back(P); } -/// Populate RequiredPasses with the analysis pass that are required by -/// pass P. -void PMDataManager::collectRequiredAnalysisPasses(std::vector &RP, - Pass *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(SmallVector&RP, + SmallVector &RP_NotAvail, + Pass *P) { AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); const std::vector &RequiredSet = AnUsage.getRequiredSet(); for (std::vector::const_iterator I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { - Pass *AnalysisPass = findAnalysisPass(*I, true); - assert (AnalysisPass && "Analysis pass is not available"); - RP.push_back(AnalysisPass); + AnalysisID AID = *I; + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(AID); } const std::vector &IDs = AnUsage.getRequiredTransitiveSet(); for (std::vector::const_iterator I = IDs.begin(), E = IDs.end(); I != E; ++I) { - Pass *AnalysisPass = findAnalysisPass(*I, true); - assert (AnalysisPass && "Analysis pass is not available"); - RP.push_back(AnalysisPass); + AnalysisID AID = *I; + if (Pass *AnalysisPass = findAnalysisPass(*I, true)) + RP.push_back(AnalysisPass); + else + RP_NotAvail.push_back(AID); } } @@ -1154,6 +1179,21 @@ MPPassManager::runOnModule(Module &M) { 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"); + assert ((P->getPotentialPassManagerType() < + RequiredPass->getPotentialPassManagerType()) + && "Unable to handle Pass that requires lower level Analysis pass"); + + assert (0 && + "Unable to handle Pass that requires lower level Analysis pass"); +} + //===----------------------------------------------------------------------===// // PassManagerImpl implementation //