FunctionSummary.h revision 7959671d456c916706a5f61af609d8f1fc95decf
1e62f048960645b79363408fdead53fec2a063c52Anna Zaks//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-// 2e62f048960645b79363408fdead53fec2a063c52Anna Zaks// 3e62f048960645b79363408fdead53fec2a063c52Anna Zaks// The LLVM Compiler Infrastructure 4e62f048960645b79363408fdead53fec2a063c52Anna Zaks// 5e62f048960645b79363408fdead53fec2a063c52Anna Zaks// This file is distributed under the University of Illinois Open Source 6e62f048960645b79363408fdead53fec2a063c52Anna Zaks// License. See LICENSE.TXT for details. 7e62f048960645b79363408fdead53fec2a063c52Anna Zaks// 8e62f048960645b79363408fdead53fec2a063c52Anna Zaks//===----------------------------------------------------------------------===// 9e62f048960645b79363408fdead53fec2a063c52Anna Zaks// 10e62f048960645b79363408fdead53fec2a063c52Anna Zaks// This file defines a summary of a function gathered/used by static analyzes. 11e62f048960645b79363408fdead53fec2a063c52Anna Zaks// 12e62f048960645b79363408fdead53fec2a063c52Anna Zaks//===----------------------------------------------------------------------===// 13e62f048960645b79363408fdead53fec2a063c52Anna Zaks 14e62f048960645b79363408fdead53fec2a063c52Anna Zaks#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H 15e62f048960645b79363408fdead53fec2a063c52Anna Zaks#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H 16e62f048960645b79363408fdead53fec2a063c52Anna Zaks 17e62f048960645b79363408fdead53fec2a063c52Anna Zaks#include "clang/AST/Decl.h" 1830a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/BitVector.h" 19e62f048960645b79363408fdead53fec2a063c52Anna Zaks#include "llvm/ADT/DenseMap.h" 20cb0a5039c243f5b0c178e70f424adac334e5789bTed Kremenek#include "llvm/ADT/DenseSet.h" 2130a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include <deque> 22e62f048960645b79363408fdead53fec2a063c52Anna Zaks 23e62f048960645b79363408fdead53fec2a063c52Anna Zaksnamespace clang { 24e62f048960645b79363408fdead53fec2a063c52Anna Zaksnamespace ento { 25577f14a34457032523e59dbbbacb88ca2cd4db57Ted Kremenektypedef std::deque<Decl*> SetOfDecls; 26cb0a5039c243f5b0c178e70f424adac334e5789bTed Kremenektypedef llvm::DenseSet<const Decl*> SetOfConstDecls; 27e62f048960645b79363408fdead53fec2a063c52Anna Zaks 28e62f048960645b79363408fdead53fec2a063c52Anna Zaksclass FunctionSummariesTy { 29e62f048960645b79363408fdead53fec2a063c52Anna Zaks struct FunctionSummary { 30e62f048960645b79363408fdead53fec2a063c52Anna Zaks /// True if this function has reached a max block count while inlined from 31e62f048960645b79363408fdead53fec2a063c52Anna Zaks /// at least one call site. 32e62f048960645b79363408fdead53fec2a063c52Anna Zaks bool MayReachMaxBlockCount; 33e62f048960645b79363408fdead53fec2a063c52Anna Zaks 34e62f048960645b79363408fdead53fec2a063c52Anna Zaks /// Total number of blocks in the function. 35e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned TotalBasicBlocks; 36e62f048960645b79363408fdead53fec2a063c52Anna Zaks 37e62f048960645b79363408fdead53fec2a063c52Anna Zaks /// Marks the IDs of the basic blocks visited during the analyzes. 38e62f048960645b79363408fdead53fec2a063c52Anna Zaks llvm::BitVector VisitedBasicBlocks; 39e62f048960645b79363408fdead53fec2a063c52Anna Zaks 407959671d456c916706a5f61af609d8f1fc95decfAnna Zaks /// The number of times the function has been inlined. 417959671d456c916706a5f61af609d8f1fc95decfAnna Zaks unsigned TimesInlined; 427959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 43e62f048960645b79363408fdead53fec2a063c52Anna Zaks FunctionSummary() : 44e62f048960645b79363408fdead53fec2a063c52Anna Zaks MayReachMaxBlockCount(false), 45e62f048960645b79363408fdead53fec2a063c52Anna Zaks TotalBasicBlocks(0), 467959671d456c916706a5f61af609d8f1fc95decfAnna Zaks VisitedBasicBlocks(0), 477959671d456c916706a5f61af609d8f1fc95decfAnna Zaks TimesInlined(0) {} 48e62f048960645b79363408fdead53fec2a063c52Anna Zaks }; 49e62f048960645b79363408fdead53fec2a063c52Anna Zaks 50e62f048960645b79363408fdead53fec2a063c52Anna Zaks typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy; 51e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy Map; 52e62f048960645b79363408fdead53fec2a063c52Anna Zaks 53e62f048960645b79363408fdead53fec2a063c52Anna Zakspublic: 54e62f048960645b79363408fdead53fec2a063c52Anna Zaks ~FunctionSummariesTy(); 55e62f048960645b79363408fdead53fec2a063c52Anna Zaks 56e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator findOrInsertSummary(const Decl *D) { 57e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = Map.find(D); 58e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (I != Map.end()) 59e62f048960645b79363408fdead53fec2a063c52Anna Zaks return I; 60e62f048960645b79363408fdead53fec2a063c52Anna Zaks FunctionSummary *DS = new FunctionSummary(); 61e62f048960645b79363408fdead53fec2a063c52Anna Zaks I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first; 62e62f048960645b79363408fdead53fec2a063c52Anna Zaks assert(I != Map.end()); 63e62f048960645b79363408fdead53fec2a063c52Anna Zaks return I; 64e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 65e62f048960645b79363408fdead53fec2a063c52Anna Zaks 66e62f048960645b79363408fdead53fec2a063c52Anna Zaks void markReachedMaxBlockCount(const Decl* D) { 67e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = findOrInsertSummary(D); 68e62f048960645b79363408fdead53fec2a063c52Anna Zaks I->second->MayReachMaxBlockCount = true; 69e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 70e62f048960645b79363408fdead53fec2a063c52Anna Zaks 71e62f048960645b79363408fdead53fec2a063c52Anna Zaks bool hasReachedMaxBlockCount(const Decl* D) { 72e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::const_iterator I = Map.find(D); 73e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (I != Map.end()) 74e62f048960645b79363408fdead53fec2a063c52Anna Zaks return I->second->MayReachMaxBlockCount; 75e62f048960645b79363408fdead53fec2a063c52Anna Zaks return false; 76e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 77e62f048960645b79363408fdead53fec2a063c52Anna Zaks 78e62f048960645b79363408fdead53fec2a063c52Anna Zaks void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { 79e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = findOrInsertSummary(D); 80e62f048960645b79363408fdead53fec2a063c52Anna Zaks llvm::BitVector &Blocks = I->second->VisitedBasicBlocks; 81e62f048960645b79363408fdead53fec2a063c52Anna Zaks assert(ID < TotalIDs); 82e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (TotalIDs > Blocks.size()) { 83e62f048960645b79363408fdead53fec2a063c52Anna Zaks Blocks.resize(TotalIDs); 84e62f048960645b79363408fdead53fec2a063c52Anna Zaks I->second->TotalBasicBlocks = TotalIDs; 85e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 86e62f048960645b79363408fdead53fec2a063c52Anna Zaks Blocks[ID] = true; 87e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 88e62f048960645b79363408fdead53fec2a063c52Anna Zaks 89e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getNumVisitedBasicBlocks(const Decl* D) { 90e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::const_iterator I = Map.find(D); 917959671d456c916706a5f61af609d8f1fc95decfAnna Zaks if (I != Map.end()) 927959671d456c916706a5f61af609d8f1fc95decfAnna Zaks return I->second->VisitedBasicBlocks.count(); 93e62f048960645b79363408fdead53fec2a063c52Anna Zaks return 0; 94e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 95e62f048960645b79363408fdead53fec2a063c52Anna Zaks 967959671d456c916706a5f61af609d8f1fc95decfAnna Zaks unsigned getNumTimesInlined(const Decl* D) { 977959671d456c916706a5f61af609d8f1fc95decfAnna Zaks MapTy::const_iterator I = Map.find(D); 987959671d456c916706a5f61af609d8f1fc95decfAnna Zaks if (I != Map.end()) 997959671d456c916706a5f61af609d8f1fc95decfAnna Zaks return I->second->TimesInlined; 1007959671d456c916706a5f61af609d8f1fc95decfAnna Zaks return 0; 1017959671d456c916706a5f61af609d8f1fc95decfAnna Zaks } 1027959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 1037959671d456c916706a5f61af609d8f1fc95decfAnna Zaks void bumpNumTimesInlined(const Decl* D) { 1047959671d456c916706a5f61af609d8f1fc95decfAnna Zaks MapTy::iterator I = findOrInsertSummary(D); 1057959671d456c916706a5f61af609d8f1fc95decfAnna Zaks I->second->TimesInlined++; 1067959671d456c916706a5f61af609d8f1fc95decfAnna Zaks } 1077959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 108cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks /// Get the percentage of the reachable blocks. 109cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks unsigned getPercentBlocksReachable(const Decl *D) { 110cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks MapTy::const_iterator I = Map.find(D); 111cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks if (I != Map.end()) 112cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks return ((I->second->VisitedBasicBlocks.count() * 100) / 113cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks I->second->TotalBasicBlocks); 114cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks return 0; 115cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks } 116cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks 117e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getTotalNumBasicBlocks(); 118e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getTotalNumVisitedBasicBlocks(); 119cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks 120e62f048960645b79363408fdead53fec2a063c52Anna Zaks}; 121e62f048960645b79363408fdead53fec2a063c52Anna Zaks 122e62f048960645b79363408fdead53fec2a063c52Anna Zaks}} // end clang ento namespaces 123e62f048960645b79363408fdead53fec2a063c52Anna Zaks 124e62f048960645b79363408fdead53fec2a063c52Anna Zaks#endif 125