[llvm] Avoid merging instrumentation profiler globals (PR #172835)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 22 08:17:01 PST 2025
https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/172835
>From 4ade16626da42a576defcd71cfd3bbfb44af7e1a Mon Sep 17 00:00:00 2001
From: Evgeny Leviant <eleviant at accesssoftek.com>
Date: Thu, 18 Dec 2025 12:04:43 +0100
Subject: [PATCH] Avoid merging instrumentation profiler globals
The global-merge pass attempts to merge instumentation profiler counters,
e.g __profc_foo and __profc_bar, which results in their corresponding
__llvm_prf_cnts sections being merged into a single one and moved out
from a comdat group, which originally gropus __llvm_prf_cnts and
__llvm_prf_data sections. This, in turn, results in __llvm_prf_data
becoming an orphaned section, which is garbage-collected when
--gc-sections linker flag is used.
---
llvm/lib/CodeGen/GlobalMerge.cpp | 16 +++++++++-------
llvm/test/CodeGen/AArch64/global-merge-comdat.ll | 7 +++++++
.../AArch64/global-merge-profile-sections.ll | 11 +++++++++++
3 files changed, 27 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/global-merge-comdat.ll
create mode 100644 llvm/test/CodeGen/AArch64/global-merge-profile-sections.ll
diff --git a/llvm/lib/CodeGen/GlobalMerge.cpp b/llvm/lib/CodeGen/GlobalMerge.cpp
index b8b0d4d612742..653c4e8ee4389 100644
--- a/llvm/lib/CodeGen/GlobalMerge.cpp
+++ b/llvm/lib/CodeGen/GlobalMerge.cpp
@@ -562,6 +562,7 @@ bool GlobalMergeImpl::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals,
MergedGV->setAlignment(MaxAlign);
MergedGV->setSection(Globals[i]->getSection());
+ MergedGV->setComdat(Globals[i]->getComdat());
LLVM_DEBUG(dbgs() << "MergedGV: " << *MergedGV << "\n");
@@ -677,7 +678,8 @@ bool GlobalMergeImpl::run(Module &M) {
IsMachO = M.getTargetTriple().isOSBinFormatMachO();
auto &DL = M.getDataLayout();
- MapVector<std::pair<unsigned, StringRef>, SmallVector<GlobalVariable *, 0>>
+ MapVector<std::tuple<unsigned, StringRef, Comdat *>,
+ SmallVector<GlobalVariable *, 0>>
Globals, ConstGlobals, BSSGlobals;
bool Changed = false;
setMustKeepGlobalVariables(M);
@@ -735,11 +737,11 @@ bool GlobalMergeImpl::run(Module &M) {
if (CanMerge) {
if (TM &&
TargetLoweringObjectFile::getKindForGlobal(&GV, *TM).isBSS())
- BSSGlobals[{AddressSpace, Section}].push_back(&GV);
+ BSSGlobals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
else if (GV.isConstant())
- ConstGlobals[{AddressSpace, Section}].push_back(&GV);
+ ConstGlobals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
else
- Globals[{AddressSpace, Section}].push_back(&GV);
+ Globals[{AddressSpace, Section, GV.getComdat()}].push_back(&GV);
}
LLVM_DEBUG(dbgs() << "GV " << (CanMerge ? "" : "not ") << "to merge: " << GV
<< "\n");
@@ -747,16 +749,16 @@ bool GlobalMergeImpl::run(Module &M) {
for (auto &P : Globals)
if (P.second.size() > 1)
- Changed |= doMerge(P.second, M, false, P.first.first);
+ Changed |= doMerge(P.second, M, false, std::get<0>(P.first));
for (auto &P : BSSGlobals)
if (P.second.size() > 1)
- Changed |= doMerge(P.second, M, false, P.first.first);
+ Changed |= doMerge(P.second, M, false, std::get<0>(P.first));
if (Opt.MergeConstantGlobals)
for (auto &P : ConstGlobals)
if (P.second.size() > 1)
- Changed |= doMerge(P.second, M, true, P.first.first);
+ Changed |= doMerge(P.second, M, true, std::get<0>(P.first));
return Changed;
}
diff --git a/llvm/test/CodeGen/AArch64/global-merge-comdat.ll b/llvm/test/CodeGen/AArch64/global-merge-comdat.ll
new file mode 100644
index 0000000000000..fed568b566e16
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/global-merge-comdat.ll
@@ -0,0 +1,7 @@
+; RUN: opt -global-merge -global-merge-max-offset=16 -global-merge-group-by-use=false %s -S -o - | FileCheck %s
+; CHECK: @_MergedGlobals = private global <{ i64, i64 }> zeroinitializer, section "__foo", comdat($__foo), align 8
+
+$__foo = comdat nodeduplicate
+
+ at __bar = private global i64 0, section "__foo", comdat($__foo), align 8
+ at __baz = private global i64 0, section "__foo", comdat($__foo), align 8
diff --git a/llvm/test/CodeGen/AArch64/global-merge-profile-sections.ll b/llvm/test/CodeGen/AArch64/global-merge-profile-sections.ll
new file mode 100644
index 0000000000000..7108d82ddaa2e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/global-merge-profile-sections.ll
@@ -0,0 +1,11 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-global-merge -global-merge-group-by-use=false < %s | FileCheck %s
+; CHECK-NOT: _MergedGlobals
+
+$__profc_begin = comdat nodeduplicate
+$__profc_end = comdat nodeduplicate
+
+ at __profc_begin = private global [2 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
+ at __profd_begin = private global { i64, i64, i64, i64, ptr, ptr, i32, [3 x i16], i32 } { i64 -1301828029439649651, i64 172590168, i64 sub (i64 ptrtoint (ptr @__profc_begin to i64), i64 ptrtoint (ptr @__profd_begin to i64)), i64 0, ptr null, ptr null, i32 2, [3 x i16] zeroinitializer, i32 0 }, section "__llvm_prf_data", comdat($__profc_begin), align 8
+ at __profc_end = private global [2 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8
+ at __profd_end = private global { i64, i64, i64, i64, ptr, ptr, i32, [3 x i16], i32 } { i64 3274037854792712831, i64 172590168, i64 sub (i64 ptrtoint (ptr @__profc_end to i64), i64 ptrtoint (ptr @__profd_end to i64)), i64 0, ptr null, ptr null, i32 2, [3 x i16] zeroinitializer, i32 0 }, section "__llvm_prf_data", comdat($__profc_end), align 8
+
More information about the llvm-commits
mailing list