Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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/SmallBitVector.h"
  21. #include <cassert>
  22. #include <deque>
  23. #include <optional>
  24. #include <utility>
  25.  
  26. namespace clang {
  27. namespace ento {
  28.  
  29. using SetOfDecls = std::deque<Decl *>;
  30. using SetOfConstDecls = llvm::DenseSet<const Decl *>;
  31.  
  32. class FunctionSummariesTy {
  33.   class FunctionSummary {
  34.   public:
  35.     /// Marks the IDs of the basic blocks visited during the analyzes.
  36.     llvm::SmallBitVector VisitedBasicBlocks;
  37.  
  38.     /// Total number of blocks in the function.
  39.     unsigned TotalBasicBlocks : 30;
  40.  
  41.     /// True if this function has been checked against the rules for which
  42.     /// functions may be inlined.
  43.     unsigned InlineChecked : 1;
  44.  
  45.     /// True if this function may be inlined.
  46.     unsigned MayInline : 1;
  47.  
  48.     /// The number of times the function has been inlined.
  49.     unsigned TimesInlined : 32;
  50.  
  51.     FunctionSummary()
  52.         : TotalBasicBlocks(0), InlineChecked(0), MayInline(0),
  53.           TimesInlined(0) {}
  54.   };
  55.  
  56.   using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>;
  57.   MapTy Map;
  58.  
  59. public:
  60.   MapTy::iterator findOrInsertSummary(const Decl *D) {
  61.     MapTy::iterator I = Map.find(D);
  62.     if (I != Map.end())
  63.       return I;
  64.  
  65.     using KVPair = std::pair<const Decl *, FunctionSummary>;
  66.  
  67.     I = Map.insert(KVPair(D, FunctionSummary())).first;
  68.     assert(I != Map.end());
  69.     return I;
  70.   }
  71.  
  72.   void markMayInline(const Decl *D) {
  73.     MapTy::iterator I = findOrInsertSummary(D);
  74.     I->second.InlineChecked = 1;
  75.     I->second.MayInline = 1;
  76.   }
  77.  
  78.   void markShouldNotInline(const Decl *D) {
  79.     MapTy::iterator I = findOrInsertSummary(D);
  80.     I->second.InlineChecked = 1;
  81.     I->second.MayInline = 0;
  82.   }
  83.  
  84.   void markReachedMaxBlockCount(const Decl *D) {
  85.     markShouldNotInline(D);
  86.   }
  87.  
  88.   std::optional<bool> mayInline(const Decl *D) {
  89.     MapTy::const_iterator I = Map.find(D);
  90.     if (I != Map.end() && I->second.InlineChecked)
  91.       return I->second.MayInline;
  92.     return std::nullopt;
  93.   }
  94.  
  95.   void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
  96.     MapTy::iterator I = findOrInsertSummary(D);
  97.     llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
  98.     assert(ID < TotalIDs);
  99.     if (TotalIDs > Blocks.size()) {
  100.       Blocks.resize(TotalIDs);
  101.       I->second.TotalBasicBlocks = TotalIDs;
  102.     }
  103.     Blocks.set(ID);
  104.   }
  105.  
  106.   unsigned getNumVisitedBasicBlocks(const Decl* D) {
  107.     MapTy::const_iterator I = Map.find(D);
  108.     if (I != Map.end())
  109.       return I->second.VisitedBasicBlocks.count();
  110.     return 0;
  111.   }
  112.  
  113.   unsigned getNumTimesInlined(const Decl* D) {
  114.     MapTy::const_iterator I = Map.find(D);
  115.     if (I != Map.end())
  116.       return I->second.TimesInlined;
  117.     return 0;
  118.   }
  119.  
  120.   void bumpNumTimesInlined(const Decl* D) {
  121.     MapTy::iterator I = findOrInsertSummary(D);
  122.     I->second.TimesInlined++;
  123.   }
  124.  
  125.   /// Get the percentage of the reachable blocks.
  126.   unsigned getPercentBlocksReachable(const Decl *D) {
  127.     MapTy::const_iterator I = Map.find(D);
  128.       if (I != Map.end())
  129.         return ((I->second.VisitedBasicBlocks.count() * 100) /
  130.                  I->second.TotalBasicBlocks);
  131.     return 0;
  132.   }
  133.  
  134.   unsigned getTotalNumBasicBlocks();
  135.   unsigned getTotalNumVisitedBasicBlocks();
  136. };
  137.  
  138. } // namespace ento
  139. } // namespace clang
  140.  
  141. #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
  142.