[llvm] 2dfc014 - RuntimeLibcalls: Dispatch to library functions from SystemRuntimeLibrary (#217593)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 04:31:11 PDT 2026


Author: Matt Arsenault
Date: 2026-09-08T13:31:07+02:00
New Revision: 2dfc0140a0385d063a7b336549a4055778febb1a

URL: https://github.com/llvm/llvm-project/commit/2dfc0140a0385d063a7b336549a4055778febb1a
DIFF: https://github.com/llvm/llvm-project/commit/2dfc0140a0385d063a7b336549a4055778febb1a.diff

LOG: RuntimeLibcalls: Dispatch to library functions from SystemRuntimeLibrary (#217593)

When a SystemRuntimeLibrary names LibcallLibrary defs,
setTargetRuntimeLibcallSets now dispatches each under an isLibraryAvailable 
guard, so an impl can be homed into a library without dropping it from the target. 
Non-library members keep the inline path. No target names a library yet, so output 
is unchanged.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

Added: 
    llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td

Modified: 
    llvm/include/llvm/IR/RuntimeLibcalls.h
    llvm/test/TableGen/RuntimeLibcallEmitter-library-grouping.td
    llvm/test/TableGen/RuntimeLibcallEmitter-library-name-merge.td
    llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index e7dfec449a842..b864e68611337 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -188,6 +188,11 @@ struct RuntimeLibcallsInfo {
   LLVM_ABI static bool hasVectorMaskArgument(RTLIB::LibcallImpl Impl);
 
 private:
+  // Generated per-library setup helpers, dispatched from
+  // setTargetRuntimeLibcallSets.
+#define GET_RUNTIME_LIBCALLS_INFO_MEMBER_DECLS
+#include "llvm/IR/RuntimeLibcalls.inc"
+
   LLVM_ABI static iota_range<RTLIB::LibcallImpl>
   lookupLibcallImplNameImpl(StringRef Name);
 

diff  --git a/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td b/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td
new file mode 100644
index 0000000000000..87c6acc9493ac
--- /dev/null
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td
@@ -0,0 +1,52 @@
+// RUN: llvm-tblgen -gen-runtime-libcalls -I %p/../../include %s | FileCheck %s
+
+// Check that a SystemRuntimeLibrary naming LibcallLibrary defs dispatches to
+// their setAvailableLibFuncs_<name> functions under an isLibraryAvailable guard,
+// inside the target's triple block, while bare (non-library) members are still
+// emitted inline via the flat path.
+
+include "llvm/IR/RuntimeLibcallsImpl.td"
+
+def MEMCPY : RuntimeLibcall;
+def SQRT_F64 : RuntimeLibcall;
+def EXTRA : RuntimeLibcall;
+
+def memcpy : RuntimeLibcallImpl<MEMCPY>;
+def sqrt : RuntimeLibcallImpl<SQRT_F64, "sqrt">;
+def extra : RuntimeLibcallImpl<EXTRA>;
+
+def IsX86 : LibcallPredicate<[{TT.isX86()}]>;
+def isX86 : RuntimeLibcallAvailability<(all_of IsX86)>;
+
+def Libc : LibcallLibrary<"libc", (add memcpy)>;
+def Libm : LibcallLibrary<"libm", (add sqrt)>;
+
+// Pulls two named libraries plus one bare inline member.
+def X86System : SystemRuntimeLibrary<isX86, (add Libc, Libm, extra)>;
+
+// The named libraries still get their standalone implementation functions.
+
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libc(
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libm(
+
+// The driver dispatches to each named library under its presence guard, then
+// emits the bare member (extra) inline.
+
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
+// CHECK:   if (TT.isX86()) {
+// CHECK-NEXT:     static constexpr LibcallImplBitset SystemAvailableImpls({
+// CHECK: AvailableLibcallImpls = SystemAvailableImpls;
+// CHECK-EMPTY:
+// CHECK-NEXT:     if (isLibraryAvailable("libc"))
+// CHECK-NEXT:       setAvailableLibFuncs_libc(TT, ExceptionModel, FloatABI, EABIVersion, ABIName, LongDoubleFormat);
+// CHECK-NEXT:     if (isLibraryAvailable("libm"))
+// CHECK-NEXT:       setAvailableLibFuncs_libm(TT, ExceptionModel, FloatABI, EABIVersion, ABIName, LongDoubleFormat);
+// CHECK-EMPTY:
+// CHECK-NEXT:     static const RTLIB::LibcallImpl LibraryCalls[] = {
+// CHECK-NEXT:         RTLIB::impl_extra, // extra
+// CHECK-NEXT:     };
+// CHECK: for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
+// CHECK-NEXT:       setAvailable(Impl);
+// CHECK-NEXT:     }
+// CHECK:     return;
+// CHECK-NEXT:   }

diff  --git a/llvm/test/TableGen/RuntimeLibcallEmitter-library-grouping.td b/llvm/test/TableGen/RuntimeLibcallEmitter-library-grouping.td
index 6937b935e7494..59d864f195906 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-library-grouping.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-library-grouping.td
@@ -31,14 +31,14 @@ def Libm : LibcallLibrary<"libm", (add sqrt,
 
 // One standalone implementation function is emitted per LibcallLibrary.
 
-// CHECK: static void setAvailableLibFuncs_libc(llvm::RTLIB::RuntimeLibcallsInfo &Info, const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libc(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
 // CHECK-NEXT:   {
 // CHECK-NEXT:     static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:         RTLIB::impl_memcpy, // memcpy
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
+// CHECK-NEXT:       setAvailable(Impl);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:     if (TT.isOSDarwin()) {
@@ -47,7 +47,7 @@ def Libm : LibcallLibrary<"libm", (add sqrt,
 // CHECK-NEXT:       };
 // CHECK-EMPTY:
 // CHECK-NEXT:       for (const RTLIB::LibcallImpl Impl : LibraryCalls_isDarwin) {
-// CHECK-NEXT:         Info.setAvailable(Impl);
+// CHECK-NEXT:         setAvailable(Impl);
 // CHECK-NEXT:       }
 // CHECK-EMPTY:
 // CHECK-NEXT:     }
@@ -55,14 +55,14 @@ def Libm : LibcallLibrary<"libm", (add sqrt,
 // CHECK-NEXT:   }
 // CHECK-NEXT: }
 
-// CHECK: static void setAvailableLibFuncs_libm(llvm::RTLIB::RuntimeLibcallsInfo &Info, const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libm(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
 // CHECK-NEXT:   {
 // CHECK-NEXT:     static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:         RTLIB::impl_sqrt, // sqrt
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
+// CHECK-NEXT:       setAvailable(Impl);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:     if (TT.isX86()) {
@@ -71,7 +71,7 @@ def Libm : LibcallLibrary<"libm", (add sqrt,
 // CHECK-NEXT:       };
 // CHECK-EMPTY:
 // CHECK-NEXT:       for (const RTLIB::LibcallImpl Impl : LibraryCalls_isX86) {
-// CHECK-NEXT:         Info.setAvailable(Impl);
+// CHECK-NEXT:         setAvailable(Impl);
 // CHECK-NEXT:       }
 // CHECK-EMPTY:
 // CHECK-NEXT:     }

diff  --git a/llvm/test/TableGen/RuntimeLibcallEmitter-library-name-merge.td b/llvm/test/TableGen/RuntimeLibcallEmitter-library-name-merge.td
index 06b900025d230..f44ae67e62d38 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-library-name-merge.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-library-name-merge.td
@@ -42,14 +42,14 @@ def DarwinLibm : LibcallLibrary<"libm", (add sqrt)> { let Pred = isDarwin; }
 // The shared core (memcpy, memset) is emitted once and unguarded; each variant's
 // guarded block carries only its own extras (bzero for Darwin, stpcpy for GNU).
 
-// CHECK: static void setAvailableLibFuncs_libc(llvm::RTLIB::RuntimeLibcallsInfo &Info, const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libc(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
 // CHECK-NEXT:   static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:       RTLIB::impl_memcpy, // memcpy
 // CHECK-NEXT:       RTLIB::impl_memset, // memset
 // CHECK-NEXT:   };
 // CHECK-EMPTY:
 // CHECK-NEXT:   for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:     Info.setAvailable(Impl);
+// CHECK-NEXT:     setAvailable(Impl);
 // CHECK-NEXT:   }
 // CHECK-EMPTY:
 // CHECK-NEXT:   if (TT.isOSDarwin()) {
@@ -58,7 +58,7 @@ def DarwinLibm : LibcallLibrary<"libm", (add sqrt)> { let Pred = isDarwin; }
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
+// CHECK-NEXT:       setAvailable(Impl);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:   }
@@ -68,7 +68,7 @@ def DarwinLibm : LibcallLibrary<"libm", (add sqrt)> { let Pred = isDarwin; }
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
+// CHECK-NEXT:       setAvailable(Impl);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:   }
@@ -77,14 +77,14 @@ def DarwinLibm : LibcallLibrary<"libm", (add sqrt)> { let Pred = isDarwin; }
 // sqrt 
diff ers in calling convention between the two libm variants, so it stays
 // per-variant: no shared-core hoist, and the GNU variant keeps its ARM_AAPCS.
 
-// CHECK: static void setAvailableLibFuncs_libm(llvm::RTLIB::RuntimeLibcallsInfo &Info, const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_libm(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) {
 // CHECK-NEXT:   if (TT.isOSDarwin()) {
 // CHECK-NEXT:     static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:         RTLIB::impl_sqrt, // sqrt
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
+// CHECK-NEXT:       setAvailable(Impl);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:   }
@@ -94,8 +94,8 @@ def DarwinLibm : LibcallLibrary<"libm", (add sqrt)> { let Pred = isDarwin; }
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls_AlwaysAvailable_ARM_AAPCS) {
-// CHECK-NEXT:       Info.setAvailable(Impl);
-// CHECK-NEXT:       Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS);
+// CHECK-NEXT:       setAvailable(Impl);
+// CHECK-NEXT:       setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS);
 // CHECK-NEXT:     }
 // CHECK-EMPTY:
 // CHECK-NEXT:   }

diff  --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index bf47d2aca4dec..3724b37e50101 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -90,19 +90,27 @@ class RuntimeLibcallEmitter {
 
   // Emit the sorted per-predicate `setAvailable` tables/loops. The
   // always-available bucket emits at \p BaseIndent; each predicated bucket is
-  // wrapped in `if (pred)`. \p Receiver prefixes the calls ("Info." for the
-  // standalone library functions, empty otherwise).
+  // wrapped in `if (pred)`. All calls are emitted in member context (no
+  // receiver prefix).
   void
   emitPredicateGroups(raw_ostream &OS, const Record *R,
                       DenseMap<PredicateWithCC, LibcallsWithCC> &Pred2Funcs,
                       SetVector<PredicateWithCC> &PredicateSorter,
-                      unsigned BaseIndent, StringRef Receiver) const;
+                      unsigned BaseIndent) const;
 
-  // Emit a file-local `setAvailableLibFuncs_<name>` for all LibcallLibrary defs
-  // sharing \p Name, each gated by its own availability predicate.
+  // Emit a `setAvailableLibFuncs_<name>` member function for all LibcallLibrary
+  // defs sharing \p Name, each gated by its own availability predicate.
   void emitLibraryFunction(raw_ostream &OS, StringRef Name,
                            ArrayRef<const Record *> Libs) const;
 
+  // Group all LibcallLibrary defs by their shared LibraryName, preserving
+  // definition order. Both the member-declaration fragment and the definitions
+  // iterate this to stay in lockstep.
+  MapVector<StringRef, std::vector<const Record *>>
+  collectLibrariesByName() const;
+
+  void emitRuntimeLibcallsInfoMemberDecls(raw_ostream &OS) const;
+
   void emitSystemRuntimeLibrarySetCalls(raw_ostream &OS) const;
 
   DenseSet<StringRef> collectLibcallNames() const;
@@ -390,8 +398,7 @@ const uint8_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameSizeTable[] = {
 void RuntimeLibcallEmitter::emitPredicateGroups(
     raw_ostream &OS, const Record *R,
     DenseMap<PredicateWithCC, LibcallsWithCC> &Pred2Funcs,
-    SetVector<PredicateWithCC> &PredicateSorter, unsigned BaseIndent,
-    StringRef Receiver) const {
+    SetVector<PredicateWithCC> &PredicateSorter, unsigned BaseIndent) const {
   SmallVector<PredicateWithCC, 0> SortedPredicates =
       PredicateSorter.takeVector();
 
@@ -459,14 +466,13 @@ void RuntimeLibcallEmitter::emitPredicateGroups(
     if (FuncsWithCC.CallingConv)
       OS << '_' << FuncsWithCC.CallingConv->getName();
 
-    OS << ") {\n"
-       << indent(IndentDepth + 4) << Receiver << "setAvailable(Impl);\n";
+    OS << ") {\n" << indent(IndentDepth + 4) << "setAvailable(Impl);\n";
 
     if (FuncsWithCC.CallingConv) {
       StringRef CCEnum =
           FuncsWithCC.CallingConv->getValueAsString("CallingConv");
-      OS << indent(IndentDepth + 4) << Receiver
-         << "setLibcallImplCallingConv(Impl, " << CCEnum << ");\n";
+      OS << indent(IndentDepth + 4) << "setLibcallImplCallingConv(Impl, "
+         << CCEnum << ");\n";
     }
 
     OS << indent(IndentDepth + 2) << "}\n";
@@ -489,10 +495,9 @@ static void emitLibFuncSuffix(raw_ostream &OS, StringRef Name) {
 
 void RuntimeLibcallEmitter::emitLibraryFunction(
     raw_ostream &OS, StringRef Name, ArrayRef<const Record *> Libs) const {
-  // File-local; referenced only from the driver in the same fragment.
-  OS << "static void setAvailableLibFuncs_";
+  OS << "void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_";
   emitLibFuncSuffix(OS, Name);
-  OS << "(llvm::RTLIB::RuntimeLibcallsInfo &Info, const llvm::Triple &TT, "
+  OS << "(const llvm::Triple &TT, "
         "ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, "
         "EABI EABIVersion, StringRef ABIName, "
         "LongDoubleFormat LongDoubleFormat) {\n";
@@ -574,7 +579,7 @@ void RuntimeLibcallEmitter::emitLibraryFunction(
     for (const RuntimeLibcallImpl *Impl : SharedCore)
       CorePred2Funcs[PredicateWithCC()].LibcallImpls.push_back(Impl);
     emitPredicateGroups(OS, Libs.front(), CorePred2Funcs, CoreSorter,
-                        /*BaseIndent=*/0, /*Receiver=*/"Info.");
+                        /*BaseIndent=*/0);
 
     for (ExpandedLibrary &EL : Expanded) {
       auto &Funcs = EL.Pred2Funcs[PredicateWithCC()].LibcallImpls;
@@ -597,7 +602,7 @@ void RuntimeLibcallEmitter::emitLibraryFunction(
     }
 
     emitPredicateGroups(OS, EL.Lib, EL.Pred2Funcs, EL.PredicateSorter,
-                        /*BaseIndent=*/2, /*Receiver=*/"Info.");
+                        /*BaseIndent=*/2);
 
     if (!LibPred.isAlwaysAvailable()) {
       OS << indent(2);
@@ -610,16 +615,30 @@ void RuntimeLibcallEmitter::emitLibraryFunction(
   OS << "}\n\n";
 }
 
-void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
-    raw_ostream &OS) const {
-  // Emit one function per distinct library name; same-named defs merge.
-  //
-  // TODO: SystemRuntimeLibrary does not yet dispatch to these
+MapVector<StringRef, std::vector<const Record *>>
+RuntimeLibcallEmitter::collectLibrariesByName() const {
   MapVector<StringRef, std::vector<const Record *>> LibsByName;
   for (const Record *Lib : Records.getAllDerivedDefinitions("LibcallLibrary"))
     LibsByName[Lib->getValueAsString("LibraryName")].push_back(Lib);
+  return LibsByName;
+}
+
+void RuntimeLibcallEmitter::emitRuntimeLibcallsInfoMemberDecls(
+    raw_ostream &OS) const {
+  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALLS_INFO_MEMBER_DECLS");
+  for (const auto &[Name, Libs] : collectLibrariesByName()) {
+    OS << "void setAvailableLibFuncs_";
+    emitLibFuncSuffix(OS, Name);
+    OS << "(const llvm::Triple &TT, ExceptionHandling ExceptionModel, "
+          "FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, "
+          "LongDoubleFormat LongDoubleFormat);\n";
+  }
+}
 
-  for (const auto &[Name, Libs] : LibsByName)
+void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
+    raw_ostream &OS) const {
+  // Emit one function per distinct library name; same-named defs merge.
+  for (const auto &[Name, Libs] : collectLibrariesByName())
     emitLibraryFunction(OS, Name, Libs);
 
   ArrayRef<const Record *> AllLibs =
@@ -651,6 +670,29 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
       }
     }
 
+    // Split the top-level member list into named LibcallLibrary references,
+    // which are dispatched to their own setAvailableLibFuncs_<name> function
+    // under an isLibraryAvailable guard, and the remaining (bare impl /
+    // LibcallImpls) members, which are emitted inline via the flat path below.
+    const DagInit *MemberDag =
+        R->getValueAsDef("MemberList")->getValueAsDag("MemberList");
+    SmallVector<StringRef, 4> DispatchLibs;
+    SmallVector<const Init *, 16> InlineArgs;
+    SmallVector<const StringInit *, 16> InlineArgNames;
+    for (auto [Arg, ArgName] :
+         zip_equal(MemberDag->getArgs(), MemberDag->getArgNames())) {
+      if (const auto *DI = dyn_cast<DefInit>(Arg);
+          DI && DI->getDef()->isSubClassOf("LibcallLibrary")) {
+        DispatchLibs.push_back(DI->getDef()->getValueAsString("LibraryName"));
+        continue;
+      }
+      InlineArgs.push_back(Arg);
+      InlineArgNames.push_back(ArgName);
+    }
+
+    const DagInit *InlineDag =
+        DagInit::get(MemberDag->getOperator(), InlineArgs, InlineArgNames);
+
     SetTheory Sets;
 
     DenseMap<const RuntimeLibcallImpl *,
@@ -659,8 +701,9 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
     Sets.addExpander("LibcallImpls", std::make_unique<LibcallPredicateExpander>(
                                          Libcalls, Func2Preds));
 
-    const SetTheory::RecVec *Elements =
-        Sets.expand(R->getValueAsDef("MemberList"));
+    SetTheory::RecSet ElementsSet;
+    Sets.evaluate(InlineDag, ElementsSet, R->getLoc());
+    const SetTheory::RecSet *Elements = &ElementsSet;
 
     // Sort to get deterministic output
     SetVector<PredicateWithCC> PredicateSorter;
@@ -723,8 +766,20 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
     OS << "\n    });\n"
           "    AvailableLibcallImpls = SystemAvailableImpls;\n\n";
 
-    emitPredicateGroups(OS, R, Pred2Funcs, PredicateSorter, /*BaseIndent=*/2,
-                        /*Receiver=*/"");
+    // Dispatch to each named library's setup function. This must come after the
+    // SystemAvailableImpls assignment above (which overwrites the bitset); the
+    // library functions union their members in on top via setAvailable.
+    for (StringRef LibName : DispatchLibs) {
+      OS << indent(4) << "if (isLibraryAvailable(\"" << LibName << "\"))\n"
+         << indent(6) << "setAvailableLibFuncs_";
+      emitLibFuncSuffix(OS, LibName);
+      OS << "(TT, ExceptionModel, FloatABI, EABIVersion, ABIName, "
+            "LongDoubleFormat);\n";
+    }
+    if (!DispatchLibs.empty())
+      OS << '\n';
+
+    emitPredicateGroups(OS, R, Pred2Funcs, PredicateSorter, /*BaseIndent=*/2);
 
     OS << indent(4) << "return;\n" << indent(2);
     TopLevelPredicate.emitEndIf(OS);
@@ -901,6 +956,8 @@ void RuntimeLibcallEmitter::run(raw_ostream &OS) {
 
   emitGetInitRuntimeLibcallNames(OS);
 
+  emitRuntimeLibcallsInfoMemberDecls(OS);
+
   {
     IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALLS_INFO");
     emitSystemRuntimeLibrarySetCalls(OS);


        


More information about the llvm-commits mailing list