diff options
Diffstat (limited to 'clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h')
| -rw-r--r-- | clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h new file mode 100644 index 00000000..53b4bf60 --- /dev/null +++ b/clang-r353983/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -0,0 +1,142 @@ +//===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a summary of a function gathered/used by static analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H + +#include "clang/AST/Decl.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallBitVector.h" +#include <cassert> +#include <deque> +#include <utility> + +namespace clang { +namespace ento { + +using SetOfDecls = std::deque<Decl *>; +using SetOfConstDecls = llvm::DenseSet<const Decl *>; + +class FunctionSummariesTy { + class FunctionSummary { + public: + /// Marks the IDs of the basic blocks visited during the analyzes. + llvm::SmallBitVector VisitedBasicBlocks; + + /// Total number of blocks in the function. + unsigned TotalBasicBlocks : 30; + + /// True if this function has been checked against the rules for which + /// functions may be inlined. + unsigned InlineChecked : 1; + + /// True if this function may be inlined. + unsigned MayInline : 1; + + /// The number of times the function has been inlined. + unsigned TimesInlined : 32; + + FunctionSummary() + : TotalBasicBlocks(0), InlineChecked(0), MayInline(0), + TimesInlined(0) {} + }; + + using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>; + MapTy Map; + +public: + MapTy::iterator findOrInsertSummary(const Decl *D) { + MapTy::iterator I = Map.find(D); + if (I != Map.end()) + return I; + + using KVPair = std::pair<const Decl *, FunctionSummary>; + + I = Map.insert(KVPair(D, FunctionSummary())).first; + assert(I != Map.end()); + return I; + } + + void markMayInline(const Decl *D) { + MapTy::iterator I = findOrInsertSummary(D); + I->second.InlineChecked = 1; + I->second.MayInline = 1; + } + + void markShouldNotInline(const Decl *D) { + MapTy::iterator I = findOrInsertSummary(D); + I->second.InlineChecked = 1; + I->second.MayInline = 0; + } + + void markReachedMaxBlockCount(const Decl *D) { + markShouldNotInline(D); + } + + Optional<bool> mayInline(const Decl *D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end() && I->second.InlineChecked) + return I->second.MayInline; + return None; + } + + void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { + MapTy::iterator I = findOrInsertSummary(D); + llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks; + assert(ID < TotalIDs); + if (TotalIDs > Blocks.size()) { + Blocks.resize(TotalIDs); + I->second.TotalBasicBlocks = TotalIDs; + } + Blocks.set(ID); + } + + unsigned getNumVisitedBasicBlocks(const Decl* D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end()) + return I->second.VisitedBasicBlocks.count(); + return 0; + } + + unsigned getNumTimesInlined(const Decl* D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end()) + return I->second.TimesInlined; + return 0; + } + + void bumpNumTimesInlined(const Decl* D) { + MapTy::iterator I = findOrInsertSummary(D); + I->second.TimesInlined++; + } + + /// Get the percentage of the reachable blocks. + unsigned getPercentBlocksReachable(const Decl *D) { + MapTy::const_iterator I = Map.find(D); + if (I != Map.end()) + return ((I->second.VisitedBasicBlocks.count() * 100) / + I->second.TotalBasicBlocks); + return 0; + } + + unsigned getTotalNumBasicBlocks(); + unsigned getTotalNumVisitedBasicBlocks(); +}; + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H |
