diff --git a/bolt/docs/Heatmaps.md b/bolt/docs/Heatmaps.md index bf68232ef7fee..9045ef4fbee4f 100644 --- a/bolt/docs/Heatmaps.md +++ b/bolt/docs/Heatmaps.md @@ -89,7 +89,13 @@ For the generation, the default bucket size was used with a line size of 128. Some useful options are: ``` --line-size= - number of entries per line (default 256) +-block-size= - heatmap bucket size in bytes (default 64) +-line-size= - number of entries per line (default 256). + Use 128 if the heatmap doesn't fit screen horizontally. -max-address= - maximum address considered valid for heatmap (default 4GB) -print-mappings - print mappings in the legend, between characters/blocks and text sections (default false) +-heatmap-zoom-out=,... - print zoomed out heatmaps with given block sizes, + must be multiples of block-size in ascending order. + Suggested values: 4096 (default page size), 16384 (16k page), + 1048576 (1MB for XL workloads). ``` diff --git a/bolt/include/bolt/Profile/Heatmap.h b/bolt/include/bolt/Profile/Heatmap.h index 9813e7fed486d..bf3d1c91c0aa5 100644 --- a/bolt/include/bolt/Profile/Heatmap.h +++ b/bolt/include/bolt/Profile/Heatmap.h @@ -85,6 +85,9 @@ class Heatmap { void printSectionHotness(raw_ostream &OS) const; size_t size() const { return Map.size(); } + + /// Increase bucket size to \p TargetSize, recomputing the heatmap. + bool resizeBucket(uint64_t TargetSize); }; } // namespace bolt diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index 6beb60741406e..aa681e633c0d8 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -68,6 +68,12 @@ FilterPID("pid", cl::Optional, cl::cat(AggregatorCategory)); +static cl::list + HeatmapZoomOut("heatmap-zoom-out", cl::CommaSeparated, + cl::desc("print secondary heatmaps with given bucket sizes"), + cl::value_desc("bucket_size"), cl::Optional, + cl::cat(HeatmapCategory)); + static cl::opt IgnoreBuildID("ignore-build-id", cl::desc("continue even if build-ids in input binary and perf.data mismatch"), @@ -1365,6 +1371,15 @@ std::error_code DataAggregator::printLBRHeatMap() { HM.printCDF(opts::HeatmapOutput + ".csv"); HM.printSectionHotness(opts::HeatmapOutput + "-section-hotness.csv"); } + // Provide coarse-grained heatmap if requested via --heatmap-zoom-out + for (const uint64_t NewBucketSize : opts::HeatmapZoomOut) { + if (!HM.resizeBucket(NewBucketSize)) + break; + if (opts::HeatmapOutput == "-") + HM.print(opts::HeatmapOutput); + else + HM.print(formatv("{0}-{1}", opts::HeatmapOutput, NewBucketSize).str()); + } return std::error_code(); } diff --git a/bolt/lib/Profile/Heatmap.cpp b/bolt/lib/Profile/Heatmap.cpp index c66c2e5487613..a73468ff0479c 100644 --- a/bolt/lib/Profile/Heatmap.cpp +++ b/bolt/lib/Profile/Heatmap.cpp @@ -364,5 +364,18 @@ void Heatmap::printSectionHotness(raw_ostream &OS) const { OS << formatv("[unmapped], 0x0, 0x0, {0:f4}, 0, 0\n", 100.0 * UnmappedHotness / NumTotalCounts); } + +bool Heatmap::resizeBucket(uint64_t TargetSize) { + if (TargetSize <= BucketSize) + return false; + std::map NewMap; + for (const auto [Bucket, Count] : Map) { + const uint64_t Address = Bucket * BucketSize; + NewMap[Address / TargetSize] += Count; + } + Map = NewMap; + BucketSize = TargetSize; + return true; +} } // namespace bolt } // namespace llvm diff --git a/bolt/test/X86/heatmap-preagg.test b/bolt/test/X86/heatmap-preagg.test index 306e74800a353..6ffed06a5cc19 100644 --- a/bolt/test/X86/heatmap-preagg.test +++ b/bolt/test/X86/heatmap-preagg.test @@ -3,8 +3,12 @@ RUN: yaml2obj %p/Inputs/blarge_new.yaml &> %t.exe ## Non-BOLTed input binary RUN: llvm-bolt-heatmap %t.exe -o %t --pa -p %p/Inputs/blarge_new.preagg.txt \ +RUN: --heatmap-zoom-out 128,1024 --line-size 64 \ RUN: 2>&1 | FileCheck --check-prefix CHECK-HEATMAP %s RUN: FileCheck %s --check-prefix CHECK-SEC-HOT --input-file %t-section-hotness.csv +RUN: FileCheck %s --check-prefix CHECK-HM-64 --input-file %t +RUN: FileCheck %s --check-prefix CHECK-HM-128 --input-file %t-128 +RUN: FileCheck %s --check-prefix CHECK-HM-1024 --input-file %t-1024 ## BOLTed input binary RUN: llvm-bolt %t.exe -o %t.out --pa -p %p/Inputs/blarge_new.preagg.txt \ @@ -24,6 +28,29 @@ CHECK-SEC-HOT-NEXT: .plt, 0x401020, 0x4010b0, 4.7583, 66.6667, 0.0317 CHECK-SEC-HOT-NEXT: .text, 0x4010b0, 0x401c25, 78.3872, 85.1064, 0.6671 CHECK-SEC-HOT-NEXT: .fini, 0x401c28, 0x401c35, 0.0000, 0.0000, 0.0000 +# Only check x scales – can't check colors, and FileCheck doesn't strip color +# codes by default. +CHECK-HM-64: (299, 937] +CHECK-HM-64-NEXT: 0 +CHECK-HM-64-NEXT: 0 +CHECK-HM-64-NEXT: 0 1 2 3 4 5 6 7 8 9 a b c d e f +CHECK-HM-64-NEXT: 048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c +CHECK-HM-64-NEXT: 0 + +CHECK-HM-128: (299, 937] +CHECK-HM-128-NEXT: 0 +CHECK-HM-128-NEXT: 0 1 +CHECK-HM-128-NEXT: 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f +CHECK-HM-128-NEXT: 0808080808080808080808080808080808080808080808080808080808080808 +CHECK-HM-128-NEXT: 0 + +CHECK-HM-1024: (483, 1663] +CHECK-HM-1024-NEXT: 0 +CHECK-HM-1024-NEXT: 0 1 2 3 4 5 6 7 8 9 a b c d e f +CHECK-HM-1024-NEXT: 048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c +CHECK-HM-1024-NEXT: 0 +CHECK-HM-1024-NEXT: 0 + CHECK-HEATMAP-BAT: PERF2BOLT: read 79 aggregated LBR entries CHECK-HEATMAP-BAT: HEATMAP: invalid traces: 2