- //===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // 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 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H) 
- #error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead" 
- #endif 
-   
- #ifndef LLVM_PASSANALYSISSUPPORT_H 
- #define LLVM_PASSANALYSISSUPPORT_H 
-   
- #include "llvm/ADT/STLExtras.h" 
- #include "llvm/ADT/SmallVector.h" 
- #include <cassert> 
- #include <tuple> 
- #include <utility> 
- #include <vector> 
-   
- namespace llvm { 
-   
- class Function; 
- class Pass; 
- class PMDataManager; 
- class StringRef; 
-   
- //===----------------------------------------------------------------------===// 
- /// 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 { 
- public: 
-   using VectorType = SmallVectorImpl<AnalysisID>; 
-   
- private: 
-   /// Sets of analyses required and preserved by a pass 
-   // TODO: It's not clear that SmallVector is an appropriate data structure for 
-   // this usecase.  The sizes were picked to minimize wasted space, but are 
-   // otherwise fairly meaningless. 
-   SmallVector<AnalysisID, 8> Required; 
-   SmallVector<AnalysisID, 2> RequiredTransitive; 
-   SmallVector<AnalysisID, 2> Preserved; 
-   SmallVector<AnalysisID, 0> Used; 
-   bool PreservesAll = false; 
-   
-   void pushUnique(VectorType &Set, AnalysisID ID) { 
-     if (!llvm::is_contained(Set, ID)) 
-       Set.push_back(ID); 
-   } 
-   
- public: 
-   AnalysisUsage() = default; 
-   
-   ///@{ 
-   /// Add the specified ID to the required set of the usage info for a pass. 
-   AnalysisUsage &addRequiredID(const void *ID); 
-   AnalysisUsage &addRequiredID(char &ID); 
-   template<class PassClass> 
-   AnalysisUsage &addRequired() { 
-     return addRequiredID(PassClass::ID); 
-   } 
-   
-   AnalysisUsage &addRequiredTransitiveID(char &ID); 
-   template<class PassClass> 
-   AnalysisUsage &addRequiredTransitive() { 
-     return addRequiredTransitiveID(PassClass::ID); 
-   } 
-   ///@} 
-   
-   ///@{ 
-   /// Add the specified ID to the set of analyses preserved by this pass. 
-   AnalysisUsage &addPreservedID(const void *ID) { 
-     pushUnique(Preserved, ID); 
-     return *this; 
-   } 
-   AnalysisUsage &addPreservedID(char &ID) { 
-     pushUnique(Preserved, &ID); 
-     return *this; 
-   } 
-   /// Add the specified Pass class to the set of analyses preserved by this pass. 
-   template<class PassClass> 
-   AnalysisUsage &addPreserved() { 
-     pushUnique(Preserved, &PassClass::ID); 
-     return *this; 
-   } 
-   ///@} 
-   
-   ///@{ 
-   /// Add the specified ID to the set of analyses used by this pass if they are 
-   /// available.. 
-   AnalysisUsage &addUsedIfAvailableID(const void *ID) { 
-     pushUnique(Used, ID); 
-     return *this; 
-   } 
-   AnalysisUsage &addUsedIfAvailableID(char &ID) { 
-     pushUnique(Used, &ID); 
-     return *this; 
-   } 
-   /// Add the specified Pass class to the set of analyses used by this pass. 
-   template<class PassClass> 
-   AnalysisUsage &addUsedIfAvailable() { 
-     pushUnique(Used, &PassClass::ID); 
-     return *this; 
-   } 
-   ///@} 
-   
-   /// Add the Pass with the specified argument string to the set of analyses 
-   /// preserved by this pass. If no such Pass exists, do nothing. This can be 
-   /// useful when a pass is trivially preserved, but may not be linked in. Be 
-   /// careful about spelling! 
-   AnalysisUsage &addPreserved(StringRef Arg); 
-   
-   /// Set by analyses that do not transform their input at all 
-   void setPreservesAll() { PreservesAll = true; } 
-   
-   /// Determine whether a pass said it does not transform its input at all 
-   bool getPreservesAll() const { return PreservesAll; } 
-   
-   /// 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 VectorType &getRequiredSet() const { return Required; } 
-   const VectorType &getRequiredTransitiveSet() const { 
-     return RequiredTransitive; 
-   } 
-   const VectorType &getPreservedSet() const { return Preserved; } 
-   const VectorType &getUsedSet() const { return Used; } 
- }; 
-   
- //===----------------------------------------------------------------------===// 
- /// AnalysisResolver - Simple interface used by Pass objects to pull all 
- /// analysis information out of pass manager that is responsible to manage 
- /// the pass. 
- /// 
- class AnalysisResolver { 
- public: 
-   AnalysisResolver() = delete; 
-   explicit AnalysisResolver(PMDataManager &P) : PM(P) {} 
-   
-   PMDataManager &getPMDataManager() { return PM; } 
-   
-   /// Find pass that is implementing PI. 
-   Pass *findImplPass(AnalysisID PI) { 
-     Pass *ResultPass = nullptr; 
-     for (const auto &AnalysisImpl : AnalysisImpls) { 
-       if (AnalysisImpl.first == PI) { 
-         ResultPass = AnalysisImpl.second; 
-         break; 
-       } 
-     } 
-     return ResultPass; 
-   } 
-   
-   /// Find pass that is implementing PI. Initialize pass for Function F. 
-   std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F); 
-   
-   void addAnalysisImplsPair(AnalysisID PI, Pass *P) { 
-     if (findImplPass(PI) == P) 
-       return; 
-     std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P); 
-     AnalysisImpls.push_back(pir); 
-   } 
-   
-   /// Clear cache that is used to connect a pass to the analysis (PassInfo). 
-   void clearAnalysisImpls() { 
-     AnalysisImpls.clear(); 
-   } 
-   
-   /// Return analysis result or null if it doesn't exist. 
-   Pass *getAnalysisIfAvailable(AnalysisID ID) const; 
-   
- private: 
-   /// This keeps track of which passes implements the interfaces that are 
-   /// required by the current pass (to implement getAnalysis()). 
-   std::vector<std::pair<AnalysisID, Pass *>> AnalysisImpls; 
-   
-   /// PassManager that is used to resolve analysis info 
-   PMDataManager &PM; 
- }; 
-   
- /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to 
- /// get analysis information that might be around, for example to update it. 
- /// This is different than getAnalysis in that it can fail (if the analysis 
- /// results haven't been computed), so should only be used if you can handle 
- /// the case when the analysis is not available.  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::getAnalysisIfAvailable() const { 
-   assert(Resolver && "Pass not resident in a PassManager object!"); 
-   
-   const void *PI = &AnalysisType::ID; 
-   
-   Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI); 
-   if (!ResultPass) return nullptr; 
-   
-   // Because the AnalysisType may not be a subclass of pass (for 
-   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially 
-   // adjust the return pointer (because the class may multiply inherit, once 
-   // from pass, once from AnalysisType). 
-   return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); 
- } 
-   
- /// getAnalysis<AnalysisType>() - This function is used by subclasses to get 
- /// to the analysis information that they claim to use by overriding the 
- /// getAnalysisUsage function. 
- template<typename AnalysisType> 
- AnalysisType &Pass::getAnalysis() const { 
-   assert(Resolver && "Pass has not been inserted into a PassManager object!"); 
-   return getAnalysisID<AnalysisType>(&AnalysisType::ID); 
- } 
-   
- template<typename AnalysisType> 
- AnalysisType &Pass::getAnalysisID(AnalysisID 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 use getAdjustedAnalysisPointer here to potentially 
-   // adjust the return pointer (because the class may multiply inherit, once 
-   // from pass, once from AnalysisType). 
-   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); 
- } 
-   
- /// getAnalysis<AnalysisType>() - This function is used by subclasses to get 
- /// to the analysis information that they claim to use by overriding the 
- /// getAnalysisUsage function. If as part of the dependencies, an IR 
- /// transformation is triggered (e.g. because the analysis requires 
- /// BreakCriticalEdges), and Changed is non null, *Changed is updated. 
- template <typename AnalysisType> 
- AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) { 
-   assert(Resolver &&"Pass has not been inserted into a PassManager object!"); 
-   
-   return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed); 
- } 
-   
- template <typename AnalysisType> 
- AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) { 
-   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; 
-   bool LocalChanged; 
-   std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F); 
-   
-   assert(ResultPass && "Unable to find requested analysis info"); 
-   if (Changed) 
-     *Changed |= LocalChanged; 
-   else 
-     assert(!LocalChanged && 
-            "A pass trigged a code update but the update status is lost"); 
-   
-   // Because the AnalysisType may not be a subclass of pass (for 
-   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially 
-   // adjust the return pointer (because the class may multiply inherit, once 
-   // from pass, once from AnalysisType). 
-   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI); 
- } 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_PASSANALYSISSUPPORT_H 
-