Clang Project

clang_source_code/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
27namespace clang {
28namespace ento {
29
30using SetOfDecls = std::deque<Decl *>;
31using SetOfConstDecls = llvm::DenseSet<const Decl *>;
32
33class 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
60public:
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<boolmayInline(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 IDconst DeclDunsigned 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 DeclD) {
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 DeclD) {
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 DeclD) {
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
143
clang::ento::FunctionSummariesTy::FunctionSummary
clang::ento::FunctionSummariesTy::FunctionSummary::VisitedBasicBlocks
clang::ento::FunctionSummariesTy::FunctionSummary::TotalBasicBlocks
clang::ento::FunctionSummariesTy::FunctionSummary::InlineChecked
clang::ento::FunctionSummariesTy::FunctionSummary::MayInline
clang::ento::FunctionSummariesTy::FunctionSummary::TimesInlined
clang::ento::FunctionSummariesTy::Map
clang::ento::FunctionSummariesTy::findOrInsertSummary
clang::ento::FunctionSummariesTy::markMayInline
clang::ento::FunctionSummariesTy::markShouldNotInline
clang::ento::FunctionSummariesTy::markReachedMaxBlockCount
clang::ento::FunctionSummariesTy::mayInline
clang::ento::FunctionSummariesTy::markVisitedBasicBlock
clang::ento::FunctionSummariesTy::getNumVisitedBasicBlocks
clang::ento::FunctionSummariesTy::getNumTimesInlined
clang::ento::FunctionSummariesTy::bumpNumTimesInlined
clang::ento::FunctionSummariesTy::getPercentBlocksReachable
clang::ento::FunctionSummariesTy::getTotalNumBasicBlocks
clang::ento::FunctionSummariesTy::getTotalNumVisitedBasicBlocks