File indexing completed on 2026-05-10 08:37:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
0014 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
0015
0016 #include "clang/AST/Decl.h"
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/DenseSet.h"
0020 #include "llvm/ADT/SmallBitVector.h"
0021 #include <cassert>
0022 #include <deque>
0023 #include <optional>
0024 #include <utility>
0025
0026 namespace clang {
0027 namespace ento {
0028
0029 using SetOfDecls = std::deque<Decl *>;
0030 using SetOfConstDecls = llvm::DenseSet<const Decl *>;
0031
0032 class FunctionSummariesTy {
0033 class FunctionSummary {
0034 public:
0035
0036 llvm::SmallBitVector VisitedBasicBlocks;
0037
0038
0039 unsigned TotalBasicBlocks : 30;
0040
0041
0042
0043 unsigned InlineChecked : 1;
0044
0045
0046 unsigned MayInline : 1;
0047
0048
0049 unsigned TimesInlined : 32;
0050
0051 FunctionSummary()
0052 : TotalBasicBlocks(0), InlineChecked(0), MayInline(0),
0053 TimesInlined(0) {}
0054 };
0055
0056 using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>;
0057 MapTy Map;
0058
0059 public:
0060 MapTy::iterator findOrInsertSummary(const Decl *D) {
0061 MapTy::iterator I = Map.find(D);
0062 if (I != Map.end())
0063 return I;
0064
0065 using KVPair = std::pair<const Decl *, FunctionSummary>;
0066
0067 I = Map.insert(KVPair(D, FunctionSummary())).first;
0068 assert(I != Map.end());
0069 return I;
0070 }
0071
0072 void markMayInline(const Decl *D) {
0073 MapTy::iterator I = findOrInsertSummary(D);
0074 I->second.InlineChecked = 1;
0075 I->second.MayInline = 1;
0076 }
0077
0078 void markShouldNotInline(const Decl *D) {
0079 MapTy::iterator I = findOrInsertSummary(D);
0080 I->second.InlineChecked = 1;
0081 I->second.MayInline = 0;
0082 }
0083
0084 std::optional<bool> mayInline(const Decl *D) {
0085 MapTy::const_iterator I = Map.find(D);
0086 if (I != Map.end() && I->second.InlineChecked)
0087 return I->second.MayInline;
0088 return std::nullopt;
0089 }
0090
0091 void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
0092 MapTy::iterator I = findOrInsertSummary(D);
0093 llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
0094 assert(ID < TotalIDs);
0095 if (TotalIDs > Blocks.size()) {
0096 Blocks.resize(TotalIDs);
0097 I->second.TotalBasicBlocks = TotalIDs;
0098 }
0099 Blocks.set(ID);
0100 }
0101
0102 unsigned getNumVisitedBasicBlocks(const Decl* D) {
0103 MapTy::const_iterator I = Map.find(D);
0104 if (I != Map.end())
0105 return I->second.VisitedBasicBlocks.count();
0106 return 0;
0107 }
0108
0109 unsigned getNumTimesInlined(const Decl* D) {
0110 MapTy::const_iterator I = Map.find(D);
0111 if (I != Map.end())
0112 return I->second.TimesInlined;
0113 return 0;
0114 }
0115
0116 void bumpNumTimesInlined(const Decl* D) {
0117 MapTy::iterator I = findOrInsertSummary(D);
0118 I->second.TimesInlined++;
0119 }
0120
0121
0122 unsigned getPercentBlocksReachable(const Decl *D) {
0123 MapTy::const_iterator I = Map.find(D);
0124 if (I != Map.end())
0125 return ((I->second.VisitedBasicBlocks.count() * 100) /
0126 I->second.TotalBasicBlocks);
0127 return 0;
0128 }
0129
0130 unsigned getTotalNumBasicBlocks();
0131 unsigned getTotalNumVisitedBasicBlocks();
0132 };
0133
0134 }
0135 }
0136
0137 #endif