Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:08

0001 //===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines a summary of a function gathered/used by static analysis.
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     /// Marks the IDs of the basic blocks visited during the analyzes.
0036     llvm::SmallBitVector VisitedBasicBlocks;
0037 
0038     /// Total number of blocks in the function.
0039     unsigned TotalBasicBlocks : 30;
0040 
0041     /// True if this function has been checked against the rules for which
0042     /// functions may be inlined.
0043     unsigned InlineChecked : 1;
0044 
0045     /// True if this function may be inlined.
0046     unsigned MayInline : 1;
0047 
0048     /// The number of times the function has been inlined.
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   /// Get the percentage of the reachable blocks.
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 } // namespace ento
0135 } // namespace clang
0136 
0137 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H