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

Generated by: LCOV version 1.13