[llvm-branch-commits] [llvm] [StaticDataLayout] Reconcile string literal hotness from data access profiles and PGO profiles. (PR #178336)
Mingming Liu via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 28 10:56:59 PST 2026
https://github.com/mingmingl-llvm updated https://github.com/llvm/llvm-project/pull/178336
>From d87fb4893d7f59c9cc6725a57fd8f8fbea914d90 Mon Sep 17 00:00:00 2001
From: Mingming Liu <mingmingl at google.com>
Date: Tue, 27 Jan 2026 17:41:33 -0800
Subject: [PATCH 1/3] Update codegen pass
---
llvm/lib/Analysis/StaticDataProfileInfo.cpp | 10 +++++-----
llvm/lib/Transforms/Instrumentation/MemProfUse.cpp | 14 +++++++-------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Analysis/StaticDataProfileInfo.cpp b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
index 61d49350c7702..96771ca8660a9 100644
--- a/llvm/lib/Analysis/StaticDataProfileInfo.cpp
+++ b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
@@ -12,6 +12,7 @@
using namespace llvm;
namespace llvm {
+extern cl::opt<unsigned> AnnotateStringLiteralSectionPrefix;
namespace memprof {
// Returns true iff the global variable has custom section either by
// __attribute__((section("name")))
@@ -124,11 +125,12 @@ StringRef StaticDataProfileInfo::getConstantSectionPrefix(
#endif
if (EnableDataAccessProf) {
- // Module flag `HasDataAccessProf` is 1 -> empty section prefix means
- // unknown hotness except for string literals.
+ // Both data access profiles and PGO counters are available. Use the
+ // hotter one.
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C);
GV && llvm::memprof::IsAnnotationOK(*GV) &&
- !GV->getName().starts_with(".str")) {
+ (AnnotateStringLiteralSectionPrefix ||
+ !GV->getName().starts_with(".str"))) {
auto HotnessFromDataAccessProf =
getSectionHotnessUsingDataAccessProfile(GV->getSectionPrefix());
@@ -140,8 +142,6 @@ StringRef StaticDataProfileInfo::getConstantSectionPrefix(
return Prefix;
}
- // Both data access profiles and PGO counters are available. Use the
- // hotter one.
auto HotnessFromPGO = getConstantHotnessUsingProfileCount(C, PSI, *Count);
StaticDataHotness GlobalVarHotness = StaticDataHotness::LukewarmOrUnknown;
if (HotnessFromDataAccessProf == StaticDataHotness::Hot ||
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index bf7df69ee5c3b..c2856bb532930 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -45,6 +45,13 @@ namespace llvm {
extern cl::opt<bool> PGOWarnMissing;
extern cl::opt<bool> NoPGOWarnMismatch;
extern cl::opt<bool> NoPGOWarnMismatchComdatWeak;
+// FIXME: This option is added for incremental rollout purposes.
+// After the option, string literal partitioning should be implied by
+// AnnotateStaticDataSectionPrefix above and this option should be cleaned up.
+cl::opt<bool> AnnotateStringLiteralSectionPrefix(
+ "memprof-annotate-string-literal-section-prefix", cl::init(false),
+ cl::Hidden,
+ cl::desc("If true, annotate the string literal data section prefix"));
} // namespace llvm
// By default disable matching of allocation profiles onto operator new that
@@ -92,13 +99,6 @@ static cl::opt<bool> AnnotateStaticDataSectionPrefix(
"memprof-annotate-static-data-prefix", cl::init(false), cl::Hidden,
cl::desc("If true, annotate the static data section prefix"));
-// FIXME: This option is added for incremental rollout purposes.
-// After the option, string literal partitioning should be implied by
-// AnnotateStaticDataSectionPrefix above and this option should be cleaned up.
-static cl::opt<bool> AnnotateStringLiteralSectionPrefix(
- "memprof-annotate-string-literal-section-prefix", cl::init(false), cl::Hidden,
- cl::desc("If true, annotate the string literal data section prefix"));
-
// Matching statistics
STATISTIC(NumOfMemProfMissing, "Number of functions without memory profile.");
STATISTIC(NumOfMemProfMismatch,
>From ff7bfb9a8da8b5f2d689c0c94e5805d70c4c305e Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 28 Jan 2026 08:54:29 -0800
Subject: [PATCH 2/3] Move option from transforms to analysis pass
---
llvm/lib/Analysis/StaticDataProfileInfo.cpp | 9 ++++++++-
llvm/lib/Transforms/Instrumentation/MemProfUse.cpp | 9 +--------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Analysis/StaticDataProfileInfo.cpp b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
index 96771ca8660a9..e06380bdd5d26 100644
--- a/llvm/lib/Analysis/StaticDataProfileInfo.cpp
+++ b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
@@ -12,7 +12,14 @@
using namespace llvm;
namespace llvm {
-extern cl::opt<unsigned> AnnotateStringLiteralSectionPrefix;
+// FIXME: This option is added for incremental rollout purposes.
+// After the option, string literal partitioning should be implied by
+// AnnotateStaticDataSectionPrefix in MemProfUse.cpp and this option should be
+// cleaned up.
+cl::opt<bool> AnnotateStringLiteralSectionPrefix(
+ "memprof-annotate-string-literal-section-prefix", cl::init(false),
+ cl::Hidden,
+ cl::desc("If true, annotate the string literal data section prefix"));
namespace memprof {
// Returns true iff the global variable has custom section either by
// __attribute__((section("name")))
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index d56fd90a48e66..cbb7ae03c245e 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -45,13 +45,7 @@ namespace llvm {
extern cl::opt<bool> PGOWarnMissing;
extern cl::opt<bool> NoPGOWarnMismatch;
extern cl::opt<bool> NoPGOWarnMismatchComdatWeak;
-// FIXME: This option is added for incremental rollout purposes.
-// After the option, string literal partitioning should be implied by
-// AnnotateStaticDataSectionPrefix below and this option should be cleaned up.
-cl::opt<bool> AnnotateStringLiteralSectionPrefix(
- "memprof-annotate-string-literal-section-prefix", cl::init(false),
- cl::Hidden,
- cl::desc("If true, annotate the string literal data section prefix"));
+extern cl::opt<bool> AnnotateStringLiteralSectionPrefix;
} // namespace llvm
// By default disable matching of allocation profiles onto operator new that
@@ -99,7 +93,6 @@ static cl::opt<bool> AnnotateStaticDataSectionPrefix(
"memprof-annotate-static-data-prefix", cl::init(false), cl::Hidden,
cl::desc("If true, annotate the static data section prefix"));
-
// Matching statistics
STATISTIC(NumOfMemProfMissing, "Number of functions without memory profile.");
STATISTIC(NumOfMemProfMismatch,
>From ee28e8fe09d2e2e440ad553c50948a5cc7cddfe7 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 28 Jan 2026 10:56:33 -0800
Subject: [PATCH 3/3] Add test coverage
---
.../X86/global-variable-partition-with-dap.ll | 69 +++++++++++++++----
1 file changed, 56 insertions(+), 13 deletions(-)
diff --git a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
index b2b0a6dab843f..05b3a639a30e5 100644
--- a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
+++ b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
@@ -10,7 +10,16 @@ target triple = "x86_64-unknown-linux-gnu"
; RUN: -partition-static-data-sections=true \
; RUN: -debug-only=static-data-profile-info \
; RUN: -data-sections=true -unique-section-names=false \
-; RUN: input-with-data-access-prof-on.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,IR
+; RUN: input-with-data-access-prof-on.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOGCOMMON,IRCOMMON,IR
+
+;; Repeat command above, but with string literals handled in the codegen pass,
+;; with -memprof-annotate-string-literal-section-prefix=true.
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \
+; RUN: -partition-static-data-sections=true \
+; RUN: -debug-only=static-data-profile-info \
+; RUN: -data-sections=true -unique-section-names=false \
+; RUN: -memprof-annotate-string-literal-section-prefix=true \
+; RUN: input-with-data-access-prof-on.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOGCOMMON,LOGSTR,IRCOMMON,IRSTR
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \
; RUN: -partition-static-data-sections=true \
@@ -18,17 +27,44 @@ target triple = "x86_64-unknown-linux-gnu"
; RUN: -data-sections=true -unique-section-names=false \
; RUN: input-with-data-access-prof-off.ll -o - 2>&1 | FileCheck %s --check-prefixes=OFF
-; LOG: hot_bss has section prefix hot, the max from data access profiles as hot and PGO counters as hot
-; LOG: data_unknown_hotness has section prefix <empty>, the max from data access profiles as <empty> and PGO counters as unlikely
-; LOG: external_relro_array has section prefix unlikely, solely from data access profiles
+; LOGCOMMON: hot_bss has section prefix hot, the max from data access profiles as hot and PGO counters as hot
+; LOGCOMMON: data_unknown_hotness has section prefix <empty>, the max from data access profiles as <empty> and PGO counters as unlikely
+
+; LOGSTR: .str has section prefix <empty>, the max from data access profiles as <empty> and PGO counters as unlikely
+; LOGSTR: .str.1 has section prefix hot, the max from data access profiles as unlikely and PGO counters as hot
+
+; LOGCOMMON: external_relro_array has section prefix unlikely, solely from data access profiles
+
+; LOGSTR: .str.llvm.98765 has section prefix <empty>, solely from data access profiles
+; LOGSTR: .str.2 has section prefix hot, solely from data access profiles
-; IR: .type hot_bss, at object
-; IR-NEXT: .section .bss.hot.,"aw"
-; IR: .type data_unknown_hotness, at object
-; IR-NEXT: .section .data,"aw"
-; IR: .type external_relro_array, at object
-; IR-NEXT: .section .data.rel.ro.unlikely.,"aw"
+; IRCOMMON: .type hot_bss, at object
+; IRCOMMON-NEXT: .section .bss.hot.,"aw"
+; IRCOMMON: .type data_unknown_hotness, at object
+; IRCOMMON-NEXT: .section .data,"aw"
+; IRSTR: .section .rodata,"a", at progbits
+; IR: .section .rodata.unlikely.,"a", at progbits
+; IRCOMMON-NEXT: .L.str:
+; IRCOMMON-NEXT: .ascii "abcde"
+
+; IRCOMMON: .section .rodata.hot.,"a"
+; IRCOMMON-NEXT: .str.1:
+; IRCOMMON-NEXT: .ascii "obj.a"
+
+; IRCOMMON: .type external_relro_array, at object
+; IRCOMMON-NEXT: .section .data.rel.ro.unlikely.,"aw"
+
+; IRCOMMON: .section .rodata,"a", at progbits
+; IRCOMMON-NEXT: .globl .str.llvm.98765
+; IRCOMMON-NEXT: .str.llvm.98765:
+; IRCOMMON-NEXT: .ascii "Joins"
+
+; IRSTR: .section .rodata.hot.,"a", at progbits
+; IR: .section .rodata,"a", at progbits
+; IRSTR-NEXT: .globl .str.2
+; IRSTR-NEXT: .str.2:
+; IRSTR-NEXT: .ascii "*ptr != nullptr"
; OFF: .type hot_bss, at object
; OFF-NEXT: .section .bss.hot.,"aw"
@@ -36,7 +72,7 @@ target triple = "x86_64-unknown-linux-gnu"
; OFF-NEXT: .section .data.unlikely.,"aw"
;; Global variable section prefix metadata is not used when
;; module flag `EnableDataAccessProf` is 0, and @external_relro_array has
-;; external linkage, so analysis based on PGO counters doesn't apply.
+;; external linkage, so analysis based on PGO counters doesn't apply.
; OFF: .type external_relro_array, at object # @external_relro_array
; OFF-NEXT: .section .data.rel.ro,"aw"
@@ -44,18 +80,25 @@ target triple = "x86_64-unknown-linux-gnu"
; Internal vars
@hot_bss = internal global i32 0, !section_prefix !17
@data_unknown_hotness = internal global i32 1
+ at .str = private constant [5 x i8] c"abcde"
+ at .str.1 = internal constant [5 x i8] c"obj.a", !section_prefix !18
; External vars
@external_relro_array = constant [2 x ptr] [ptr @hot_bss, ptr @data_unknown_hotness], !section_prefix !18
+;; <empty> -> <empty>
+ at .str.llvm.98765 = constant [5 x i8] c"Joins"
+
+ at .str.2 = constant [15 x i8] c"*ptr != nullptr", !section_prefix !17
+
define void @cold_func() !prof !15 {
%9 = load i32, ptr @data_unknown_hotness
- %11 = call i32 (...) @func_taking_arbitrary_param(i32 %9)
+ %11 = call i32 (...) @func_taking_arbitrary_param(i32 %9, ptr @.str)
ret void
}
define void @hot_func() !prof !14 {
%9 = load i32, ptr @hot_bss
- %11 = call i32 (...) @func_taking_arbitrary_param(i32 %9)
+ %11 = call i32 (...) @func_taking_arbitrary_param(i32 %9, ptr @.str.1)
ret void
}
More information about the llvm-branch-commits
mailing list