xref: /llvm-project/bolt/include/bolt/Profile/Heatmap.h (revision 733dc3e50b2d34ebccaba24ca72ce72b5a3545f6)
1 //===- bolt/Profile/Heatmap.h -----------------------------------*- 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 #ifndef BOLT_PROFILE_HEATMAP_H
10 #define BOLT_PROFILE_HEATMAP_H
11 
12 #include "llvm/ADT/StringRef.h"
13 #include <cstdint>
14 #include <map>
15 #include <vector>
16 
17 namespace llvm {
18 class raw_ostream;
19 
20 namespace bolt {
21 
22 /// Struct representing a section name and its address range in the binary.
23 struct SectionNameAndRange {
24   StringRef Name;
25   uint64_t BeginAddress;
26   uint64_t EndAddress;
27 };
28 
29 class Heatmap {
30   /// Number of bytes per entry in the heat map.
31   size_t BucketSize;
32 
33   /// Minimum address that is considered to be valid.
34   uint64_t MinAddress;
35 
36   /// Maximum address that is considered to be valid.
37   uint64_t MaxAddress;
38 
39   /// Count invalid ranges.
40   uint64_t NumSkippedRanges{0};
41 
42   /// Map buckets to the number of samples.
43   std::map<uint64_t, uint64_t> Map;
44 
45   /// Map section names to their address range.
46   const std::vector<SectionNameAndRange> TextSections;
47 
48 public:
49   explicit Heatmap(uint64_t BucketSize = 4096, uint64_t MinAddress = 0,
50                    uint64_t MaxAddress = std::numeric_limits<uint64_t>::max(),
51                    std::vector<SectionNameAndRange> TextSections = {})
BucketSize(BucketSize)52       : BucketSize(BucketSize), MinAddress(MinAddress), MaxAddress(MaxAddress),
53         TextSections(TextSections) {}
54 
ignoreAddress(uint64_t Address)55   inline bool ignoreAddress(uint64_t Address) const {
56     return (Address > MaxAddress) || (Address < MinAddress);
57   }
58 
59   /// Register a single sample at \p Address.
registerAddress(uint64_t Address)60   void registerAddress(uint64_t Address) {
61     if (!ignoreAddress(Address))
62       ++Map[Address / BucketSize];
63   }
64 
65   /// Register \p Count samples at [\p StartAddress, \p EndAddress ].
66   void registerAddressRange(uint64_t StartAddress, uint64_t EndAddress,
67                             uint64_t Count);
68 
69   /// Return the number of ranges that failed to register.
getNumInvalidRanges()70   uint64_t getNumInvalidRanges() const { return NumSkippedRanges; }
71 
72   void print(StringRef FileName) const;
73 
74   void print(raw_ostream &OS) const;
75 
76   void printCDF(StringRef FileName) const;
77 
78   void printCDF(raw_ostream &OS) const;
79 
80   void printSectionHotness(StringRef Filename) const;
81 
82   void printSectionHotness(raw_ostream &OS) const;
83 
size()84   size_t size() const { return Map.size(); }
85 };
86 
87 } // namespace bolt
88 } // namespace llvm
89 
90 #endif
91