1 //== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a summary of a function gathered/used by static analysis.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
15 #define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
17 #include "clang/Basic/LLVM.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/DenseSet.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/SmallBitVector.h"
28 typedef std::deque<Decl*> SetOfDecls;
29 typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
31 class FunctionSummariesTy {
32 class FunctionSummary {
34 /// Marks the IDs of the basic blocks visited during the analyzes.
35 llvm::SmallBitVector VisitedBasicBlocks;
37 /// Total number of blocks in the function.
38 unsigned TotalBasicBlocks : 30;
40 /// True if this function has been checked against the rules for which
41 /// functions may be inlined.
42 unsigned InlineChecked : 1;
44 /// True if this function may be inlined.
45 unsigned MayInline : 1;
47 /// The number of times the function has been inlined.
48 unsigned TimesInlined : 32;
56 typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
60 MapTy::iterator findOrInsertSummary(const Decl *D) {
61 MapTy::iterator I = Map.find(D);
65 typedef std::pair<const Decl *, FunctionSummary> KVPair;
66 I = Map.insert(KVPair(D, FunctionSummary())).first;
67 assert(I != Map.end());
71 void markMayInline(const Decl *D) {
72 MapTy::iterator I = findOrInsertSummary(D);
73 I->second.InlineChecked = 1;
74 I->second.MayInline = 1;
77 void markShouldNotInline(const Decl *D) {
78 MapTy::iterator I = findOrInsertSummary(D);
79 I->second.InlineChecked = 1;
80 I->second.MayInline = 0;
83 void markReachedMaxBlockCount(const Decl *D) {
84 markShouldNotInline(D);
87 Optional<bool> mayInline(const Decl *D) {
88 MapTy::const_iterator I = Map.find(D);
89 if (I != Map.end() && I->second.InlineChecked)
90 return I->second.MayInline;
94 void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
95 MapTy::iterator I = findOrInsertSummary(D);
96 llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
97 assert(ID < TotalIDs);
98 if (TotalIDs > Blocks.size()) {
99 Blocks.resize(TotalIDs);
100 I->second.TotalBasicBlocks = TotalIDs;
105 unsigned getNumVisitedBasicBlocks(const Decl* D) {
106 MapTy::const_iterator I = Map.find(D);
108 return I->second.VisitedBasicBlocks.count();
112 unsigned getNumTimesInlined(const Decl* D) {
113 MapTy::const_iterator I = Map.find(D);
115 return I->second.TimesInlined;
119 void bumpNumTimesInlined(const Decl* D) {
120 MapTy::iterator I = findOrInsertSummary(D);
121 I->second.TimesInlined++;
124 /// Get the percentage of the reachable blocks.
125 unsigned getPercentBlocksReachable(const Decl *D) {
126 MapTy::const_iterator I = Map.find(D);
128 return ((I->second.VisitedBasicBlocks.count() * 100) /
129 I->second.TotalBasicBlocks);
133 unsigned getTotalNumBasicBlocks();
134 unsigned getTotalNumVisitedBasicBlocks();
138 }} // end clang ento namespaces