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