[llvm] [Sample Profile] make page size configurable for ProfiledBinary (PR #206867)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 30 18:51:58 PDT 2026
https://github.com/wjx951753 updated https://github.com/llvm/llvm-project/pull/206867
>From 25be8c56f6e01bfa61abf9c5896f596c375ddc08 Mon Sep 17 00:00:00 2001
From: wangjx6 <wangjiaxin35 at huawei.com>
Date: Wed, 1 Jul 2026 09:41:00 +0800
Subject: [PATCH] [Sample Profile] make page size configurable for
ProfiledBinary
---
.../Inputs/multi-load-segs-64k.perfscript | 11 +++++++
llvm/test/tools/llvm-profgen/page-size.test | 33 +++++++++++++++++++
llvm/tools/llvm-profgen/ProfiledBinary.cpp | 21 +++++++-----
3 files changed, 57 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/tools/llvm-profgen/Inputs/multi-load-segs-64k.perfscript
create mode 100644 llvm/test/tools/llvm-profgen/page-size.test
diff --git a/llvm/test/tools/llvm-profgen/Inputs/multi-load-segs-64k.perfscript b/llvm/test/tools/llvm-profgen/Inputs/multi-load-segs-64k.perfscript
new file mode 100644
index 0000000000000..8db032298220e
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/Inputs/multi-load-segs-64k.perfscript
@@ -0,0 +1,11 @@
+PERF_RECORD_MMAP2 3476378/3476378: [0x200000(0x10000) @ 0 00:23 51215901 72455]: r-xp multi-load-segs.perfbin
+PERF_RECORD_MMAP2 3476378/3476378: [0x201000(0x1000) @ 0x1000 00:23 51215901 72455]: r-xp multi-load-segs.perfbin
+PERF_RECORD_MMAP2 3476378/3476378: [0x400000(0x1000) @ 0x200000 00:23 51215901 72455]: r-xp multi-load-segs.perfbin
+
+ 201a1e
+ 7f9f03a46d95
+ 20178a
+ 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/5 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/5 0x201a56/0x201a10/P/-/-/5 0x201a56/0x201a10/P/-/-/5 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/3 0x201a56/0x201a10/P/-/-/7 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/3 0x201a56/0x201a10/P/-/-/6 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/3 0x201a56/0x201a10/P/-/-/6 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/4 0x201a56/0x201a10/P/-/-/3 0x201a56/0x201a10/P/-/-/6
+
+
+
diff --git a/llvm/test/tools/llvm-profgen/page-size.test b/llvm/test/tools/llvm-profgen/page-size.test
new file mode 100644
index 0000000000000..65ef70c6d5e06
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/page-size.test
@@ -0,0 +1,33 @@
+; RUN: not llvm-profgen --perfscript=%S/Inputs/multi-load-segs.perfscript --binary=%S/Inputs/multi-load-segs.perfbin --output=%t --format=text --csspgo-preinliner=0 --gen-cs-nested-profile=0 --page-size=0 2>&1 | FileCheck %s --check-prefix=INVALID
+; RUN: not llvm-profgen --perfscript=%S/Inputs/multi-load-segs.perfscript --binary=%S/Inputs/multi-load-segs.perfbin --output=%t --format=text --csspgo-preinliner=0 --gen-cs-nested-profile=0 --page-size=3 2>&1 | FileCheck %s --check-prefix=INVALID
+; RUN: llvm-profgen --perfscript=%S/Inputs/multi-load-segs.perfscript --binary=%S/Inputs/multi-load-segs.perfbin --output=%t --format=text --csspgo-preinliner=0 --gen-cs-nested-profile=0 --page-size=4096
+; RUN: FileCheck %s --input-file %t
+; RUN: llvm-profgen --perfscript=%S/Inputs/multi-load-segs-64k.perfscript --binary=%S/Inputs/multi-load-segs.perfbin --output=%t --format=text --csspgo-preinliner=0 --gen-cs-nested-profile=0 --page-size=65536
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-64K
+
+;; %S/Inputs/multi-load-segs.perfbin is an ELF image with two executable load segments.
+; running llvm-readelf -l %S/Inputs/multi-load-segs.perfbin gives:
+;; LOAD 0x000000 0x0000000000200000 0x0000000000200000 0x00075c 0x00075c R 0x1000
+;; LOAD 0x000760 0x0000000000201760 0x0000000000201760 0x0004c0 0x0004c0 R E 0x1000
+;; LOAD 0x000c20 0x0000000000202c20 0x0000000000202c20 0x0001f0 0x0001f0 RW 0x1000
+;; LOAD 0x000e10 0x0000000000203e10 0x0000000000203e10 0x000040 0x000058 RW 0x1000
+;; LOAD 0x200000 0x0000000000400000 0x0000000000400000 0x0005e8 0x0005e8 R E 0x200000
+
+; INVALID: Number in -page-size=<num> must be positive power of two
+
+; CHECK: [main:2 @ _Z10sort_arrayv:6 @ _Z11bubble_sortPii]:465:0
+; CHECK-NEXT: 4: 31
+; CHECK-NEXT: 5: 31
+; CHECK-NEXT: 7: 31
+; CHECK-NEXT: 8: 31
+; CHECK-NEXT: 65516: 31
+; CHECK-NEXT: !Attributes: 1
+
+; CHECK-64K: [main:2 @ _Z10sort_arrayv:6 @ _Z11bubble_sortPii]:465:0
+; CHECK-64K-NEXT: 4: 31
+; CHECK-64K-NEXT: 5: 31
+; CHECK-64K-NEXT: 7: 31
+; CHECK-64K-NEXT: 8: 31
+; CHECK-64K-NEXT: 65516: 31
+; CHECK-64K-NEXT: !Attributes: 1
+
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
index 08fd6917c9f3a..13c92933fab30 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
@@ -81,6 +81,12 @@ static cl::opt<bool>
cl::desc("Generate the profile for Linux kernel binary."),
cl::cat(ProfGenCategory));
+static cl::opt<unsigned> PageSize(
+ "page-size", cl::init(0x1000),
+ cl::desc("Page size for aligning segment addresses. Use 4096 for 4KB "
+ "pages (default) or 65536 for 64KB pages (e.g. AArch64)."),
+ cl::cat(ProfGenCategory));
+
namespace sampleprof {
static const Target *getTarget(const ObjectFile *Obj) {
@@ -362,22 +368,21 @@ template <class ELFT>
void ProfiledBinary::setPreferredTextSegmentAddresses(const ELFFile<ELFT> &Obj,
StringRef FileName) {
const auto &PhdrRange = unwrapOrError(Obj.program_headers(), FileName);
- // FIXME: This should be the page size of the system running profiling.
- // However such info isn't available at post-processing time, assuming
- // 4K page now. Note that we don't use EXEC_PAGESIZE from <linux/param.h>
- // because we may build the tools on non-linux.
- uint64_t PageSize = 0x1000;
+ uint64_t LocalPageSize = PageSize;
+ if (!LocalPageSize || (LocalPageSize & (LocalPageSize - 1)))
+ exitWithError("Number in -page-size=<num> must be positive power of two", FileName);
+
for (const typename ELFT::Phdr &Phdr : PhdrRange) {
if (Phdr.p_type == ELF::PT_INTERP)
HasInterp = true;
if (Phdr.p_type == ELF::PT_LOAD) {
if (!FirstLoadableAddress)
- FirstLoadableAddress = Phdr.p_vaddr & ~(PageSize - 1U);
+ FirstLoadableAddress = Phdr.p_vaddr & ~(LocalPageSize - 1U);
if (Phdr.p_flags & ELF::PF_X) {
// Segments will always be loaded at a page boundary.
PreferredTextSegmentAddresses.push_back(Phdr.p_vaddr &
- ~(PageSize - 1U));
- TextSegmentOffsets.push_back(Phdr.p_offset & ~(PageSize - 1U));
+ ~(LocalPageSize - 1U));
+ TextSegmentOffsets.push_back(Phdr.p_offset & ~(LocalPageSize - 1U));
} else {
PhdrInfo Info;
Info.FileOffset = Phdr.p_offset;
More information about the llvm-commits
mailing list