FunctionSummary.h revision 992acb2269171b6ef68694d71a36f6b7408d8e82
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// 10992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose// This file defines a summary of a function gathered/used by static analysis. 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" 18992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose#include "llvm/ADT/SmallBitVector.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 { 30992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose /// Marks the IDs of the basic blocks visited during the analyzes. 31992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose llvm::SmallBitVector VisitedBasicBlocks; 32e62f048960645b79363408fdead53fec2a063c52Anna Zaks 33e62f048960645b79363408fdead53fec2a063c52Anna Zaks /// Total number of blocks in the function. 34992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose unsigned TotalBasicBlocks : 31; 35e62f048960645b79363408fdead53fec2a063c52Anna Zaks 36992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose /// True if this function has reached a max block count while inlined from 37992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose /// at least one call site. 38992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose unsigned MayReachMaxBlockCount : 1; 39e62f048960645b79363408fdead53fec2a063c52Anna Zaks 407959671d456c916706a5f61af609d8f1fc95decfAnna Zaks /// The number of times the function has been inlined. 41992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose unsigned TimesInlined : 32; 427959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 43e62f048960645b79363408fdead53fec2a063c52Anna Zaks FunctionSummary() : 44e62f048960645b79363408fdead53fec2a063c52Anna Zaks TotalBasicBlocks(0), 45992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose MayReachMaxBlockCount(0), 467959671d456c916706a5f61af609d8f1fc95decfAnna Zaks TimesInlined(0) {} 47e62f048960645b79363408fdead53fec2a063c52Anna Zaks }; 48e62f048960645b79363408fdead53fec2a063c52Anna Zaks 49992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy; 50e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy Map; 51e62f048960645b79363408fdead53fec2a063c52Anna Zaks 52e62f048960645b79363408fdead53fec2a063c52Anna Zakspublic: 53e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator findOrInsertSummary(const Decl *D) { 54e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = Map.find(D); 55e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (I != Map.end()) 56e62f048960645b79363408fdead53fec2a063c52Anna Zaks return I; 57992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose 58992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose typedef std::pair<const Decl *, FunctionSummary> KVPair; 59992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose I = Map.insert(KVPair(D, FunctionSummary())).first; 60e62f048960645b79363408fdead53fec2a063c52Anna Zaks assert(I != Map.end()); 61e62f048960645b79363408fdead53fec2a063c52Anna Zaks return I; 62e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 63e62f048960645b79363408fdead53fec2a063c52Anna Zaks 64e62f048960645b79363408fdead53fec2a063c52Anna Zaks void markReachedMaxBlockCount(const Decl* D) { 65e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = findOrInsertSummary(D); 66992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose I->second.MayReachMaxBlockCount = 1; 67e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 68e62f048960645b79363408fdead53fec2a063c52Anna Zaks 69e62f048960645b79363408fdead53fec2a063c52Anna Zaks bool hasReachedMaxBlockCount(const Decl* D) { 70e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::const_iterator I = Map.find(D); 71e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (I != Map.end()) 72992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose return I->second.MayReachMaxBlockCount; 73e62f048960645b79363408fdead53fec2a063c52Anna Zaks return false; 74e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 75e62f048960645b79363408fdead53fec2a063c52Anna Zaks 76e62f048960645b79363408fdead53fec2a063c52Anna Zaks void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { 77e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::iterator I = findOrInsertSummary(D); 78992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks; 79e62f048960645b79363408fdead53fec2a063c52Anna Zaks assert(ID < TotalIDs); 80e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (TotalIDs > Blocks.size()) { 81e62f048960645b79363408fdead53fec2a063c52Anna Zaks Blocks.resize(TotalIDs); 82992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose I->second.TotalBasicBlocks = TotalIDs; 83e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 84992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose Blocks.set(ID); 85e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 86e62f048960645b79363408fdead53fec2a063c52Anna Zaks 87e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getNumVisitedBasicBlocks(const Decl* D) { 88e62f048960645b79363408fdead53fec2a063c52Anna Zaks MapTy::const_iterator I = Map.find(D); 897959671d456c916706a5f61af609d8f1fc95decfAnna Zaks if (I != Map.end()) 90992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose return I->second.VisitedBasicBlocks.count(); 91e62f048960645b79363408fdead53fec2a063c52Anna Zaks return 0; 92e62f048960645b79363408fdead53fec2a063c52Anna Zaks } 93e62f048960645b79363408fdead53fec2a063c52Anna Zaks 947959671d456c916706a5f61af609d8f1fc95decfAnna Zaks unsigned getNumTimesInlined(const Decl* D) { 957959671d456c916706a5f61af609d8f1fc95decfAnna Zaks MapTy::const_iterator I = Map.find(D); 967959671d456c916706a5f61af609d8f1fc95decfAnna Zaks if (I != Map.end()) 97992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose return I->second.TimesInlined; 987959671d456c916706a5f61af609d8f1fc95decfAnna Zaks return 0; 997959671d456c916706a5f61af609d8f1fc95decfAnna Zaks } 1007959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 1017959671d456c916706a5f61af609d8f1fc95decfAnna Zaks void bumpNumTimesInlined(const Decl* D) { 1027959671d456c916706a5f61af609d8f1fc95decfAnna Zaks MapTy::iterator I = findOrInsertSummary(D); 103992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose I->second.TimesInlined++; 1047959671d456c916706a5f61af609d8f1fc95decfAnna Zaks } 1057959671d456c916706a5f61af609d8f1fc95decfAnna Zaks 106cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks /// Get the percentage of the reachable blocks. 107cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks unsigned getPercentBlocksReachable(const Decl *D) { 108cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks MapTy::const_iterator I = Map.find(D); 109cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks if (I != Map.end()) 110992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose return ((I->second.VisitedBasicBlocks.count() * 100) / 111992acb2269171b6ef68694d71a36f6b7408d8e82Jordan Rose I->second.TotalBasicBlocks); 112cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks return 0; 113cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks } 114cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks 115e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getTotalNumBasicBlocks(); 116e62f048960645b79363408fdead53fec2a063c52Anna Zaks unsigned getTotalNumVisitedBasicBlocks(); 117cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks 118e62f048960645b79363408fdead53fec2a063c52Anna Zaks}; 119e62f048960645b79363408fdead53fec2a063c52Anna Zaks 120e62f048960645b79363408fdead53fec2a063c52Anna Zaks}} // end clang ento namespaces 121e62f048960645b79363408fdead53fec2a063c52Anna Zaks 122e62f048960645b79363408fdead53fec2a063c52Anna Zaks#endif 123