]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / StaticAnalyzer / Core / PathSensitive / FunctionSummary.h
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/None.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/SmallBitVector.h"
23 #include <cassert>
24 #include <deque>
25 #include <utility>
26
27 namespace clang {
28 namespace ento {
29
30 using SetOfDecls = std::deque<Decl *>;
31 using SetOfConstDecls = llvm::DenseSet<const Decl *>;
32
33 class FunctionSummariesTy {
34   class FunctionSummary {
35   public:
36     /// Marks the IDs of the basic blocks visited during the analyzes.
37     llvm::SmallBitVector VisitedBasicBlocks;
38
39     /// Total number of blocks in the function.
40     unsigned TotalBasicBlocks : 30;
41
42     /// True if this function has been checked against the rules for which
43     /// functions may be inlined.
44     unsigned InlineChecked : 1;
45
46     /// True if this function may be inlined.
47     unsigned MayInline : 1;
48
49     /// The number of times the function has been inlined.
50     unsigned TimesInlined : 32;
51
52     FunctionSummary()
53         : TotalBasicBlocks(0), InlineChecked(0), MayInline(0),
54           TimesInlined(0) {}
55   };
56
57   using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>;
58   MapTy Map;
59
60 public:
61   MapTy::iterator findOrInsertSummary(const Decl *D) {
62     MapTy::iterator I = Map.find(D);
63     if (I != Map.end())
64       return I;
65
66     using KVPair = std::pair<const Decl *, FunctionSummary>;
67
68     I = Map.insert(KVPair(D, FunctionSummary())).first;
69     assert(I != Map.end());
70     return I;
71   }
72
73   void markMayInline(const Decl *D) {
74     MapTy::iterator I = findOrInsertSummary(D);
75     I->second.InlineChecked = 1;
76     I->second.MayInline = 1;
77   }
78
79   void markShouldNotInline(const Decl *D) {
80     MapTy::iterator I = findOrInsertSummary(D);
81     I->second.InlineChecked = 1;
82     I->second.MayInline = 0;
83   }
84
85   void markReachedMaxBlockCount(const Decl *D) {
86     markShouldNotInline(D);
87   }
88
89   Optional<bool> mayInline(const Decl *D) {
90     MapTy::const_iterator I = Map.find(D);
91     if (I != Map.end() && I->second.InlineChecked)
92       return I->second.MayInline;
93     return None;
94   }
95
96   void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
97     MapTy::iterator I = findOrInsertSummary(D);
98     llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
99     assert(ID < TotalIDs);
100     if (TotalIDs > Blocks.size()) {
101       Blocks.resize(TotalIDs);
102       I->second.TotalBasicBlocks = TotalIDs;
103     }
104     Blocks.set(ID);
105   }
106
107   unsigned getNumVisitedBasicBlocks(const Decl* D) {
108     MapTy::const_iterator I = Map.find(D);
109     if (I != Map.end())
110       return I->second.VisitedBasicBlocks.count();
111     return 0;
112   }
113
114   unsigned getNumTimesInlined(const Decl* D) {
115     MapTy::const_iterator I = Map.find(D);
116     if (I != Map.end())
117       return I->second.TimesInlined;
118     return 0;
119   }
120
121   void bumpNumTimesInlined(const Decl* D) {
122     MapTy::iterator I = findOrInsertSummary(D);
123     I->second.TimesInlined++;
124   }
125
126   /// Get the percentage of the reachable blocks.
127   unsigned getPercentBlocksReachable(const Decl *D) {
128     MapTy::const_iterator I = Map.find(D);
129       if (I != Map.end())
130         return ((I->second.VisitedBasicBlocks.count() * 100) /
131                  I->second.TotalBasicBlocks);
132     return 0;
133   }
134
135   unsigned getTotalNumBasicBlocks();
136   unsigned getTotalNumVisitedBasicBlocks();
137 };
138
139 } // namespace ento
140 } // namespace clang
141
142 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H