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