[llvm] [BOLT] Match instrument-funcs-file entries against restored names (PR #208313)

YongKang Zhu via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 15:49:57 PDT 2026


https://github.com/yozhu updated https://github.com/llvm/llvm-project/pull/208313

>From 1a79a73fbf2afa1c26d2464fc5833f53ab366b76 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Tue, 7 Jul 2026 11:54:34 -0700
Subject: [PATCH 1/3] [BOLT] Match instrument-funcs-file entries against
 restored names

Local symbols are uniquified with a "/<id>" suffix, but
instrument-funcs-file usually contains original mangled names. To
avoid skipping local functions for instrumentation, we now also
match restored names which have suffix (if any) stripped.
---
 bolt/lib/Passes/Instrumentation.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index ae9faf4e9cc2d..2e756f0b6a014 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h"
 #include "bolt/Utils/CommandLineOpts.h"
+#include "bolt/Utils/NameResolver.h"
 #include "bolt/Utils/Utils.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/CommandLine.h"
@@ -674,7 +675,12 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
     if (HasInstrumentFuncsFilter) {
       bool Found = false;
       for (const StringRef Name : BF.getNames()) {
-        if (InstrumentFuncsSet.contains(Name)) {
+        // instrument-funcs-file could specify original mangled function names
+        // and BOLT will append a "/<id>" (or "/<file>/<id2>") suffix to a local
+        // function name. Match against restored (suffix-stripped) name too, so
+        // local functions specified in the file won't be silently skipped.
+        if (InstrumentFuncsSet.contains(Name) ||
+            InstrumentFuncsSet.contains(NameResolver::restore(Name))) {
           Found = true;
           break;
         }

>From ef92b32381336e695c39207e919fd115d023c397 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Tue, 14 Jul 2026 15:38:46 -0700
Subject: [PATCH 2/3] address review feedback

---
 bolt/docs/CommandLineArgumentReference.md |  7 ++++++
 bolt/lib/Passes/Instrumentation.cpp       | 18 +++++++--------
 bolt/test/X86/instrument-funcs-file.s     | 28 +++++++++++++----------
 3 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md
index bf706ba3a1cdc..17d5a94c432d0 100644
--- a/bolt/docs/CommandLineArgumentReference.md
+++ b/bolt/docs/CommandLineArgumentReference.md
@@ -244,6 +244,13 @@
 
   Run retpoline insertion pass
 
+- `--instrument-funcs-file-no-regex`
+
+  File with list of functions to instrument (non-regex). If local function is
+  specified with original mangled name, i.e., no suffix of `/n` or `/file/n`
+  is added, BOLT will instrument all the local functions whose original mangled
+  names match the specified name.
+
 - `--keep-aranges`
 
   Keep or generate .debug_aranges section if .gdb_index is written
diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index 2e756f0b6a014..868ebe0817f79 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -79,11 +79,9 @@ cl::opt<bool> InstrumentationWaitForks(
              "(use with instrumentation-sleep-time option)"),
     cl::init(false), cl::Optional, cl::cat(BoltInstrCategory));
 
-cl::opt<std::string> InstrumentFuncsFile(
-    "instrument-funcs-file",
-    cl::desc("file with list of function names (one per line) to instrument; "
-             "only functions whose name exactly matches a line in this file "
-             "will be instrumented"),
+cl::opt<std::string> InstrumentFuncsFileNR(
+    "instrument-funcs-file-no-regex",
+    cl::desc("file with list of functions to instrument (non-regex)"),
     cl::Optional, cl::cat(BoltInstrCategory));
 
 cl::opt<bool>
@@ -653,14 +651,14 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
 
   createAuxiliaryFunctions(BC);
 
-  const bool HasInstrumentFuncsFilter = !opts::InstrumentFuncsFile.empty();
+  const bool HasInstrumentFuncsFilter = !opts::InstrumentFuncsFileNR.empty();
   StringSet<> InstrumentFuncsSet;
   if (HasInstrumentFuncsFilter) {
-    std::ifstream FuncsFile(opts::InstrumentFuncsFile, std::ios::in);
+    std::ifstream FuncsFile(opts::InstrumentFuncsFileNR, std::ios::in);
     if (!FuncsFile)
-      return createFatalBOLTError(Twine("instrument-funcs-file \"") +
-                                  Twine(opts::InstrumentFuncsFile) +
-                                  Twine("\" can't be opened."));
+      return createFatalBOLTError(
+          Twine("instrument-funcs-file-no-regex \"") +
+          Twine(opts::InstrumentFuncsFileNR) + Twine("\" can't be opened."));
     std::string FuncName;
     while (std::getline(FuncsFile, FuncName))
       if (!FuncName.empty())
diff --git a/bolt/test/X86/instrument-funcs-file.s b/bolt/test/X86/instrument-funcs-file.s
index 04e128a865eaf..5a406c99b684c 100644
--- a/bolt/test/X86/instrument-funcs-file.s
+++ b/bolt/test/X86/instrument-funcs-file.s
@@ -1,9 +1,11 @@
-# Test --instrument-funcs-file, alone and combined with --instrument-hot-only.
+# Test --instrument-funcs-file-no-regex, alone and combined with
+# --instrument-hot-only.
 #
 # The binary defines three functions (foo, bar, baz). We attach a profile that
-# only marks foo as hot. With --instrument-funcs-file listing foo and bar, only
-# those two are instrumented. Adding --instrument-hot-only further restricts
-# instrumentation to foo (the only function that is both listed and hot).
+# only marks foo as hot. With --instrument-funcs-file-no-regex listing foo and
+# bar, only those two are instrumented. Adding --instrument-hot-only further
+# restricts instrumentation to foo (the only function that is both listed and
+# hot).
 
 # REQUIRES: system-linux,bolt-runtime,target=x86_64-{{.*}}
 
@@ -14,29 +16,31 @@
 # RUN: echo "foo" > %t.funcs
 # RUN: echo "bar" >> %t.funcs
 
-# Test A: only --instrument-funcs-file. Both foo and bar get instrumented.
-# RUN: llvm-bolt --instrument --instrument-funcs-file=%t.funcs \
+# Test A: only --instrument-funcs-file-no-regex. Both foo and bar get
+# instrumented.
+# RUN: llvm-bolt --instrument --instrument-funcs-file-no-regex=%t.funcs \
 # RUN:     -o %t.a.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-A
 
-# Test B: --instrument-funcs-file combined with --instrument-hot-only. Profile
-# marks only foo as hot, so bar is filtered out by --instrument-hot-only.
-# RUN: llvm-bolt --instrument --instrument-funcs-file=%t.funcs \
+# Test B: --instrument-funcs-file-no-regex combined with --instrument-hot-only.
+# Profile marks only foo as hot, so bar is filtered out by
+# --instrument-hot-only.
+# RUN: llvm-bolt --instrument --instrument-funcs-file-no-regex=%t.funcs \
 # RUN:     --instrument-hot-only --data %t.fdata \
 # RUN:     -o %t.b.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-B
 
 # Test C: empty file means "no functions match", so nothing is instrumented.
 # RUN: rm -f %t.empty && touch %t.empty
-# RUN: llvm-bolt --instrument --instrument-funcs-file=%t.empty \
+# RUN: llvm-bolt --instrument --instrument-funcs-file-no-regex=%t.empty \
 # RUN:     -o %t.c.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-C
 
 # Test D: missing file produces a fatal error.
-# RUN: not llvm-bolt --instrument --instrument-funcs-file=%t.missing \
+# RUN: not llvm-bolt --instrument --instrument-funcs-file-no-regex=%t.missing \
 # RUN:     -o %t.d.out %t.exe 2>&1 | FileCheck %s --check-prefix=CHECK-D
 
 # CHECK-A: BOLT-INSTRUMENTER: Number of function descriptors: 2
 # CHECK-B: BOLT-INSTRUMENTER: Number of function descriptors: 1
 # CHECK-C: BOLT-INSTRUMENTER: Number of function descriptors: 0
-# CHECK-D: instrument-funcs-file {{.*}}.missing{{.*}} can't be opened
+# CHECK-D: instrument-funcs-file-no-regex {{.*}}.missing{{.*}} can't be opened
 
     .text
     .globl _start

>From 68475452b6dcb0514b801fd564c1280f63335cfc Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Tue, 14 Jul 2026 15:49:18 -0700
Subject: [PATCH 3/3] Fix format error

---
 bolt/lib/Passes/Instrumentation.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index 868ebe0817f79..059f0ec97dec5 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -656,9 +656,9 @@ Error Instrumentation::runOnFunctions(BinaryContext &BC) {
   if (HasInstrumentFuncsFilter) {
     std::ifstream FuncsFile(opts::InstrumentFuncsFileNR, std::ios::in);
     if (!FuncsFile)
-      return createFatalBOLTError(
-          Twine("instrument-funcs-file-no-regex \"") +
-          Twine(opts::InstrumentFuncsFileNR) + Twine("\" can't be opened."));
+      return createFatalBOLTError(Twine("instrument-funcs-file-no-regex \"") +
+                                  Twine(opts::InstrumentFuncsFileNR) +
+                                  Twine("\" can't be opened."));
     std::string FuncName;
     while (std::getline(FuncsFile, FuncName))
       if (!FuncName.empty())



More information about the llvm-commits mailing list