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/Basic/LLVM.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/DenseSet.h" 20 #include "llvm/ADT/Optional.h" 21 #include "llvm/ADT/SmallBitVector.h" 22 #include <deque> 23 24 namespace clang { 25 class Decl; 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 FunctionSummary()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: findOrInsertSummary(const Decl * D)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 markMayInline(const Decl * D)71 void markMayInline(const Decl *D) { 72 MapTy::iterator I = findOrInsertSummary(D); 73 I->second.InlineChecked = 1; 74 I->second.MayInline = 1; 75 } 76 markShouldNotInline(const Decl * D)77 void markShouldNotInline(const Decl *D) { 78 MapTy::iterator I = findOrInsertSummary(D); 79 I->second.InlineChecked = 1; 80 I->second.MayInline = 0; 81 } 82 markReachedMaxBlockCount(const Decl * D)83 void markReachedMaxBlockCount(const Decl *D) { 84 markShouldNotInline(D); 85 } 86 mayInline(const Decl * D)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 markVisitedBasicBlock(unsigned ID,const Decl * D,unsigned TotalIDs)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 getNumVisitedBasicBlocks(const Decl * D)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 getNumTimesInlined(const Decl * D)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 bumpNumTimesInlined(const Decl * D)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. getPercentBlocksReachable(const Decl * D)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