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 analyzes.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
     15 #define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
     16 
     17 #include "clang/AST/Decl.h"
     18 #include "llvm/ADT/BitVector.h"
     19 #include "llvm/ADT/DenseMap.h"
     20 #include "llvm/ADT/DenseSet.h"
     21 #include <deque>
     22 
     23 namespace clang {
     24 namespace ento {
     25 typedef std::deque<Decl*> SetOfDecls;
     26 typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
     27 
     28 class FunctionSummariesTy {
     29   struct FunctionSummary {
     30     /// True if this function has reached a max block count while inlined from
     31     /// at least one call site.
     32     bool MayReachMaxBlockCount;
     33 
     34     /// Total number of blocks in the function.
     35     unsigned TotalBasicBlocks;
     36 
     37     /// Marks the IDs of the basic blocks visited during the analyzes.
     38     llvm::BitVector VisitedBasicBlocks;
     39 
     40     /// The number of times the function has been inlined.
     41     unsigned TimesInlined;
     42 
     43     FunctionSummary() :
     44       MayReachMaxBlockCount(false),
     45       TotalBasicBlocks(0),
     46       VisitedBasicBlocks(0),
     47       TimesInlined(0) {}
     48   };
     49 
     50   typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy;
     51   MapTy Map;
     52 
     53 public:
     54   ~FunctionSummariesTy();
     55 
     56   MapTy::iterator findOrInsertSummary(const Decl *D) {
     57     MapTy::iterator I = Map.find(D);
     58     if (I != Map.end())
     59       return I;
     60     FunctionSummary *DS = new FunctionSummary();
     61     I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first;
     62     assert(I != Map.end());
     63     return I;
     64   }
     65 
     66   void markReachedMaxBlockCount(const Decl* D) {
     67     MapTy::iterator I = findOrInsertSummary(D);
     68     I->second->MayReachMaxBlockCount = true;
     69   }
     70 
     71   bool hasReachedMaxBlockCount(const Decl* D) {
     72   MapTy::const_iterator I = Map.find(D);
     73     if (I != Map.end())
     74       return I->second->MayReachMaxBlockCount;
     75     return false;
     76   }
     77 
     78   void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
     79     MapTy::iterator I = findOrInsertSummary(D);
     80     llvm::BitVector &Blocks = I->second->VisitedBasicBlocks;
     81     assert(ID < TotalIDs);
     82     if (TotalIDs > Blocks.size()) {
     83       Blocks.resize(TotalIDs);
     84       I->second->TotalBasicBlocks = TotalIDs;
     85     }
     86     Blocks[ID] = true;
     87   }
     88 
     89   unsigned getNumVisitedBasicBlocks(const Decl* D) {
     90     MapTy::const_iterator I = Map.find(D);
     91     if (I != Map.end())
     92       return I->second->VisitedBasicBlocks.count();
     93     return 0;
     94   }
     95 
     96   unsigned getNumTimesInlined(const Decl* D) {
     97     MapTy::const_iterator I = Map.find(D);
     98     if (I != Map.end())
     99       return I->second->TimesInlined;
    100     return 0;
    101   }
    102 
    103   void bumpNumTimesInlined(const Decl* D) {
    104     MapTy::iterator I = findOrInsertSummary(D);
    105     I->second->TimesInlined++;
    106   }
    107 
    108   /// Get the percentage of the reachable blocks.
    109   unsigned getPercentBlocksReachable(const Decl *D) {
    110     MapTy::const_iterator I = Map.find(D);
    111       if (I != Map.end())
    112         return ((I->second->VisitedBasicBlocks.count() * 100) /
    113                  I->second->TotalBasicBlocks);
    114     return 0;
    115   }
    116 
    117   unsigned getTotalNumBasicBlocks();
    118   unsigned getTotalNumVisitedBasicBlocks();
    119 
    120 };
    121 
    122 }} // end clang ento namespaces
    123 
    124 #endif
    125