[llvm] [PGO] Gracefully handle zero entry-count in `fixFuncEntryCount` (PR #112029)
Michael O'Farrell via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 09:22:28 PDT 2024
https://github.com/mofarrell updated https://github.com/llvm/llvm-project/pull/112029
>From 83a55a2bca4aee1659b05f9ad224762e9306d607 Mon Sep 17 00:00:00 2001
From: Michael O'Farrell <micpof at gmail.com>
Date: Tue, 8 Oct 2024 10:41:11 -0700
Subject: [PATCH 1/2] [PGO] Gracefully handle zero entry-count
With sampled instrumentation (#69535), profile counts can appear
corrupt. In particular a function can have a 0 block counts for all its
blocks, while having some non-zero counters for select instrumentation.
This is only possible for colder functions, and a reasonable
modification to ensure the entry is non-zero (required by
`fixFuncEntryCounts`) is to set the counter to one. This is only likely
to happen for colder functions, so it is reasonable to take any action
that does not crash.
---
.../lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index dbe908bb5e72f3..3fe1d236ae22b5 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -1624,8 +1624,12 @@ void PGOUseFunc::populateCounters() {
FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
}
- // Fix the obviously inconsistent entry count.
- if (FuncMaxCount > 0 && FuncEntryCount == 0)
+ // Fix the obviously inconsistent entry count. A function that has all zero
+ // counters will skip populating the counters so a minimum entry count of 1
+ // makes sense. Note that the presence of a non-zero counter does not imply
+ // FuncMaxCount is greater than zero because the only non-zero counts could
+ // be for select instrumentation which is handled later.
+ if (FuncEntryCount == 0)
FuncEntryCount = 1;
F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
markFunctionAttributes(FuncEntryCount, FuncMaxCount);
>From abfdcb663983eaa8c7ce0d03a3c6440c5fc97e9a Mon Sep 17 00:00:00 2001
From: Michael O'Farrell <micpof at gmail.com>
Date: Wed, 16 Oct 2024 12:25:15 -0700
Subject: [PATCH 2/2] [PGO] Test graceful handling of zero profile counts
This crashed before making fixFuncEntryCount gracefully handle zero
counts.
---
.../Inputs/fix_entry_count_sampled.proftext | 8 ++++++
.../PGOProfile/fix_entry_count_sampled.ll | 28 +++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 llvm/test/Transforms/PGOProfile/Inputs/fix_entry_count_sampled.proftext
create mode 100644 llvm/test/Transforms/PGOProfile/fix_entry_count_sampled.ll
diff --git a/llvm/test/Transforms/PGOProfile/Inputs/fix_entry_count_sampled.proftext b/llvm/test/Transforms/PGOProfile/Inputs/fix_entry_count_sampled.proftext
new file mode 100644
index 00000000000000..8578f8be07fa8a
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/Inputs/fix_entry_count_sampled.proftext
@@ -0,0 +1,8 @@
+:ir
+test_no_entry_block_counter
+431494656217155589
+3
+0
+0
+1
+
diff --git a/llvm/test/Transforms/PGOProfile/fix_entry_count_sampled.ll b/llvm/test/Transforms/PGOProfile/fix_entry_count_sampled.ll
new file mode 100644
index 00000000000000..56d26178cd6265
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/fix_entry_count_sampled.ll
@@ -0,0 +1,28 @@
+; RUN: llvm-profdata merge %S/Inputs/fix_entry_count_sampled.proftext -o %t.profdata
+; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s --check-prefix=USE
+
+; Instrumentation PGO sampling makes corrupt looking counters possible. This
+; tests one extreme case:
+; Test loading zero profile counts for all instrumented blocks while the entry
+; block is not instrumented. Additionally include a non-zero profile count for
+; a select instruction, which prevents short circuiting the PGO application.
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @test_no_entry_block_counter(i32 %n) {
+; USE: define i32 @test_no_entry_block_counter(i32 %n)
+; USE-SAME: !prof ![[ENTRY_COUNT:[0-9]*]]
+entry:
+ %cmp = icmp slt i32 42, %n
+ br i1 %cmp, label %tail1, label %tail2
+tail1:
+ %ret = select i1 true, i32 %n, i32 42
+; USE: %ret = select i1 true, i32 %n, i32 42
+; USE-SAME: !prof ![[BW_FOR_SELECT:[0-9]+]]
+ ret i32 %ret
+tail2:
+ ret i32 42
+}
+; USE: ![[ENTRY_COUNT]] = !{!"function_entry_count", i64 1}
+; USE: ![[BW_FOR_SELECT]] = !{!"branch_weights", i32 1, i32 0}
More information about the llvm-commits
mailing list