[llvm] [BOLT] Add an option to remove pseudo probe sections (PR #218662)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 04:05:40 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-bolt

Author: Thrrreeee (Thrrreeee)

<details>
<summary>Changes</summary>

Add the --remove-pseudo-probes option to strip the `.pseudo_probe` and `.pseudo_probe_desc` sections from the output binary when pseudo-probe metadata is no longer needed after BOLT optimization.

When enabled, this option skips pseudo-probe rewriting and prevents both sections from being emitted, reducing output binary size and avoiding unnecessary metadata processing. The default behavior remains unchanged, preserving pseudo-probe sections unless the option is set to true.


Comparison | Time | RSS
-- | -- | -- 
Original |  47.54 s |   17.76 GiB
 Stripped binary | 40.03 s  | 16.82 GiB
--remove-pseudo-probes | 40.05 s | 16.82 GiB

(**Stripped binary**: pseudo-probe sections were removed using objcopy before running BOLT.)

BTW, in our internal pipeline, BOLT is the final optimization step, so retaining the pseudo-probe section provides no value. We currently have to remove it with objcopy before deployment to avoid unnecessary binary-size growth. A better solution would be to let BOLT optionally remove this section during optimization, similar to how relocation sections are handled.

---
Full diff: https://github.com/llvm/llvm-project/pull/218662.diff


2 Files Affected:

- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+18-2) 
- (added) bolt/test/X86/remove-pseudo-probes.test (+23) 


``````````diff
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 4486efe926d01..96b1fbfd6f559 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -114,6 +114,11 @@ static cl::opt<bool> MergeTextSections(
              "instead of separate .text/.text.cold sections (relocation mode)"),
     cl::init(false), cl::cat(BoltCategory));
 
+static cl::opt<bool> RemovePseudoProbes(
+    "remove-pseudo-probes",
+    cl::desc("remove pseudo probe sections from the output binary"),
+    cl::init(false), cl::cat(BoltOutputCategory));
+
 static cl::opt<std::string>
     BoltID("bolt-id",
            cl::desc("add any string to tag this execution in the "
@@ -345,6 +350,11 @@ cl::opt<RuntimeLibInitHookTarget> RuntimeLibInitHook(
 
 } // namespace opts
 
+static bool shouldRemovePseudoProbeSection(StringRef SectionName) {
+  return opts::RemovePseudoProbes && (SectionName == ".pseudo_probe" ||
+                                      SectionName == ".pseudo_probe_desc");
+}
+
 // FIXME: implement a better way to mark sections for replacement.
 std::vector<std::string> RewriteInstance::DebugSectionsToOverwrite = {
     ".debug_abbrev", ".debug_aranges",  ".debug_line",   ".debug_line_str",
@@ -3843,8 +3853,8 @@ void RewriteInstance::initializeMetadataManager() {
     MetadataManager.registerRewriter(createLinuxKernelRewriter(*BC));
 
   MetadataManager.registerRewriter(createBuildIDRewriter(*BC));
-
-  MetadataManager.registerRewriter(createPseudoProbeRewriter(*BC));
+  if (!opts::RemovePseudoProbes)
+    MetadataManager.registerRewriter(createPseudoProbeRewriter(*BC));
 
   MetadataManager.registerRewriter(createRSeqRewriter(*BC));
 
@@ -5176,6 +5186,8 @@ void RewriteInstance::rewriteNoteSections(ELFObjectFile<ELFT> *File) {
 
   // Write new note sections.
   for (BinarySection &Section : BC->nonAllocatableSections()) {
+    if (shouldRemovePseudoProbeSection(Section.getOutputName()))
+      continue;
     if (Section.getOutputFileOffset() || !Section.getAllocAddress())
       continue;
 
@@ -5258,6 +5270,10 @@ void RewriteInstance::encodeBATSection() {
 template <typename ELFShdrTy>
 bool RewriteInstance::shouldStrip(const ELFShdrTy &Section,
                                   StringRef SectionName) {
+  // Do not emit pseudo probe metadata when its removal is requested.
+  if (shouldRemovePseudoProbeSection(SectionName))
+    return true;
+
   // Strip non-allocatable relocation sections.
   if (!(Section.sh_flags & ELF::SHF_ALLOC) &&
       (Section.sh_type == ELF::SHT_RELA || Section.sh_type == ELF::SHT_CREL))
diff --git a/bolt/test/X86/remove-pseudo-probes.test b/bolt/test/X86/remove-pseudo-probes.test
new file mode 100644
index 0000000000000..da294693a97d2
--- /dev/null
+++ b/bolt/test/X86/remove-pseudo-probes.test
@@ -0,0 +1,23 @@
+## Check that BOLT omits pseudo probe metadata only when requested.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-readelf -SW \
+# RUN:   %S/../../../llvm/test/tools/llvm-profgen/X86/Inputs/noinline-cs-pseudoprobe.perfbin \
+# RUN:   | FileCheck %s --check-prefix=CHECK
+# RUN: llvm-bolt \
+# RUN:   %S/../../../llvm/test/tools/llvm-profgen/X86/Inputs/noinline-cs-pseudoprobe.perfbin \
+# RUN:   -o %t.default
+# RUN: llvm-readelf -SW %t.default | FileCheck %s --check-prefix=CHECK
+# RUN: llvm-bolt \
+# RUN:   %S/../../../llvm/test/tools/llvm-profgen/X86/Inputs/noinline-cs-pseudoprobe.perfbin \
+# RUN:   -o %t.removed --remove-pseudo-probes
+# RUN: llvm-readelf -SW %t.removed | FileCheck %s --check-prefix=CHECK-PROBES
+
+# CHECK-DAG: .pseudo_probe PROGBITS
+# CHECK-DAG: .pseudo_probe_desc PROGBITS
+
+# CHECK-PROBES: Section Headers:
+# CHECK-PROBES-NOT: .pseudo_probe
+# CHECK-PROBES-NOT: .pseudo_probe_desc
+# CHECK-PROBES: Key to Flags:

``````````

</details>


https://github.com/llvm/llvm-project/pull/218662


More information about the llvm-commits mailing list