[llvm] [PGO] Fix incorrect count threshold calculation when 0% cutoff (PR #117359)

Ken Matsui via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 22 12:47:30 PST 2024


https://github.com/ken-matsui updated https://github.com/llvm/llvm-project/pull/117359

>From b62dc0bed5a49eadac32adb692ed1a701b924ac7 Mon Sep 17 00:00:00 2001
From: Ken Matsui <ken.matsui at mediatek.com>
Date: Fri, 22 Nov 2024 10:34:49 -0500
Subject: [PATCH] [PGO] Fix incorrect count threshold calculation when 0%
 cutoff

DefaultCutoffsData does not have an entry for the 0th percentile.  As a
result, when the getEntryForPercentile method is called with a
percentile argument of 0, it returns a ProfileSummaryEntry for the 1st
percentile instead.  This behavior affects the threshold calculations,
such as getHotCountThreshold, causing them to incorrectly identify some
sample profile counts as hot when they should not be.

This patch addresses the issue by adding an entry for the 0th percentile
to DetailedSummary.  This ensures that when the
-profile-summary-cutoff-hot (or -cold) option is set to 0, samples are
not incorrectly recognized as hot or cold.
---
 .../lib/ProfileData/ProfileSummaryBuilder.cpp | 12 ++++-
 llvm/test/Analysis/ProfileSummary/cutoff_0.ll | 48 +++++++++++++++++++
 .../cs-sample-nested-profile.test             |  2 +
 .../tools/llvm-profdata/sample-summary.test   |  1 +
 .../suppl-instr-with-sample.test              |  1 +
 llvm/tools/llvm-profdata/llvm-profdata.cpp    |  4 +-
 6 files changed, 65 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/Analysis/ProfileSummary/cutoff_0.ll

diff --git a/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp
index 3a45113b0a2eae..59a62867a211dd 100644
--- a/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp
+++ b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp
@@ -70,6 +70,7 @@ cl::opt<uint64_t> ProfileSummaryColdCount(
 // A set of cutoff values. Each value, when divided by ProfileSummary::Scale
 // (which is 1000000) is a desired percentile of total counts.
 static const uint32_t DefaultCutoffsData[] = {
+    0,      /*  0% */
     10000,  /*  1% */
     100000, /* 10% */
     200000, 300000, 400000, 500000, 600000, 700000, 800000,
@@ -134,13 +135,22 @@ void ProfileSummaryBuilder::computeDetailedSummary() {
   if (DetailedSummaryCutoffs.empty())
     return;
   llvm::sort(DetailedSummaryCutoffs);
+
+  size_t StartIdx = 0;
+  if (DetailedSummaryCutoffs.front() == 0) {
+    // Put an entry for the 0th percentile.  Assume there is no UINT64_MAX
+    // sample count.
+    DetailedSummary.emplace_back(0, UINT64_MAX, 0);
+    StartIdx = 1;
+  }
+
   auto Iter = CountFrequencies.begin();
   const auto End = CountFrequencies.end();
 
   uint32_t CountsSeen = 0;
   uint64_t CurrSum = 0, Count = 0;
 
-  for (const uint32_t Cutoff : DetailedSummaryCutoffs) {
+  for (const uint32_t Cutoff : drop_begin(DetailedSummaryCutoffs, StartIdx)) {
     assert(Cutoff <= 999999);
     APInt Temp(128, TotalCount);
     APInt N(128, Cutoff);
diff --git a/llvm/test/Analysis/ProfileSummary/cutoff_0.ll b/llvm/test/Analysis/ProfileSummary/cutoff_0.ll
new file mode 100644
index 00000000000000..b523e341625648
--- /dev/null
+++ b/llvm/test/Analysis/ProfileSummary/cutoff_0.ll
@@ -0,0 +1,48 @@
+; RUN: opt < %s -disable-output -passes=print-profile-summary -S 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-output -profile-summary-cutoff-hot=0 -passes=print-profile-summary -S 2>&1 | FileCheck %s -check-prefixes=HOT-CUTOFF-0
+; RUN: opt < %s -disable-output -profile-summary-cutoff-cold=0 -profile-summary-hot-count=18446744073709551615 -passes=print-profile-summary -S 2>&1 | FileCheck %s -check-prefixes=COLD-CUTOFF-0
+
+define void @f1() !prof !20 {
+; CHECK-LABEL: f1 :hot
+; HOT-CUTOFF-0-LABEL: f1{{$}}
+; COLD-CUTOFF-0-LABEL: f1 :cold
+
+  ret void
+}
+
+define void @f2() !prof !21 {
+; CHECK-LABEL: f2 :cold
+; HOT-CUTOFF-0-LABEL: f2 :cold
+; COLD-CUTOFF-0-LABEL: f2 :cold
+
+  ret void
+}
+
+define void @f3() !prof !22 {
+; CHECK-LABEL: f3 :hot
+; HOT-CUTOFF-0-LABEL: f3{{$}}
+; COLD-CUTOFF-0-LABEL: f3 :cold
+
+  ret void
+}
+
+!llvm.module.flags = !{!1}
+!20 = !{!"function_entry_count", i64 400}
+!21 = !{!"function_entry_count", i64 1}
+!22 = !{!"function_entry_count", i64 100}
+
+!1 = !{i32 1, !"ProfileSummary", !2}
+!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
+!3 = !{!"ProfileFormat", !"InstrProf"}
+!4 = !{!"TotalCount", i64 10000}
+!5 = !{!"MaxCount", i64 10}
+!6 = !{!"MaxInternalCount", i64 1}
+!7 = !{!"MaxFunctionCount", i64 1000}
+!8 = !{!"NumCounts", i64 3}
+!9 = !{!"NumFunctions", i64 3}
+!10 = !{!"DetailedSummary", !11}
+!11 = !{!12, !13, !14, !15}
+!12 = !{i32 0, i64 18446744073709551615, i32 0}
+!13 = !{i32 10000, i64 100, i32 1}
+!14 = !{i32 990000, i64 100, i32 1}
+!15 = !{i32 999999, i64 1, i32 2}
diff --git a/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test b/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test
index 7b01324219115c..a41471f50a4823 100644
--- a/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test
+++ b/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test
@@ -157,6 +157,7 @@ RUN: llvm-profdata show -sample -detailed-summary %t3.proftext | FileCheck %s -c
 ; SUMMARY-NEXT: Total number of blocks: 16
 ; SUMMARY-NEXT: Total count: 772562
 ; SUMMARY-NEXT: Detailed summary:
+; SUMMARY-NEXT: 0 blocks with count >= 18446744073709551615 account for 0 percentage of the total counts.
 ; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 1 percentage of the total counts.
 ; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 10 percentage of the total counts.
 ; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 20 percentage of the total counts.
@@ -181,6 +182,7 @@ RUN: llvm-profdata show -sample -detailed-summary %t3.proftext | FileCheck %s -c
 ; SUMMARY-NEST-NEXT: Total number of blocks: 15
 ; SUMMARY-NEST-NEXT: Total count: 772504
 ; SUMMARY-NEST-NEXT: Detailed summary:
+; SUMMARY-NEST-NEXT: 0 blocks with count >= 18446744073709551615 account for 0 percentage of the total counts.
 ; SUMMARY-NEST-NEXT: 1 blocks with count >= 362830 account for 1 percentage of the total counts.
 ; SUMMARY-NEST-NEXT: 1 blocks with count >= 362830 account for 10 percentage of the total counts.
 ; SUMMARY-NEST-NEXT: 1 blocks with count >= 362830 account for 20 percentage of the total counts.
diff --git a/llvm/test/tools/llvm-profdata/sample-summary.test b/llvm/test/tools/llvm-profdata/sample-summary.test
index 3326c9bb29806b..d4c648e9713fe3 100644
--- a/llvm/test/tools/llvm-profdata/sample-summary.test
+++ b/llvm/test/tools/llvm-profdata/sample-summary.test
@@ -6,6 +6,7 @@
 ; CHECK-NEXT: Total number of blocks: 11
 ; CHECK-NEXT: Total count: 12943
 ; CHECK-NEXT: Detailed summary:
+; CHECK-NEXT: 0 blocks with count >= 18446744073709551615 account for 0 percentage of the total counts.
 ; CHECK-NEXT: 1 blocks with count >= 2080 account for 1 percentage of the total counts.
 ; CHECK-NEXT: 1 blocks with count >= 2080 account for 10 percentage of the total counts.
 ; CHECK-NEXT: 2 blocks with count >= 2064 account for 20 percentage of the total counts.
diff --git a/llvm/test/tools/llvm-profdata/suppl-instr-with-sample.test b/llvm/test/tools/llvm-profdata/suppl-instr-with-sample.test
index 20d4d2198ff449..07c2a5d5a8e3e1 100644
--- a/llvm/test/tools/llvm-profdata/suppl-instr-with-sample.test
+++ b/llvm/test/tools/llvm-profdata/suppl-instr-with-sample.test
@@ -98,6 +98,7 @@ MIX5-NEXT: Maximum internal block count: 2000
 MIX5-NEXT: Total number of blocks: 9
 MIX5-NEXT: Total count: 6525
 MIX5-NEXT: Detailed summary:
+MIX5-NEXT: 0 blocks with count >= 18446744073709551615 account for 0 percentage of the total counts.
 MIX5-NEXT: 1 blocks with count >= 3000 account for 1 percentage of the total counts.
 MIX5-NEXT: 1 blocks with count >= 3000 account for 10 percentage of the total counts.
 MIX5-NEXT: 1 blocks with count >= 3000 account for 20 percentage of the total counts.
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 7641a80129de35..7a5fb436c73bd7 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -1111,8 +1111,8 @@ static void updateInstrProfileEntry(InstrProfileEntry &IFE, bool SetToHot,
   });
 }
 
-const uint64_t ColdPercentileIdx = 15;
-const uint64_t HotPercentileIdx = 11;
+const uint64_t ColdPercentileIdx = 16;
+const uint64_t HotPercentileIdx = 12;
 
 using sampleprof::FSDiscriminatorPass;
 



More information about the llvm-commits mailing list