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