LCOV - code coverage report
Current view: top level - include/llvm - PassAnalysisSupport.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 33 33 100.0 %
Date: 2018-07-13 00:08:38 Functions: 162 166 97.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines stuff that is used to define and "use" Analysis Passes.
      11             : // This file is automatically #included by Pass.h, so:
      12             : //
      13             : //           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
      14             : //
      15             : // Instead, #include Pass.h
      16             : //
      17             : //===----------------------------------------------------------------------===//
      18             : 
      19             : #ifndef LLVM_PASSANALYSISSUPPORT_H
      20             : #define LLVM_PASSANALYSISSUPPORT_H
      21             : 
      22             : #include "Pass.h"
      23             : #include "llvm/ADT/SmallVector.h"
      24             : #include "llvm/ADT/StringRef.h"
      25             : #include <cassert>
      26             : #include <utility>
      27             : #include <vector>
      28             : 
      29             : namespace llvm {
      30             : 
      31             : class Function;
      32             : class Pass;
      33             : class PMDataManager;
      34             : 
      35             : //===----------------------------------------------------------------------===//
      36             : /// Represent the analysis usage information of a pass.  This tracks analyses
      37             : /// that the pass REQUIRES (must be available when the pass runs), REQUIRES
      38             : /// TRANSITIVE (must be available throughout the lifetime of the pass), and
      39             : /// analyses that the pass PRESERVES (the pass does not invalidate the results
      40             : /// of these analyses).  This information is provided by a pass to the Pass
      41             : /// infrastructure through the getAnalysisUsage virtual function.
      42             : ///
      43    15178098 : class AnalysisUsage {
      44             : public:
      45             :   using VectorType = SmallVectorImpl<AnalysisID>;
      46             : 
      47             : private:
      48             :   /// Sets of analyses required and preserved by a pass
      49             :   // TODO: It's not clear that SmallVector is an appropriate data structure for
      50             :   // this usecase.  The sizes were picked to minimize wasted space, but are
      51             :   // otherwise fairly meaningless.
      52             :   SmallVector<AnalysisID, 8> Required;
      53             :   SmallVector<AnalysisID, 2> RequiredTransitive;
      54             :   SmallVector<AnalysisID, 2> Preserved;
      55             :   SmallVector<AnalysisID, 0> Used;
      56             :   bool PreservesAll = false;
      57             : 
      58             : public:
      59     4026602 :   AnalysisUsage() = default;
      60             : 
      61             :   ///@{
      62             :   /// Add the specified ID to the required set of the usage info for a pass.
      63             :   AnalysisUsage &addRequiredID(const void *ID);
      64             :   AnalysisUsage &addRequiredID(char &ID);
      65             :   template<class PassClass>
      66             :   AnalysisUsage &addRequired() {
      67     4847125 :     return addRequiredID(PassClass::ID);
      68             :   }
      69             : 
      70             :   AnalysisUsage &addRequiredTransitiveID(char &ID);
      71             :   template<class PassClass>
      72             :   AnalysisUsage &addRequiredTransitive() {
      73      170458 :     return addRequiredTransitiveID(PassClass::ID);
      74             :   }
      75             :   ///@}
      76             : 
      77             :   ///@{
      78             :   /// Add the specified ID to the set of analyses preserved by this pass.
      79             :   AnalysisUsage &addPreservedID(const void *ID) {
      80             :     Preserved.push_back(ID);
      81             :     return *this;
      82             :   }
      83             :   AnalysisUsage &addPreservedID(char &ID) {
      84      379234 :     Preserved.push_back(&ID);
      85             :     return *this;
      86             :   }
      87             :   /// Add the specified Pass class to the set of analyses preserved by this pass.
      88             :   template<class PassClass>
      89             :   AnalysisUsage &addPreserved() {
      90     3473015 :     Preserved.push_back(&PassClass::ID);
      91             :     return *this;
      92             :   }
      93             :   ///@}
      94             : 
      95             :   ///@{
      96             :   /// Add the specified ID to the set of analyses used by this pass if they are
      97             :   /// available..
      98             :   AnalysisUsage &addUsedIfAvailableID(const void *ID) {
      99             :     Used.push_back(ID);
     100             :     return *this;
     101             :   }
     102             :   AnalysisUsage &addUsedIfAvailableID(char &ID) {
     103             :     Used.push_back(&ID);
     104             :     return *this;
     105             :   }
     106             :   /// Add the specified Pass class to the set of analyses used by this pass.
     107             :   template<class PassClass>
     108             :   AnalysisUsage &addUsedIfAvailable() {
     109      122252 :     Used.push_back(&PassClass::ID);
     110             :     return *this;
     111             :   }
     112             :   ///@}
     113             : 
     114             :   /// Add the Pass with the specified argument string to the set of analyses
     115             :   /// preserved by this pass. If no such Pass exists, do nothing. This can be
     116             :   /// useful when a pass is trivially preserved, but may not be linked in. Be
     117             :   /// careful about spelling!
     118             :   AnalysisUsage &addPreserved(StringRef Arg);
     119             : 
     120             :   /// Set by analyses that do not transform their input at all
     121     1972290 :   void setPreservesAll() { PreservesAll = true; }
     122             : 
     123             :   /// Determine whether a pass said it does not transform its input at all
     124             :   bool getPreservesAll() const { return PreservesAll; }
     125             : 
     126             :   /// This function should be called by the pass, iff they do not:
     127             :   ///
     128             :   ///  1. Add or remove basic blocks from the function
     129             :   ///  2. Modify terminator instructions in any way.
     130             :   ///
     131             :   /// This function annotates the AnalysisUsage info object to say that analyses
     132             :   /// that only depend on the CFG are preserved by this pass.
     133             :   void setPreservesCFG();
     134             : 
     135     7824261 :   const VectorType &getRequiredSet() const { return Required; }
     136             :   const VectorType &getRequiredTransitiveSet() const {
     137     7824279 :     return RequiredTransitive;
     138             :   }
     139     7824277 :   const VectorType &getPreservedSet() const { return Preserved; }
     140     7824278 :   const VectorType &getUsedSet() const { return Used; }
     141             : };
     142             : 
     143             : //===----------------------------------------------------------------------===//
     144             : /// AnalysisResolver - Simple interface used by Pass objects to pull all
     145             : /// analysis information out of pass manager that is responsible to manage
     146             : /// the pass.
     147             : ///
     148     4018944 : class AnalysisResolver {
     149             : public:
     150             :   AnalysisResolver() = delete;
     151     8073966 :   explicit AnalysisResolver(PMDataManager &P) : PM(P) {}
     152             : 
     153             :   PMDataManager &getPMDataManager() { return PM; }
     154             : 
     155             :   /// Find pass that is implementing PI.
     156             :   Pass *findImplPass(AnalysisID PI) {
     157             :     Pass *ResultPass = nullptr;
     158   321319216 :     for (const auto &AnalysisImpl : AnalysisImpls) {
     159   314397554 :       if (AnalysisImpl.first == PI) {
     160   133155695 :         ResultPass = AnalysisImpl.second;
     161             :         break;
     162             :       }
     163             :     }
     164             :     return ResultPass;
     165             :   }
     166             : 
     167             :   /// Find pass that is implementing PI. Initialize pass for Function F.
     168             :   Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
     169             : 
     170    75415393 :   void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
     171    75415393 :     if (findImplPass(PI) == P)
     172    68493728 :       return;
     173     6921665 :     std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
     174     6921665 :     AnalysisImpls.push_back(pir);
     175             :   }
     176             : 
     177             :   /// Clear cache that is used to connect a pass to the analysis (PassInfo).
     178             :   void clearAnalysisImpls() {
     179             :     AnalysisImpls.clear();
     180             :   }
     181             : 
     182             :   /// Return analysis result or null if it doesn't exist.
     183             :   Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
     184             : 
     185             : private:
     186             :   /// This keeps track of which passes implements the interfaces that are
     187             :   /// required by the current pass (to implement getAnalysis()).
     188             :   std::vector<std::pair<AnalysisID, Pass *>> AnalysisImpls;
     189             : 
     190             :   /// PassManager that is used to resolve analysis info
     191             :   PMDataManager &PM;
     192             : };
     193             : 
     194             : /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
     195             : /// get analysis information that might be around, for example to update it.
     196             : /// This is different than getAnalysis in that it can fail (if the analysis
     197             : /// results haven't been computed), so should only be used if you can handle
     198             : /// the case when the analysis is not available.  This method is often used by
     199             : /// transformation APIs to update analysis results for a pass automatically as
     200             : /// the transform is performed.
     201             : template<typename AnalysisType>
     202    20384745 : AnalysisType *Pass::getAnalysisIfAvailable() const {
     203             :   assert(Resolver && "Pass not resident in a PassManager object!");
     204             : 
     205             :   const void *PI = &AnalysisType::ID;
     206             : 
     207    20384745 :   Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true);
     208    20384745 :   if (!ResultPass) return nullptr;
     209             : 
     210             :   // Because the AnalysisType may not be a subclass of pass (for
     211             :   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
     212             :   // adjust the return pointer (because the class may multiply inherit, once
     213             :   // from pass, once from AnalysisType).
     214     6901472 :   return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
     215             : }
     216             : 
     217             : /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
     218             : /// to the analysis information that they claim to use by overriding the
     219             : /// getAnalysisUsage function.
     220             : template<typename AnalysisType>
     221    64646806 : AnalysisType &Pass::getAnalysis() const {
     222             :   assert(Resolver && "Pass has not been inserted into a PassManager object!");
     223   129293615 :   return getAnalysisID<AnalysisType>(&AnalysisType::ID);
     224             : }
     225             : 
     226             : template<typename AnalysisType>
     227             : AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
     228             :   assert(PI && "getAnalysis for unregistered pass!");
     229             :   assert(Resolver&&"Pass has not been inserted into a PassManager object!");
     230             :   // PI *must* appear in AnalysisImpls.  Because the number of passes used
     231             :   // should be a small number, we just do a linear search over a (dense)
     232             :   // vector.
     233             :   Pass *ResultPass = Resolver->findImplPass(PI);
     234             :   assert(ResultPass && 
     235             :          "getAnalysis*() called on an analysis that was not "
     236             :          "'required' by pass!");
     237             : 
     238             :   // Because the AnalysisType may not be a subclass of pass (for
     239             :   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
     240             :   // adjust the return pointer (because the class may multiply inherit, once
     241             :   // from pass, once from AnalysisType).
     242    64661964 :   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
     243             : }
     244             : 
     245             : /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
     246             : /// to the analysis information that they claim to use by overriding the
     247             : /// getAnalysisUsage function.
     248             : template<typename AnalysisType>
     249             : AnalysisType &Pass::getAnalysis(Function &F) {
     250             :   assert(Resolver &&"Pass has not been inserted into a PassManager object!");
     251             : 
     252        5177 :   return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
     253             : }
     254             : 
     255             : template<typename AnalysisType>
     256        5177 : AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) {
     257             :   assert(PI && "getAnalysis for unregistered pass!");
     258             :   assert(Resolver && "Pass has not been inserted into a PassManager object!");
     259             :   // PI *must* appear in AnalysisImpls.  Because the number of passes used
     260             :   // should be a small number, we just do a linear search over a (dense)
     261             :   // vector.
     262        5177 :   Pass *ResultPass = Resolver->findImplPass(this, PI, F);
     263             :   assert(ResultPass && "Unable to find requested analysis info");
     264             : 
     265             :   // Because the AnalysisType may not be a subclass of pass (for
     266             :   // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
     267             :   // adjust the return pointer (because the class may multiply inherit, once
     268             :   // from pass, once from AnalysisType).
     269        5177 :   return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
     270             : }
     271             : 
     272             : } // end namespace llvm
     273             : 
     274             : #endif // LLVM_PASSANALYSISSUPPORT_H

Generated by: LCOV version 1.13