[llvm] [ORC] Share one Mangler across a lookupAndApply group (PR #224285)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 05:52:02 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/224285

LookupPrepareFn now receives a Mangler that lookupAndApply builds once from the search order's target triple, rather than each recordAddr / recordProxy constructing its own per entry.

>From e8c375ef58f0b1408da5d47ce36d55a1bc01ae33 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Thu, 17 Sep 2026 22:42:15 +1000
Subject: [PATCH] [ORC] Share one Mangler across a lookupAndApply group

LookupPrepareFn now receives a Mangler that lookupAndApply builds once
from the search order's target triple, rather than each recordAddr /
recordProxy constructing its own per entry.
---
 .../llvm/ExecutionEngine/Orc/LookupAndApply.h | 20 +++++++++++--------
 .../llvm/ExecutionEngine/Orc/RecordProxy.h    | 12 +++++------
 .../ExecutionEngine/Orc/LookupAndApply.cpp    |  6 +++++-
 .../Orc/LookupAndApplyTest.cpp                |  4 ++--
 4 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LookupAndApply.h b/llvm/include/llvm/ExecutionEngine/Orc/LookupAndApply.h
index c3e83168d1cd2..af2c83b958aaa 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LookupAndApply.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LookupAndApply.h
@@ -46,10 +46,14 @@ using LookupApplyFn = unique_function<void(const SymbolMap &M)>;
 /// stand for a whole service's worth of bindings. The applicator it returns
 /// runs only if the lookup succeeds.
 ///
+/// The Mangler is built once by lookupAndApply (from the search order's target)
+/// and shared across all prepare functions, so a name-mangling prepare function
+/// need not construct its own.
+///
 /// The call operator is const so that these can be passed as a braced list (see
 /// lookupAndApply): they hold no mutable state.
 using LookupPrepareFn = unique_function<LookupApplyFn(
-    SymbolLookupSet &LS, ExecutionSession &ES) const>;
+    SymbolLookupSet &LS, ExecutionSession &ES, const Mangler &Mangle) const>;
 
 /// Resolve the symbols contributed by every prepare function with a single
 /// lookup, then let each of their applicators act on the result.
