[llvm] [BOLT] Introduce BinaryFunction::canClone() (PR #138771)

Maksim Panchenko via llvm-commits llvm-commits at lists.llvm.org
Tue May 6 15:06:24 PDT 2025


https://github.com/maksfb created https://github.com/llvm/llvm-project/pull/138771

In some scenarios, we want to allow execution of the original function code together with its rewritten (optimized) copy. We used to limit such capability when the function uses C++ exceptions, since we cannot duplicate exception tables. There's more metadata that cannot be duplicated, and this PR adds more checks via the introduction of canClone() function that checks all such limitations.

>From 8950f026f4de4165f206aed605d3c9c2059183a0 Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Tue, 6 May 2025 14:55:32 -0700
Subject: [PATCH] [BOLT] Introduce BinaryFunction::canClone()

In some scenarios, we want to allow execution of the original function
code together with its rewritten (optimized) copy. We used to limit such
capability when the function uses C++ exceptions, since we cannot
duplicate exception tables. There's more metadata that cannot be
duplicated, and this PR adds more checks via the introduction of
canClone() function that checks all such limitations.
---
 bolt/include/bolt/Core/BinaryFunction.h |  5 +++++
 bolt/lib/Core/BinaryFunction.cpp        | 10 ++++++++++
 bolt/lib/Passes/PatchEntries.cpp        |  2 +-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index a52998564ee1b..edeaa51481e6f 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -1375,6 +1375,11 @@ class BinaryFunction {
   /// Return true if the function should not have associated symbol table entry.
   bool isAnonymous() const { return IsAnonymous; }
 
+  /// Return true if we can allow the execution of the original body of the
+  /// function together with its rewritten copy. This means, e.g., that metadata
+  /// associated with the function can be duplicated/cloned.
+  bool canClone() const;
+
   /// If this function was folded, return the function it was folded into.
   BinaryFunction *getFoldedIntoFunction() const { return FoldedIntoFunction; }
 
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 9773e21aa7522..24972bac58409 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -3744,6 +3744,16 @@ void BinaryFunction::postProcessBranches() {
   assert(validateCFG() && "invalid CFG");
 }
 
+bool BinaryFunction::canClone() const {
+  // For instrumentation, we need to restrict the execution to the rewritten
+  // version of the function.
+  if (opts::Instrument)
+    return false;
+
+  // Check for the presence of metadata that cannot be duplicated.
+  return !hasEHRanges() && !hasSDTMarker() && !hasPseudoProbe() && !hasORC();
+}
+
 MCSymbol *BinaryFunction::addEntryPointAtOffset(uint64_t Offset) {
   assert(Offset && "cannot add primary entry point");
   assert(CurrentState == State::Empty || CurrentState == State::Disassembled);
diff --git a/bolt/lib/Passes/PatchEntries.cpp b/bolt/lib/Passes/PatchEntries.cpp
index 4877e7dd8fdf3..8d07d163ef412 100644
--- a/bolt/lib/Passes/PatchEntries.cpp
+++ b/bolt/lib/Passes/PatchEntries.cpp
@@ -65,7 +65,7 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
       continue;
 
     // Check if we can skip patching the function.
-    if (!opts::ForcePatch && !Function.hasEHRanges() &&
+    if (!opts::ForcePatch && Function.canClone() &&
         Function.getSize() < PatchThreshold)
       continue;
 



More information about the llvm-commits mailing list