Home | History | Annotate | Download | only in PathSensitive
      1 //== FunctionSummary.h - Stores summaries of functions. ------------*- 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 a summary of a function gathered/used by static analysis.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
     15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
     16 
     17 #include "clang/AST/Decl.h"
     18 #include "clang/Basic/LLVM.h"
     19 #include "llvm/ADT/DenseMap.h"
     20 #include "llvm/ADT/DenseSet.h"
     21 #include "llvm/ADT/Optional.h"
     22 #include "llvm/ADT/SmallBitVector.h"
     23 #include <deque>
     24 
     25 namespace clang {
     26 
     27 namespace ento {
     28 typedef std::deque<Decl*> SetOfDecls;
     29 typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
     30 
     31 class FunctionSummariesTy {
     32   class FunctionSummary {
     33   public:
     34     /// Marks the IDs of the basic blocks visited during the analyzes.
     35     llvm::SmallBitVector VisitedBasicBlocks;
     36 
     37     /// Total number of blocks in the function.
     38     unsigned TotalBasicBlocks : 30;
     39 
     40     /// True if this function has been checked against the rules for which
     41     /// functions may be inlined.
     42     unsigned InlineChecked : 1;
     43 
     44     /// True if this function may be inlined.
     45     unsigned MayInline : 1;
     46 
     47     /// The number of times the function has been inlined.
     48     unsigned TimesInlined : 32;
     49 
     50     FunctionSummary() :
     51       TotalBasicBlocks(0),
     52       InlineChecked(0),
     53       TimesInlined(0) {}
     54   };
     55 
     56   typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
     57   MapTy Map;
     58 
     59 public:
     60   MapTy::iterator findOrInsertSummary(const Decl *D) {
     61     MapTy::iterator I = Map.find(D);
     62     if (I != Map.end())
     63       return I;
     64 
     65     typedef std::pair<const Decl *, FunctionSummary> KVPair;
     66     I = Map.insert(KVPair(D, FunctionSummary())).first;
     67     assert(I != Map.end());
     68     return I;
     69   }
     70 
     71   void markMayInline(const Decl *D) {
     72     MapTy::iterator I = findOrInsertSummary(D);
     73     I->second.InlineChecked = 1;
     74     I->second.MayInline = 1;
     75   }
     76 
     77   void markShouldNotInline(const Decl *D) {
     78     MapTy::iterator I = findOrInsertSummary(D);
     79     I->second.InlineChecked = 1;
     80     I->second.MayInline = 0;
     81   }
     82 
     83   void markReachedMaxBlockCount(const Decl *D) {
     84     markShouldNotInline(D);
     85   }
     86 
     87   Optional<bool> mayInline(const Decl *D) {
     88     MapTy::const_iterator I = Map.find(D);
     89     if (I != Map.end() && I->second.InlineChecked)
     90       return I->second.MayInline;
     91     return None;
     92   }
     93 
     94   void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
     95     MapTy::iterator I = findOrInsertSummary(D);
     96     llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
     97     assert(ID < TotalIDs);
     98     if (TotalIDs > Blocks.size()) {
     99       Blocks.resize(TotalIDs);
    100       I->second.TotalBasicBlocks = TotalIDs;
    101     }
    102     Blocks.set(ID);
    103   }
    104 
    105   unsigned getNumVisitedBasicBlocks(const Decl* D) {
    106     MapTy::const_iterator I = Map.find(D);
    107     if (I != Map.end())
    108       return I->second.VisitedBasicBlocks.count();
    109     return 0;
    110   }
    111 
    112   unsigned getNumTimesInlined(const Decl* D) {
    113     MapTy::const_iterator I = Map.find(D);
    114     if (I != Map.end())
    115       return I->second.TimesInlined;
    116     return 0;
    117   }
    118 
    119   void bumpNumTimesInlined(const Decl* D) {
    120     MapTy::iterator I = findOrInsertSummary(D);
    121     I->second.TimesInlined++;
    122   }
    123 
    124   /// Get the percentage of the reachable blocks.
    125   unsigned getPercentBlocksReachable(const Decl *D) {
    126     MapTy::const_iterator I = Map.find(D);
    127       if (I != Map.end())
    128         return ((I->second.VisitedBasicBlocks.count() * 100) /
    129                  I->second.TotalBasicBlocks);
    130     return 0;
    131   }
    132 
    133   unsigned getTotalNumBasicBlocks();
    134   unsigned getTotalNumVisitedBasicBlocks();
    135 
    136 };
    137 
    138 }} // end clang ento namespaces
    139 
    140 #endif
    141