Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This file defines a summary of a function gathered/used by static analysis. |
||
10 | // |
||
11 | //===----------------------------------------------------------------------===// |
||
12 | |||
13 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H |
||
14 | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H |
||
15 | |||
16 | #include "clang/AST/Decl.h" |
||
17 | #include "clang/Basic/LLVM.h" |
||
18 | #include "llvm/ADT/DenseMap.h" |
||
19 | #include "llvm/ADT/DenseSet.h" |
||
20 | #include "llvm/ADT/SmallBitVector.h" |
||
21 | #include <cassert> |
||
22 | #include <deque> |
||
23 | #include <optional> |
||
24 | #include <utility> |
||
25 | |||
26 | namespace clang { |
||
27 | namespace ento { |
||
28 | |||
29 | using SetOfDecls = std::deque<Decl *>; |
||
30 | using SetOfConstDecls = llvm::DenseSet<const Decl *>; |
||
31 | |||
32 | class FunctionSummariesTy { |
||
33 | class FunctionSummary { |
||
34 | public: |
||
35 | /// Marks the IDs of the basic blocks visited during the analyzes. |
||
36 | llvm::SmallBitVector VisitedBasicBlocks; |
||
37 | |||
38 | /// Total number of blocks in the function. |
||
39 | unsigned TotalBasicBlocks : 30; |
||
40 | |||
41 | /// True if this function has been checked against the rules for which |
||
42 | /// functions may be inlined. |
||
43 | unsigned InlineChecked : 1; |
||
44 | |||
45 | /// True if this function may be inlined. |
||
46 | unsigned MayInline : 1; |
||
47 | |||
48 | /// The number of times the function has been inlined. |
||
49 | unsigned TimesInlined : 32; |
||
50 | |||
51 | FunctionSummary() |
||
52 | : TotalBasicBlocks(0), InlineChecked(0), MayInline(0), |
||
53 | TimesInlined(0) {} |
||
54 | }; |
||
55 | |||
56 | using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>; |
||
57 | MapTy Map; |
||
58 | |||
59 | public: |
||
60 | MapTy::iterator findOrInsertSummary(const Decl *D) { |
||
61 | MapTy::iterator I = Map.find(D); |
||
62 | if (I != Map.end()) |
||
63 | return I; |
||
64 | |||
65 | using KVPair = std::pair<const Decl *, FunctionSummary>; |
||
66 | |||
67 | I = Map.insert(KVPair(D, FunctionSummary())).first; |
||
68 | assert(I != Map.end()); |
||
69 | return I; |
||
70 | } |
||
71 | |||
72 | void markMayInline(const Decl *D) { |
||
73 | MapTy::iterator I = findOrInsertSummary(D); |
||
74 | I->second.InlineChecked = 1; |
||
75 | I->second.MayInline = 1; |
||
76 | } |
||
77 | |||
78 | void markShouldNotInline(const Decl *D) { |
||
79 | MapTy::iterator I = findOrInsertSummary(D); |
||
80 | I->second.InlineChecked = 1; |
||
81 | I->second.MayInline = 0; |
||
82 | } |
||
83 | |||
84 | void markReachedMaxBlockCount(const Decl *D) { |
||
85 | markShouldNotInline(D); |
||
86 | } |
||
87 | |||
88 | std::optional<bool> mayInline(const Decl *D) { |
||
89 | MapTy::const_iterator I = Map.find(D); |
||
90 | if (I != Map.end() && I->second.InlineChecked) |
||
91 | return I->second.MayInline; |
||
92 | return std::nullopt; |
||
93 | } |
||
94 | |||
95 | void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { |
||
96 | MapTy::iterator I = findOrInsertSummary(D); |
||
97 | llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks; |
||
98 | assert(ID < TotalIDs); |
||
99 | if (TotalIDs > Blocks.size()) { |
||
100 | Blocks.resize(TotalIDs); |
||
101 | I->second.TotalBasicBlocks = TotalIDs; |
||
102 | } |
||
103 | Blocks.set(ID); |
||
104 | } |
||
105 | |||
106 | unsigned getNumVisitedBasicBlocks(const Decl* D) { |
||
107 | MapTy::const_iterator I = Map.find(D); |
||
108 | if (I != Map.end()) |
||
109 | return I->second.VisitedBasicBlocks.count(); |
||
110 | return 0; |
||
111 | } |
||
112 | |||
113 | unsigned getNumTimesInlined(const Decl* D) { |
||
114 | MapTy::const_iterator I = Map.find(D); |
||
115 | if (I != Map.end()) |
||
116 | return I->second.TimesInlined; |
||
117 | return 0; |
||
118 | } |
||
119 | |||
120 | void bumpNumTimesInlined(const Decl* D) { |
||
121 | MapTy::iterator I = findOrInsertSummary(D); |
||
122 | I->second.TimesInlined++; |
||
123 | } |
||
124 | |||
125 | /// Get the percentage of the reachable blocks. |
||
126 | unsigned getPercentBlocksReachable(const Decl *D) { |
||
127 | MapTy::const_iterator I = Map.find(D); |
||
128 | if (I != Map.end()) |
||
129 | return ((I->second.VisitedBasicBlocks.count() * 100) / |
||
130 | I->second.TotalBasicBlocks); |
||
131 | return 0; |
||
132 | } |
||
133 | |||
134 | unsigned getTotalNumBasicBlocks(); |
||
135 | unsigned getTotalNumVisitedBasicBlocks(); |
||
136 | }; |
||
137 | |||
138 | } // namespace ento |
||
139 | } // namespace clang |
||
140 | |||
141 | #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H |