• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
FunctionSummaryFunctionSummary43     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 
findOrInsertSummary(const Decl * D)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 
markReachedMaxBlockCount(const Decl * D)66   void markReachedMaxBlockCount(const Decl* D) {
67     MapTy::iterator I = findOrInsertSummary(D);
68     I->second->MayReachMaxBlockCount = true;
69   }
70 
hasReachedMaxBlockCount(const Decl * D)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 
markVisitedBasicBlock(unsigned ID,const Decl * D,unsigned TotalIDs)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 
getNumVisitedBasicBlocks(const Decl * D)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 
getNumTimesInlined(const Decl * D)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 
bumpNumTimesInlined(const Decl * D)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.
getPercentBlocksReachable(const Decl * D)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