Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:46

0001 //===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines stuff that is used to define and "use" Analysis Passes.
0010 // This file is automatically #included by Pass.h, so:
0011 //
0012 //           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
0013 //
0014 // Instead, #include Pass.h
0015 //
0016 //===----------------------------------------------------------------------===//
0017 
0018 #if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H)
0019 #error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead"
0020 #endif
0021 
0022 #ifndef LLVM_PASSANALYSISSUPPORT_H
0023 #define LLVM_PASSANALYSISSUPPORT_H
0024 
0025 #include "llvm/ADT/STLExtras.h"
0026 #include "llvm/ADT/SmallVector.h"
0027 #include <cassert>
0028 #include <tuple>
0029 #include <utility>
0030 #include <vector>
0031 
0032 namespace llvm {
0033 
0034 class Function;
0035 class Pass;
0036 class PMDataManager;
0037 class StringRef;
0038 
0039 //===----------------------------------------------------------------------===//
0040 /// Represent the analysis usage information of a pass.  This tracks analyses
0041 /// that the pass REQUIRES (must be available when the pass runs), REQUIRES
0042 /// TRANSITIVE (must be available throughout the lifetime of the pass), and
0043 /// analyses that the pass PRESERVES (the pass does not invalidate the results
0044 /// of these analyses).  This information is provided by a pass to the Pass
0045 /// infrastructure through the getAnalysisUsage virtual function.
0046 ///
0047 class AnalysisUsage {
0048 public:
0049   using VectorType = SmallVectorImpl<AnalysisID>;
0050 
0051 private:
0052   /// Sets of analyses required and preserved by a pass
0053   // TODO: It's not clear that SmallVector is an appropriate data structure for
0054   // this usecase.  The sizes were picked to minimize wasted space, but are
0055   // otherwise fairly meaningless.
0056   SmallVector<AnalysisID, 8> Required;
0057   SmallVector<AnalysisID, 2> RequiredTransitive;
0058   SmallVector<AnalysisID, 2> Preserved;
0059   SmallVector<AnalysisID, 0> Used;
0060   bool PreservesAll = false;
0061 
0062   void pushUnique(VectorType &Set, AnalysisID ID) {
0063     if (!llvm::is_contained(Set, ID))
0064       Set.push_back(ID);
0065   }
0066 
0067 public:
0068   AnalysisUsage() = default;
0069 
0070   ///@{
0071   /// Add the specified ID to the required set of the usage info for a pass.
0072   AnalysisUsage &addRequiredID(const void *ID);
0073   AnalysisUsage &addRequiredID(char &ID);
0074   template<class PassClass>
0075   AnalysisUsage &addRequired() {
0076     return addRequiredID(PassClass::ID);
0077   }
0078 
0079   AnalysisUsage &addRequiredTransitiveID(char &ID);
0080   template<class PassClass>
0081   AnalysisUsage &addRequiredTransitive() {
0082     return addRequiredTransitiveID(PassClass::ID);
0083   }
0084   ///@}
0085 
0086   ///@{
0087   /// Add the specified ID to the set of analyses preserved by this pass.
0088   AnalysisUsage &addPreservedID(const void *ID) {
0089     pushUnique(Preserved, ID);
0090     return *this;
0091   }
0092   AnalysisUsage &addPreservedID(char &ID) {
0093     pushUnique(Preserved, &ID);
0094     return *this;
0095   }
0096   /// Add the specified Pass class to the set of analyses preserved by this pass.
0097   template<class PassClass>
0098   AnalysisUsage &addPreserved() {
0099     pushUnique(Preserved, &PassClass::ID);
0100     return *this;
0101   }
0102   ///@}
0103 
0104   ///@{
0105   /// Add the specified ID to the set of analyses used by this pass if they are
0106   /// available..
0107   AnalysisUsage &addUsedIfAvailableID(const void *ID) {
0108     pushUnique(Used, ID);
0109     return *this;
0110   }
0111   AnalysisUsage &addUsedIfAvailableID(char &ID) {
0112     pushUnique(Used, &ID);
0113     return *this;
0114   }
0115   /// Add the specified Pass class to the set of analyses used by this pass.
0116   template<class PassClass>
0117   AnalysisUsage &addUsedIfAvailable() {
0118     pushUnique(Used, &PassClass::ID);
0119     return *this;
0120   }
0121   ///@}
0122 
0123   /// Add the Pass with the specified argument string to the set of analyses
0124   /// preserved by this pass. If no such Pass exists, do nothing. This can be
0125   /// useful when a pass is trivially preserved, but may not be linked in. Be
0126   /// careful about spelling!
0127   AnalysisUsage &addPreserved(StringRef Arg);
0128 
0129   /// Set by analyses that do not transform their input at all
0130   void setPreservesAll() { PreservesAll = true; }
0131 
0132   /// Determine whether a pass said it does not transform its input at all
0133   bool getPreservesAll() const { return PreservesAll; }
0134 
0135   /// This function should be called by the pass, iff they do not:
0136   ///
0137   ///  1. Add or remove basic blocks from the function
0138   ///  2. Modify terminator instructions in any way.
0139   ///
0140   /// This function annotates the AnalysisUsage info object to say that analyses
0141   /// that only depend on the CFG are preserved by this pass.
0142   void setPreservesCFG();
0143 
0144   const VectorType &getRequiredSet() const { return Required; }
0145   const VectorType &getRequiredTransitiveSet() const {
0146     return RequiredTransitive;
0147   }
0148   const VectorType &getPreservedSet() const { return Preserved; }
0149   const VectorType &getUsedSet() const { return Used; }
0150 };
0151 
0152 //===----------------------------------------------------------------------===//
0153 /// AnalysisResolver - Simple interface used by Pass objects to pull all
0154 /// analysis information out of pass manager that is responsible to manage
0155 /// the pass.
0156 ///
0157 class AnalysisResolver {
0158 public:
0159   AnalysisResolver() = delete;
0160   explicit AnalysisResolver(PMDataManager &P) : PM(P) {}
0161 
0162   PMDataManager &getPMDataManager() { return PM; }
0163 
0164   /// Find pass that is implementing PI.
0165   Pass *findImplPass(AnalysisID PI) {
0166     Pass *ResultPass = nullptr;
0167     for (const auto &AnalysisImpl : AnalysisImpls) {
0168       if (AnalysisImpl.first == PI) {
0169         ResultPass = AnalysisImpl.second;
0170         break;
0171       }
0172     }
0173     return ResultPass;
0174   }
0175 
0176   /// Find pass that is implementing PI. Initialize pass for Function F.
0177   std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F);
0178 
0179   void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
0180     if (findImplPass(PI) == P)
0181       return;
0182     std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
0183     AnalysisImpls.push_back(pir);
0184   }
0185 
0186   /// Clear cache that is used to connect a pass to the analysis (PassInfo).
0187   void clearAnalysisImpls() {
0188     AnalysisImpls.clear();
0189   }
0190 
0191   /// Return analysis result or null if it doesn't exist.
0192   Pass *getAnalysisIfAvailable(AnalysisID ID) const;
0193 
0194 private:
0195   /// This keeps track of which passes implements the interfaces that are
0196   /// required by the current pass (to implement getAnalysis()).
0197   std::vector<std::pair<AnalysisID, Pass *>> AnalysisImpls;
0198 
0199   /// PassManager that is used to resolve analysis info
0200   PMDataManager &PM;
0201 };
0202 
0203 /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
0204 /// get analysis information that might be around, for example to update it.
0205 /// This is different than getAnalysis in that it can fail (if the analysis
0206 /// results haven't been computed), so should only be used if you can handle
0207 /// the case when the analysis is not available.  This method is often used by
0208 /// transformation APIs to update analysis results for a pass automatically as
0209 /// the transform is performed.
0210 template<typename AnalysisType>
0211 AnalysisType *Pass::getAnalysisIfAvailable() const {
0212   assert(Resolver && "Pass not resident in a PassManager object!");
0213 
0214   const void *PI = &AnalysisType::ID;
0215 
0216   Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI);
0217   if (!ResultPass) return nullptr;
0218 
0219   // Because the AnalysisType may not be a subclass of pass (for
0220   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
0221   // adjust the return pointer (because the class may multiply inherit, once
0222   // from pass, once from AnalysisType).
0223   return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0224 }
0225 
0226 /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
0227 /// to the analysis information that they claim to use by overriding the
0228 /// getAnalysisUsage function.
0229 template<typename AnalysisType>
0230 AnalysisType &Pass::getAnalysis() const {
0231   assert(Resolver && "Pass has not been inserted into a PassManager object!");
0232   return getAnalysisID<AnalysisType>(&AnalysisType::ID);
0233 }
0234 
0235 template<typename AnalysisType>
0236 AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
0237   assert(PI && "getAnalysis for unregistered pass!");
0238   assert(Resolver&&"Pass has not been inserted into a PassManager object!");
0239   // PI *must* appear in AnalysisImpls.  Because the number of passes used
0240   // should be a small number, we just do a linear search over a (dense)
0241   // vector.
0242   Pass *ResultPass = Resolver->findImplPass(PI);
0243   assert(ResultPass &&
0244          "getAnalysis*() called on an analysis that was not "
0245          "'required' by pass!");
0246 
0247   // Because the AnalysisType may not be a subclass of pass (for
0248   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
0249   // adjust the return pointer (because the class may multiply inherit, once
0250   // from pass, once from AnalysisType).
0251   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0252 }
0253 
0254 /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
0255 /// to the analysis information that they claim to use by overriding the
0256 /// getAnalysisUsage function. If as part of the dependencies, an IR
0257 /// transformation is triggered (e.g. because the analysis requires
0258 /// BreakCriticalEdges), and Changed is non null, *Changed is updated.
0259 template <typename AnalysisType>
0260 AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) {
0261   assert(Resolver &&"Pass has not been inserted into a PassManager object!");
0262 
0263   return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed);
0264 }
0265 
0266 template <typename AnalysisType>
0267 AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) {
0268   assert(PI && "getAnalysis for unregistered pass!");
0269   assert(Resolver && "Pass has not been inserted into a PassManager object!");
0270   // PI *must* appear in AnalysisImpls.  Because the number of passes used
0271   // should be a small number, we just do a linear search over a (dense)
0272   // vector.
0273   Pass *ResultPass;
0274   bool LocalChanged;
0275   std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F);
0276 
0277   assert(ResultPass && "Unable to find requested analysis info");
0278   if (Changed)
0279     *Changed |= LocalChanged;
0280   else
0281     assert(!LocalChanged &&
0282            "A pass trigged a code update but the update status is lost");
0283 
0284   // Because the AnalysisType may not be a subclass of pass (for
0285   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
0286   // adjust the return pointer (because the class may multiply inherit, once
0287   // from pass, once from AnalysisType).
0288   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0289 }
0290 
0291 } // end namespace llvm
0292 
0293 #endif // LLVM_PASSANALYSISSUPPORT_H