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