FunctionSummary.h revision 577f14a34457032523e59dbbbacb88ca2cd4db57
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
17577f14a34457032523e59dbbbacb88ca2cd4db57Ted Kremenek#include <deque>
18e62f048960645b79363408fdead53fec2a063c52Anna Zaks#include "clang/AST/Decl.h"
19e62f048960645b79363408fdead53fec2a063c52Anna Zaks#include "llvm/ADT/DenseMap.h"
20cb0a5039c243f5b0c178e70f424adac334e5789bTed Kremenek#include "llvm/ADT/DenseSet.h"
21e62f048960645b79363408fdead53fec2a063c52Anna Zaks#include "llvm/ADT/BitVector.h"
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
40e62f048960645b79363408fdead53fec2a063c52Anna Zaks    FunctionSummary() :
41e62f048960645b79363408fdead53fec2a063c52Anna Zaks      MayReachMaxBlockCount(false),
42e62f048960645b79363408fdead53fec2a063c52Anna Zaks      TotalBasicBlocks(0),
43e62f048960645b79363408fdead53fec2a063c52Anna Zaks      VisitedBasicBlocks(0) {}
44e62f048960645b79363408fdead53fec2a063c52Anna Zaks  };
45e62f048960645b79363408fdead53fec2a063c52Anna Zaks
46e62f048960645b79363408fdead53fec2a063c52Anna Zaks  typedef llvm::DenseMap<const Decl*, FunctionSummary*> MapTy;
47e62f048960645b79363408fdead53fec2a063c52Anna Zaks  MapTy Map;
48e62f048960645b79363408fdead53fec2a063c52Anna Zaks
49e62f048960645b79363408fdead53fec2a063c52Anna Zakspublic:
50e62f048960645b79363408fdead53fec2a063c52Anna Zaks  ~FunctionSummariesTy();
51e62f048960645b79363408fdead53fec2a063c52Anna Zaks
52e62f048960645b79363408fdead53fec2a063c52Anna Zaks  MapTy::iterator findOrInsertSummary(const Decl *D) {
53e62f048960645b79363408fdead53fec2a063c52Anna Zaks    MapTy::iterator I = Map.find(D);
54e62f048960645b79363408fdead53fec2a063c52Anna Zaks    if (I != Map.end())
55e62f048960645b79363408fdead53fec2a063c52Anna Zaks      return I;
56e62f048960645b79363408fdead53fec2a063c52Anna Zaks    FunctionSummary *DS = new FunctionSummary();
57e62f048960645b79363408fdead53fec2a063c52Anna Zaks    I = Map.insert(std::pair<const Decl*, FunctionSummary*>(D, DS)).first;
58e62f048960645b79363408fdead53fec2a063c52Anna Zaks    assert(I != Map.end());
59e62f048960645b79363408fdead53fec2a063c52Anna Zaks    return I;
60e62f048960645b79363408fdead53fec2a063c52Anna Zaks  }
61e62f048960645b79363408fdead53fec2a063c52Anna Zaks
62e62f048960645b79363408fdead53fec2a063c52Anna Zaks  void markReachedMaxBlockCount(const Decl* D) {
63e62f048960645b79363408fdead53fec2a063c52Anna Zaks    MapTy::iterator I = findOrInsertSummary(D);
64e62f048960645b79363408fdead53fec2a063c52Anna Zaks    I->second->MayReachMaxBlockCount = true;
65e62f048960645b79363408fdead53fec2a063c52Anna Zaks  }
66e62f048960645b79363408fdead53fec2a063c52Anna Zaks
67e62f048960645b79363408fdead53fec2a063c52Anna Zaks  bool hasReachedMaxBlockCount(const Decl* D) {
68e62f048960645b79363408fdead53fec2a063c52Anna Zaks  MapTy::const_iterator I = Map.find(D);
69e62f048960645b79363408fdead53fec2a063c52Anna Zaks    if (I != Map.end())
70e62f048960645b79363408fdead53fec2a063c52Anna Zaks      return I->second->MayReachMaxBlockCount;
71e62f048960645b79363408fdead53fec2a063c52Anna Zaks    return false;
72e62f048960645b79363408fdead53fec2a063c52Anna Zaks  }
73e62f048960645b79363408fdead53fec2a063c52Anna Zaks
74e62f048960645b79363408fdead53fec2a063c52Anna Zaks  void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
75e62f048960645b79363408fdead53fec2a063c52Anna Zaks    MapTy::iterator I = findOrInsertSummary(D);
76e62f048960645b79363408fdead53fec2a063c52Anna Zaks    llvm::BitVector &Blocks = I->second->VisitedBasicBlocks;
77e62f048960645b79363408fdead53fec2a063c52Anna Zaks    assert(ID < TotalIDs);
78e62f048960645b79363408fdead53fec2a063c52Anna Zaks    if (TotalIDs > Blocks.size()) {
79e62f048960645b79363408fdead53fec2a063c52Anna Zaks      Blocks.resize(TotalIDs);
80e62f048960645b79363408fdead53fec2a063c52Anna Zaks      I->second->TotalBasicBlocks = TotalIDs;
81e62f048960645b79363408fdead53fec2a063c52Anna Zaks    }
82e62f048960645b79363408fdead53fec2a063c52Anna Zaks    Blocks[ID] = true;
83e62f048960645b79363408fdead53fec2a063c52Anna Zaks  }
84e62f048960645b79363408fdead53fec2a063c52Anna Zaks
85e62f048960645b79363408fdead53fec2a063c52Anna Zaks  unsigned getNumVisitedBasicBlocks(const Decl* D) {
86e62f048960645b79363408fdead53fec2a063c52Anna Zaks    MapTy::const_iterator I = Map.find(D);
87e62f048960645b79363408fdead53fec2a063c52Anna Zaks      if (I != Map.end())
88e62f048960645b79363408fdead53fec2a063c52Anna Zaks        return I->second->VisitedBasicBlocks.count();
89e62f048960645b79363408fdead53fec2a063c52Anna Zaks    return 0;
90e62f048960645b79363408fdead53fec2a063c52Anna Zaks  }
91e62f048960645b79363408fdead53fec2a063c52Anna Zaks
92cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks  /// Get the percentage of the reachable blocks.
93cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks  unsigned getPercentBlocksReachable(const Decl *D) {
94cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks    MapTy::const_iterator I = Map.find(D);
95cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks      if (I != Map.end())
96cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks        return ((I->second->VisitedBasicBlocks.count() * 100) /
97cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks                 I->second->TotalBasicBlocks);
98cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks    return 0;
99cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks  }
100cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks
101e62f048960645b79363408fdead53fec2a063c52Anna Zaks  unsigned getTotalNumBasicBlocks();
102e62f048960645b79363408fdead53fec2a063c52Anna Zaks  unsigned getTotalNumVisitedBasicBlocks();
103cd863466b97cee866370bc6ff75370628ab01d37Anna Zaks
104e62f048960645b79363408fdead53fec2a063c52Anna Zaks};
105e62f048960645b79363408fdead53fec2a063c52Anna Zaks
106e62f048960645b79363408fdead53fec2a063c52Anna Zaks}} // end clang ento namespaces
107e62f048960645b79363408fdead53fec2a063c52Anna Zaks
108e62f048960645b79363408fdead53fec2a063c52Anna Zaks#endif
109