[llvm] TableGen: Allow defining sets of runtime libraries (PR #144978)
Daniel Paoliello via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 27 11:14:16 PDT 2025
================
@@ -297,48 +295,190 @@ void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallNames(
OS << '\n';
}
OS << "};\n\n";
+}
- std::vector<RuntimeLibcallImpl> ZOSRuntimeLibcallImplList =
- getRuntimeLibcallImplSet("ZOSRuntimeLibcallImpl");
- emitTargetOverrideFunc(OS, "setZOSLibCallNameOverrides",
- ZOSRuntimeLibcallImplList);
+void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
+ raw_ostream &OS) const {
+ OS << "void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets("
+ "const llvm::Triple &TT) {\n"
+ " struct LibcallImplPair {\n"
+ " RTLIB::Libcall Func;\n"
+ " RTLIB::LibcallImpl Impl;\n"
+ " };\n";
+ ArrayRef<const Record *> AllLibs =
+ Records.getAllDerivedDefinitions("SystemRuntimeLibrary");
+
+ for (const Record *R : AllLibs) {
+ OS << '\n';
- std::vector<RuntimeLibcallImpl> PPCRuntimeLibcallImplList =
- getRuntimeLibcallImplSet("PPCRuntimeLibcallImpl");
- emitTargetOverrideFunc(OS, "setPPCLibCallNameOverrides",
- PPCRuntimeLibcallImplList);
+ AvailabilityPredicate TopLevelPredicate(R->getValueAsDef("TriplePred"));
- emitWindowsArm64LibCallNameOverrides(OS);
-}
+ OS << indent(2);
+ TopLevelPredicate.emitIf(OS);
+ SetTheory Sets;
-void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallUtils(
- raw_ostream &OS) const {
- // FIXME: Hack we shouldn't really need
- OS << "#ifdef GET_INIT_RUNTIME_LIBCALL_UTILS\n"
- "static inline bool isAtomicLibCall(llvm::RTLIB::Libcall LC) {\n"
- " switch (LC) {\n";
- for (const RuntimeLibcall &LibCall : RuntimeLibcallDefList) {
- StringRef Name = LibCall.getName();
- if (Name.contains("ATOMIC")) {
- OS << " case ";
- LibCall.emitEnumEntry(OS);
- OS << ":\n";
+ DenseMap<const Record *, std::vector<const Record *>> Func2Preds;
+ Sets.addExpander(
+ "LibcallImpls",
+ std::make_unique<LibcallPredicateExpander>(*this, Func2Preds));
+
+ const SetTheory::RecVec *Elements =
+ Sets.expand(R->getValueAsDef("MemberList"));
+
+ // Sort to get deterministic output
+ SetVector<const Record *> PredicateSorter;
+ PredicateSorter.insert(nullptr); // No predicate first.
+
+ DenseMap<const Record *, std::vector<const RuntimeLibcallImpl *>>
+ Pred2Funcs;
+ for (const Record *Elt : *Elements) {
+ const RuntimeLibcallImpl *LibCallImpl = getRuntimeLibcallImpl(Elt);
+ if (!LibCallImpl) {
+ PrintError(R, "entry for SystemLibrary is not a RuntimeLibcallImpl");
+
+ PrintNote(Elt->getLoc(), "invalid entry `" + Elt->getName() + "`");
+
+ continue;
+ }
+
+ auto It = Func2Preds.find(Elt);
+ if (It == Func2Preds.end()) {
+ Pred2Funcs[nullptr].push_back(LibCallImpl);
+ continue;
+ }
+
+ for (const Record *Pred : It->second) {
+ Pred2Funcs[Pred].push_back(LibCallImpl);
+ PredicateSorter.insert(Pred);
+ }
+ }
+
+ SmallVector<const Record *, 0> SortedPredicates =
+ PredicateSorter.takeVector();
+
+ sort(SortedPredicates, [](const Record *A, const Record *B) {
+ if (!A)
+ return true;
+ if (!B)
+ return false;
+ return A->getName() < B->getName();
+ });
+
+ for (const Record *Pred : SortedPredicates) {
+ AvailabilityPredicate SubsetPredicate(Pred);
+ unsigned IndentDepth = 2;
+
+ auto It = Pred2Funcs.find(Pred);
+ if (It == Pred2Funcs.end())
+ continue;
+
+ if (!SubsetPredicate.isAlwaysAvailable()) {
+ IndentDepth = 4;
+
+ OS << indent(IndentDepth);
+ SubsetPredicate.emitIf(OS);
+ }
+
+ std::vector<const RuntimeLibcallImpl *> &Funcs = It->second;
+
+ // Ensure we only emit a unique implementation per libcall in the
+ // selection table.
+ //
+ // FIXME: We need to generate separate functions for
----------------
dpaoliello wrote:
Addressed in later PR?
https://github.com/llvm/llvm-project/pull/144978
More information about the llvm-commits
mailing list