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