| //===- 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: |
| // |
| // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY |
| // |
| // Instead, #include Pass.h |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_PASS_ANALYSIS_SUPPORT_H |
| #define LLVM_PASS_ANALYSIS_SUPPORT_H |
| |
| namespace llvm { |
| |
| // 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 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<AnalysisID> Required, RequiredTransitive, Preserved; |
| bool PreservesAll; |
| public: |
| AnalysisUsage() : PreservesAll(false) {} |
| |
| // addRequired - Add the specified ID to the required set of the usage info |
| // for a pass. |
| // |
| AnalysisUsage &addRequiredID(AnalysisID ID) { |
| Required.push_back(ID); |
| return *this; |
| } |
| template<class PassClass> |
| AnalysisUsage &addRequired() { |
| assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!"); |
| Required.push_back(Pass::getClassPassInfo<PassClass>()); |
| return *this; |
| } |
| |
| template<class PassClass> |
| AnalysisUsage &addRequiredTransitive() { |
| AnalysisID ID = Pass::getClassPassInfo<PassClass>(); |
| assert(ID && "Pass class not registered!"); |
| Required.push_back(ID); |
| RequiredTransitive.push_back(ID); |
| return *this; |
| } |
| |
| // addPreserved - Add the specified ID to the set of analyses preserved by |
| // this pass |
| // |
| AnalysisUsage &addPreservedID(AnalysisID ID) { |
| Preserved.push_back(ID); |
| return *this; |
| } |
| |
| template<class PassClass> |
| AnalysisUsage &addPreserved() { |
| assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!"); |
| Preserved.push_back(Pass::getClassPassInfo<PassClass>()); |
| return *this; |
| } |
| |
| // setPreservesAll - Set by analyses that do not transform their input at all |
| void setPreservesAll() { PreservesAll = true; } |
| 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<AnalysisID> &getRequiredSet() const { return Required; } |
| const std::vector<AnalysisID> &getRequiredTransitiveSet() const { |
| return RequiredTransitive; |
| } |
| const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; } |
| }; |
| |
| |
| |
| //===----------------------------------------------------------------------===// |
| // AnalysisResolver - Simple interface implemented by PassManager objects that |
| // is used to pull analysis information out of them. |
| // |
| 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; |
| } |
| |
| // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist |
| Pass *getAnalysisToUpdate(AnalysisID ID) const { |
| return getAnalysisOrNullUp(ID); |
| } |
| |
| // 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; |
| |
| virtual void markPassUsed(AnalysisID P, Pass *User) = 0; |
| |
| void startPass(Pass *P) {} |
| void endPass(Pass *P) {} |
| protected: |
| void setAnalysisResolver(Pass *P, AnalysisResolver *AR); |
| }; |
| |
| /// getAnalysisToUpdate<AnalysisType>() - 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<typename AnalysisType> |
| AnalysisType *Pass::getAnalysisToUpdate() const { |
| assert(Resolver && "Pass not resident in a PassManager object!"); |
| const PassInfo *PI = getClassPassInfo<AnalysisType>(); |
| if (PI == 0) return 0; |
| return dynamic_cast<AnalysisType*>(Resolver->getAnalysisToUpdate(PI)); |
| } |
| |
| } // End llvm namespace |
| |
| #endif |