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_GR_FUNCTIONSUMMARY_H 15#define LLVM_CLANG_GR_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 24namespace clang { 25class Decl; 26 27namespace ento { 28typedef std::deque<Decl*> SetOfDecls; 29typedef llvm::DenseSet<const Decl*> SetOfConstDecls; 30 31class 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 59public: 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