X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassAnalysisSupport.h;h=75434a25ef2bbae96cdaf95222e0ad119fbbffc1;hb=c651e4c51e11feb58e6c12fee8a8f85631269f2f;hp=415f93cc67bb9a358818e209ac3e15bde12a0902;hpb=e8f38486394f3a897e3637b559ade420dddbe1e3;p=oota-llvm.git diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index 415f93cc67b..75434a25ef2 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -19,6 +19,8 @@ #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H #define LLVM_PASS_ANALYSIS_SUPPORT_H +#include + namespace llvm { // No need to include Pass.h, we are being included by it! @@ -98,39 +100,53 @@ public: const std::vector &getPreservedSet() const { return Preserved; } }; - - //===----------------------------------------------------------------------===// -// AnalysisResolver - Simple interface implemented by PassManager objects that -// is used to pull analysis information out of them. +// AnalysisResolver - Simple interface used by Pass objects to pull all +// analysis information out of pass manager that is responsible to manage +// the pass. // -struct AnalysisResolver { - virtual ~AnalysisResolver(); - virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0; - virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0; - virtual void addPass(ImmutablePass *IP, AnalysisUsage &AU) = 0; - Pass *getAnalysis(AnalysisID ID) const { - Pass *Result = getAnalysisOrNullUp(ID); - assert(Result && "Pass has an incorrect analysis uses set!"); - return Result; +class PMDataManager; +class AnalysisResolver { +private: + AnalysisResolver(); // DO NOT IMPLEMENT + +public: + explicit AnalysisResolver(PMDataManager &P) : PM(P) { } + + inline PMDataManager &getPMDataManager() { return PM; } + + // Find pass that is implementing PI. + Pass *findImplPass(const PassInfo *PI) { + Pass *ResultPass = 0; + for (unsigned i = 0; i < AnalysisImpls.size() ; ++i) { + if (AnalysisImpls[i].first == PI) { + ResultPass = AnalysisImpls[i].second; + break; + } + } + return ResultPass; } - // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist - Pass *getAnalysisToUpdate(AnalysisID ID) const { - return getAnalysisOrNullUp(ID); + // Find pass that is implementing PI. Initialize pass for Function F. + Pass *findImplPass(Pass *P, const PassInfo *PI, Function &F); + + void addAnalysisImplsPair(const PassInfo *PI, Pass *P) { + std::pair pir = std::make_pair(PI,P); + AnalysisImpls.push_back(pir); } - // Methods for introspecting into pass manager objects... - virtual unsigned getDepth() const = 0; - virtual unsigned getNumContainedPasses() const = 0; - virtual const Pass *getContainedPass(unsigned N) const = 0; + // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist + Pass *getAnalysisToUpdate(AnalysisID ID, bool Direction) const; - virtual void markPassUsed(AnalysisID P, Pass *User) = 0; + // AnalysisImpls - This keeps track of which passes implements the interfaces + // that are required by the current pass (to implement getAnalysis()). + // NOTE : Remove AnalysisImpls from class Pass, when AnalysisResolver + // replaces AnalysisResolver + std::vector > AnalysisImpls; - void startPass(Pass *P) {} - void endPass(Pass *P) {} -protected: - void setAnalysisResolver(Pass *P, AnalysisResolver *AR); +private: + // PassManager that is used to resolve analysis info + PMDataManager &PM; }; /// getAnalysisToUpdate() - This function is used by subclasses @@ -144,9 +160,77 @@ protected: template AnalysisType *Pass::getAnalysisToUpdate() const { assert(Resolver && "Pass not resident in a PassManager object!"); + const PassInfo *PI = getClassPassInfo(); if (PI == 0) return 0; - return dynamic_cast(Resolver->getAnalysisToUpdate(PI)); + return dynamic_cast + (Resolver->getAnalysisToUpdate(PI, true)); +} + +/// getAnalysis() - This function is used by subclasses to get +/// to the analysis information that they claim to use by overriding the +/// getAnalysisUsage function. +/// +template +AnalysisType &Pass::getAnalysis() const { + assert(Resolver &&"Pass has not been inserted into a PassManager object!"); + + return getAnalysisID(getClassPassInfo()); +} + +template +AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const { + assert(PI && "getAnalysis for unregistered pass!"); + assert(Resolver&&"Pass has not been inserted into a PassManager object!"); + // PI *must* appear in AnalysisImpls. Because the number of passes used + // should be a small number, we just do a linear search over a (dense) + // vector. + Pass *ResultPass = Resolver->findImplPass(PI); + assert (ResultPass && + "getAnalysis*() called on an analysis that was not " + "'required' by pass!"); + + // Because the AnalysisType may not be a subclass of pass (for + // AnalysisGroups), we must use dynamic_cast here to potentially adjust the + // return pointer (because the class may multiply inherit, once from pass, + // once from AnalysisType). + // + AnalysisType *Result = dynamic_cast(ResultPass); + assert(Result && "Pass does not implement interface required!"); + return *Result; +} + +/// getAnalysis() - This function is used by subclasses to get +/// to the analysis information that they claim to use by overriding the +/// getAnalysisUsage function. +/// +template +AnalysisType &Pass::getAnalysis(Function &F) { + assert(Resolver &&"Pass has not been inserted into a PassManager object!"); + + return getAnalysisID(getClassPassInfo(), F); +} + +template +AnalysisType &Pass::getAnalysisID(const PassInfo *PI, Function &F) { + assert(PI && "getAnalysis for unregistered pass!"); + assert(Resolver&&"Pass has not been inserted into a PassManager object!"); + // PI *must* appear in AnalysisImpls. Because the number of passes used + // should be a small number, we just do a linear search over a (dense) + // vector. + Pass *ResultPass = Resolver->findImplPass(this, PI, F); + assert (ResultPass && + "getAnalysis*() called on an analysis that was not " + "'required' by pass!"); + + // Because the AnalysisType may not be a subclass of pass (for + // AnalysisGroups), we must use dynamic_cast here to potentially adjust the + // return pointer (because the class may multiply inherit, once from pass, + // once from AnalysisType). + // + AnalysisType *Result = dynamic_cast(ResultPass); + assert(Result && "Pass does not implement interface required!"); + return *Result; } } // End llvm namespace