X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassAnalysisSupport.h;h=75434a25ef2bbae96cdaf95222e0ad119fbbffc1;hb=c651e4c51e11feb58e6c12fee8a8f85631269f2f;hp=c105c390c55b5b2a2aa4e8105585cbff19ac27c7;hpb=aabff771653cb70b9b53d9beee027d680c5e29fd;p=oota-llvm.git diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index c105c390c55..75434a25ef2 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -1,4 +1,11 @@ -//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code ---*- C++ -*-==// +//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines stuff that is used to define and "use" Analysis Passes. // This file is automatically #included by Pass.h, so: @@ -12,146 +19,220 @@ #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H #define LLVM_PASS_ANALYSIS_SUPPORT_H -// No need to include Pass.h, we are being included by it! - - -// CreatePass - Helper template to invoke the constructor for the AnalysisID -// class. Note that this should be a template internal to AnalysisID, but -// GCC 2.95.3 crashes if we do that, doh. -// -template -static Pass *CreatePass() { return new AnalysisType(); } - -//===----------------------------------------------------------------------===// -// AnalysisID - This class is used to uniquely identify an analysis pass that -// is referenced by a transformation. -// -class AnalysisID { - static unsigned NextID; // Next ID # to deal out... - unsigned ID; // Unique ID for this analysis - Pass *(*Constructor)(); // Constructor to return the Analysis - - AnalysisID(); // Disable default ctor - AnalysisID(unsigned id, Pass *(*Ct)()) : ID(id), Constructor(Ct) {} -public: - // create - the only way to define a new AnalysisID. This static method is - // supposed to be used to define the class static AnalysisID's that are - // provided by analysis passes. In the implementation (.cpp) file for the - // class, there should be a line that looks like this (using CallGraph as an - // example): - // - // AnalysisID CallGraph::ID(AnalysisID::create()); - // - template - static AnalysisID create() { - return AnalysisID(NextID++, CreatePass); - } - - // Special Copy Constructor - This is how analysis passes declare that they - // only depend on the CFG of the function they are working on, so they are not - // invalidated by other passes that do not modify the CFG. This should be - // used like this: - // AnalysisID DominatorSet::ID(AnalysisID::create(), true); - // - AnalysisID(const AnalysisID &AID, bool DependsOnlyOnCFG = false); +#include +namespace llvm { - inline Pass *createPass() const { return Constructor(); } - - inline bool operator==(const AnalysisID &A) const { - return A.ID == ID; - } - inline bool operator!=(const AnalysisID &A) const { - return A.ID != ID; - } - inline bool operator<(const AnalysisID &A) const { - return ID < A.ID; - } -}; +// No need to include Pass.h, we are being included by it! //===----------------------------------------------------------------------===// // AnalysisUsage - Represent the analysis usage information of a pass. This -// tracks analyses that the pass REQUIRES (must available when the pass runs), -// and analyses that the pass PRESERVES (the pass does not invalidate the +// tracks analyses that the pass REQUIRES (must be available when the pass +// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the +// pass), and analyses that the pass PRESERVES (the pass does not invalidate the // results of these analyses). This information is provided by a pass to the // Pass infrastructure through the getAnalysisUsage virtual function. // class AnalysisUsage { // Sets of analyses required and preserved by a pass - std::vector Required, Preserved, Provided; + std::vector Required, RequiredTransitive, Preserved; bool PreservesAll; public: AnalysisUsage() : PreservesAll(false) {} - - // addRequires - Add the specified ID to the required set of the usage info + + // addRequired - Add the specified ID to the required set of the usage info // for a pass. // - AnalysisUsage &addRequired(AnalysisID ID) { + AnalysisUsage &addRequiredID(AnalysisID ID) { + Required.push_back(ID); + return *this; + } + template + AnalysisUsage &addRequired() { + assert(Pass::getClassPassInfo() && "Pass class not registered!"); + Required.push_back(Pass::getClassPassInfo()); + return *this; + } + + template + AnalysisUsage &addRequiredTransitive() { + AnalysisID ID = Pass::getClassPassInfo(); + assert(ID && "Pass class not registered!"); Required.push_back(ID); + RequiredTransitive.push_back(ID); return *this; } - // addPreserves - Add the specified ID to the set of analyses preserved by + // addPreserved - Add the specified ID to the set of analyses preserved by // this pass // - AnalysisUsage &addPreserved(AnalysisID ID) { + AnalysisUsage &addPreservedID(AnalysisID ID) { Preserved.push_back(ID); return *this; } - void addProvided(AnalysisID ID) { - Provided.push_back(ID); + template + AnalysisUsage &addPreserved() { + assert(Pass::getClassPassInfo() && "Pass class not registered!"); + Preserved.push_back(Pass::getClassPassInfo()); + return *this; } - // PreservesAll - Set by analyses that do not transform their input at all + // setPreservesAll - Set by analyses that do not transform their input at all void setPreservesAll() { PreservesAll = true; } - bool preservesAll() const { return PreservesAll; } - - // preservesCFG - This function should be called to by the pass, iff they do - // not: - // - // 1. Add or remove basic blocks from the function - // 2. Modify terminator instructions in any way. - // - // This function annotates the AnalysisUsage info object to say that analyses - // that only depend on the CFG are preserved by this pass. - // - void preservesCFG(); + bool getPreservesAll() const { return PreservesAll; } + + /// setPreservesCFG - This function should be called by the pass, iff they do + /// not: + /// + /// 1. Add or remove basic blocks from the function + /// 2. Modify terminator instructions in any way. + /// + /// This function annotates the AnalysisUsage info object to say that analyses + /// that only depend on the CFG are preserved by this pass. + /// + void setPreservesCFG(); const std::vector &getRequiredSet() const { return Required; } + const std::vector &getRequiredTransitiveSet() const { + return RequiredTransitive; + } const std::vector &getPreservedSet() const { return Preserved; } - const std::vector &getProvidedSet() const { return Provided; } }; - - //===----------------------------------------------------------------------===// -// AnalysisResolver - Simple interface implemented by PassManagers 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 Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0; - virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0; - Pass *getAnalysis(AnalysisID ID) { - 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) { - Pass *Result = getAnalysisOrNullUp(ID); - return Result; + // 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); } - virtual unsigned getDepth() 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 +/// to get to the analysis information that might be around that needs to be +/// updated. This is different than getAnalysis in that it can fail (ie the +/// analysis results haven't been computed), so should only be used if you +/// provide the capability to update an analysis that exists. This method is +/// often used by transformation APIs to update analysis results for a pass +/// automatically as the transform is performed. +/// +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, 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 + #endif