@@ -103,11 +107,10 @@ LLVM_ABI Error lookupAndApply(JITDylib &JD,
 inline LookupPrepareFn
 recordAddr(SymbolNameSpec Name, ExecutorAddr *A,
            SymbolLookupFlags LF = SymbolLookupFlags::RequiredSymbol) {
-  return [Name, A, LF](SymbolLookupSet &LS,
-                       ExecutionSession &ES) -> LookupApplyFn {
-    auto N =
-        Mangler(ES.getTargetTriple())
-            .withMangledNameDo([&](StringRef M) { return ES.intern(M); }, Name);
+  return [Name, A, LF](SymbolLookupSet &LS, ExecutionSession &ES,
+                       const Mangler &Mangle) -> LookupApplyFn {
+    auto N = Mangle.withMangledNameDo([&](StringRef M) { return ES.intern(M); },
+                                      Name);
     LS.add(N, LF);
     return [A, N = std::move(N)](const SymbolMap &M) {
       *A = M.lookup(N).getAddress();
@@ -121,8 +124,9 @@ recordAddr(SymbolNameSpec Name, ExecutorAddr *A,
 inline LookupPrepareFn
 recordAddr(SymbolStringPtr Name, ExecutorAddr *A,
            SymbolLookupFlags LF = SymbolLookupFlags::RequiredSymbol) {
-  return [Name = std::move(Name), A,
-          LF](SymbolLookupSet &LS, ExecutionSession &ES) -> LookupApplyFn {
+  return [Name = std::move(Name), A, LF](SymbolLookupSet &LS,
+                                         ExecutionSession &ES,
+                                         const Mangler &) -> LookupApplyFn {
     LS.add(Name, LF);
     return [A, Name](const SymbolMap &M) { *A = M.lookup(Name).getAddress(); };
   };
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RecordProxy.h b/llvm/include/llvm/ExecutionEngine/Orc/RecordProxy.h
index 5b8a0f0faef63..4f4985d3a078a 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/RecordProxy.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RecordProxy.h
@@ -32,11 +32,10 @@ LookupPrepareFn
 recordProxy(Proxy<FnT> *P, typename Proxy<FnT>::DispatchFn Dispatch,
             SymbolNameSpec Name,
             SymbolLookupFlags LF = SymbolLookupFlags::RequiredSymbol) {
-  return [P, Dispatch, Name, LF](SymbolLookupSet &LS,
-                                 ExecutionSession &ES) -> LookupApplyFn {
-    auto N =
-        Mangler(ES.getTargetTriple())
-            .withMangledNameDo([&](StringRef M) { return ES.intern(M); }, Name);
+  return [P, Dispatch, Name, LF](SymbolLookupSet &LS, ExecutionSession &ES,
+                                 const Mangler &Mangle) -> LookupApplyFn {
+    auto N = Mangle.withMangledNameDo([&](StringRef M) { return ES.intern(M); },
+                                      Name);
     LS.add(N, LF);
     return [P, Dispatch, N = std::move(N)](const SymbolMap &M) {
       auto Sym = M.lookup(N);
@@ -56,7 +55,8 @@ recordProxy(Proxy<FnT> *P, typename Proxy<FnT>::DispatchFn Dispatch,
             SymbolStringPtr Name,
             SymbolLookupFlags LF = SymbolLookupFlags::RequiredSymbol) {
   return [P, Dispatch, Name = std::move(Name),
-          LF](SymbolLookupSet &LS, ExecutionSession &ES) -> LookupApplyFn {
+          LF](SymbolLookupSet &LS, ExecutionSession &ES,
+              const Mangler &) -> LookupApplyFn {
     LS.add(Name, LF);
     return [P, Dispatch, Name](const SymbolMap &M) {
       auto Sym = M.lookup(Name);
diff --git a/llvm/lib/ExecutionEngine/Orc/LookupAndApply.cpp b/llvm/lib/ExecutionEngine/Orc/LookupAndApply.cpp
index 26ecd8c2ad9ec..19dbc7c0953f3 100644
--- a/llvm/lib/ExecutionEngine/Orc/LookupAndApply.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LookupAndApply.cpp
@@ -31,6 +31,10 @@ void lookupAndApply(unique_function<void(Error)> OnApplied, LookupKind K,
 
   auto &ES = SearchOrder.front().first->getExecutionSession();
 
+  // Build one Mangler for the whole group, so name-mangling prepare functions
+  // don't each construct their own.
+  Mangler Mangle(ES.getTargetTriple());
+
   // Collect the symbols to look up. Each prepare function hands back the
   // applicator that will act on the result; the prepare functions themselves
   // are not needed beyond this point.
@@ -38,7 +42,7 @@ void lookupAndApply(unique_function<void(Error)> OnApplied, LookupKind K,
   std::vector<LookupApplyFn> Applies;
   Applies.reserve(PrepareFns.size());
   for (const auto &PF : PrepareFns)
-    Applies.push_back(PF(Symbols, ES));
+    Applies.push_back(PF(Symbols, ES, Mangle));
 
   // PrepareFns are independent, so two of them may legitimately ask for the
   // same symbol. ExecutionSession::lookup requires a duplicate-free set, and
diff --git a/llvm/unittests/ExecutionEngine/Orc/LookupAndApplyTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LookupAndApplyTest.cpp
index d358467990910..22e3fcdcd4ad2 100644
--- a/llvm/unittests/ExecutionEngine/Orc/LookupAndApplyTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LookupAndApplyTest.cpp
@@ -139,8 +139,8 @@ TEST(LookupAndApplyTest, MultiplePrepareFns) {
   ExecutorAddr A, B, C, D;
 
   // A composite prepare fn: contributes both names, records both results.
-  auto RecordBoth = [&C, &D](SymbolLookupSet &LS,
-                             ExecutionSession &ES) -> LookupApplyFn {
+  auto RecordBoth = [&C, &D](SymbolLookupSet &LS, ExecutionSession &ES,
+                             const Mangler &) -> LookupApplyFn {
     auto NA = ES.intern("addr_a");
     auto NB = ES.intern("addr_b");
     LS.add(NA);



More information about the llvm-commits mailing list