[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