//===- RuntimeLibcallEmitter.cpp - Properties from RuntimeLibcalls.td -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "runtime-libcall-emitter"

#include "RuntimeLibcalls.h"

#include "SequenceToOffsetTable.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/xxhash.h"
#include "llvm/TableGen/CodeGenHelpers.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/SetTheory.h"
#include "llvm/TableGen/StringToOffsetTable.h"
#include "llvm/TableGen/TableGenBackend.h"

using namespace llvm;

namespace {
// Pair of a RuntimeLibcallAvailability and LibcallCallingConv to use as a map
// key.
struct PredicateWithCC {
  const Record *Availability = nullptr;
  const Record *CallingConv = nullptr;

  PredicateWithCC() = default;
  PredicateWithCC(std::pair<const Record *, const Record *> P)
      : Availability(P.first), CallingConv(P.second) {}

  PredicateWithCC(const Record *P, const Record *C)
      : Availability(P), CallingConv(C) {}
};

inline bool operator==(PredicateWithCC LHS, PredicateWithCC RHS) {
  return LHS.Availability == RHS.Availability &&
         LHS.CallingConv == RHS.CallingConv;
}
} // namespace

namespace {
/// A floating-point libcall family parsed from a RuntimeLibcallFamily record.
struct FPLibcallFamily {
  StringRef Base;
  std::vector<StringRef> Intrinsics;
  std::vector<StringRef> VectorSuffixes;

  explicit FPLibcallFamily(const Record *R)
      : Base(R->getValueAsString("LibcallBase")),
        Intrinsics(R->getValueAsListOfStrings("Intrinsics")),
        VectorSuffixes(R->getValueAsListOfStrings("VectorSuffixes")) {}
};
} // namespace

namespace llvm {
template <> struct DenseMapInfo<PredicateWithCC, void> {
  static unsigned getHashValue(const PredicateWithCC Val) {
    auto Pair = std::make_pair(Val.Availability, Val.CallingConv);
    return DenseMapInfo<
        std::pair<const Record *, const Record *>>::getHashValue(Pair);
  }

  static bool isEqual(PredicateWithCC LHS, PredicateWithCC RHS) {
    return LHS == RHS;
  }
};

class RuntimeLibcallEmitter {
private:
  const RecordKeeper &Records;
  RuntimeLibcalls Libcalls;

  void emitGetRuntimeLibcallEnum(raw_ostream &OS) const;

  void emitNameMatchHashTable(raw_ostream &OS,
                              StringToOffsetTable &OffsetTable) const;

  void emitGetInitRuntimeLibcallNames(raw_ostream &OS) const;
  void emitGetInitRuntimeLibcallSignatures(raw_ostream &OS) const;
  void emitMaskedVectorLibcallMapping(raw_ostream &OS) const;

  // Emit the sorted per-predicate `setAvailable` tables/loops. The
  // always-available bucket emits at \p BaseIndent; each predicated bucket is
  // 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) const;

  // A LibraryRef opt-out: the impls a consumer drops from a shared library,
  // plus the consumer's triple predicate.
  struct LibraryExclusion {
    const Record *TriplePred;
    std::vector<const RuntimeLibcallImpl *> Impls;
  };

  // A SystemRuntimeLibrary's default calling convention and the libraries it
  // dispatches, as (LibraryName, FuncSuffix) pairs.
  struct SystemLibraryDispatch {
    const Record *System;
    StringRef DefaultCC;
    SetVector<std::pair<StringRef, StringRef>> Libs;
  };

  // A single LibcallLibrary variant, expanded into its per-predicate impl
  // groups. Unconditional impls are tracked separately for cross-variant
  // deduplication. A variant is Deferred when it re-adds an impl its own
  // consumer excludes; deferred variants are emitted after the LibraryRef
  // exclusions so the re-add wins over the opt-out.
  struct ExpandedLibrary {
    const Record *Lib;
    DenseMap<PredicateWithCC, LibcallsWithCC> Pred2Funcs;
    SetVector<PredicateWithCC> PredicateSorter;
    SetVector<const RuntimeLibcallImpl *> Unconditional;
    bool Deferred = false;
  };

  // Emit one variant's guarded `setAvailable` block into the enclosing
  // `setAvailableLibFuncs_<name>` function.
  void emitLibraryVariant(raw_ostream &OS, ExpandedLibrary &EL) const;

  // Emit a `setAvailableLibFuncs_<name>` member function for all LibcallLibrary
  // defs sharing \p Name, each gated by its own availability predicate. \p
  // Exclusions are emitted as guarded setUnavailable calls at the end.
  void emitLibraryFunction(raw_ostream &OS, StringRef Name,
                           ArrayRef<const Record *> Libs,
                           ArrayRef<LibraryExclusion> Exclusions) 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;

  // Get the sorted, unique list of every defined LibraryName.
  std::vector<StringRef> collectLibraryNames() const;

  void emitRuntimeLibcallsInfoMemberDecls(raw_ostream &OS) const;

  std::vector<SystemLibraryDispatch> collectSystemLibraryDispatch() const;

  void emitSystemRuntimeLibrarySetCalls(
      raw_ostream &OS, ArrayRef<SystemLibraryDispatch> Systems) const;

  // Emit setAvailableLibraryLibcalls, which enables a library by name.
  void emitLibraryByNameSetCalls(raw_ostream &OS,
                                 ArrayRef<SystemLibraryDispatch> Systems) const;

  DenseSet<StringRef> collectLibcallNames() const;

  void checkFPLibcallFamilies(ArrayRef<FPLibcallFamily> Families,
                              const DenseSet<StringRef> &LibcallNames) const;

  void emitFPLibcallSelectorDecls(raw_ostream &OS,
                                  ArrayRef<FPLibcallFamily> Families) const;

  void emitFPLibcallSelectors(raw_ostream &OS,
                              ArrayRef<FPLibcallFamily> Families,
                              const DenseSet<StringRef> &LibcallNames) const;

  void
  emitGetLibcallForIntrinsic(raw_ostream &OS,
                             ArrayRef<FPLibcallFamily> Families,
                             const DenseSet<StringRef> &LibcallNames) const;

public:
  RuntimeLibcallEmitter(const RecordKeeper &R) : Records(R), Libcalls(R) {}

  void run(raw_ostream &OS);
};

} // End anonymous namespace.

// Emit the linker name \p Name as a C++ identifier suffix, replacing characters
// invalid in an identifier (e.g. the '-' in "compiler-rt") with '_'.
static void emitLibFuncSuffix(raw_ostream &OS, StringRef Name) {
  for (char C : Name)
    OS << (isAlnum(C) || C == '_' ? C : '_');
}

static void emitRuntimeLibraryEnumerator(raw_ostream &OS, StringRef Name) {
  OS << "RTLIB::RuntimeLibrary::";
  emitLibFuncSuffix(OS, Name);
}

void RuntimeLibcallEmitter::emitGetRuntimeLibcallEnum(raw_ostream &OS) const {
  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALL_ENUM");

  OS << "namespace llvm {\n"
        "namespace RTLIB {\n"
        "enum Libcall : unsigned short {\n";

  for (const RuntimeLibcall &LibCall : Libcalls.getRuntimeLibcallDefList()) {
    StringRef Name = LibCall.getName();
    OS << "  " << Name << " = " << LibCall.getEnumVal() << ",\n";
  }

  OS << "  UNKNOWN_LIBCALL = " << Libcalls.getRuntimeLibcallDefList().size()
     << "\n};\n\n"
        "enum LibcallImpl : unsigned short {\n"
        "  Unsupported = 0,\n";

  for (const RuntimeLibcallImpl &LibCall :
       Libcalls.getRuntimeLibcallImplDefList()) {
    OS << "  impl_" << LibCall.getName() << " = " << LibCall.getEnumVal()
       << ", // " << LibCall.getLibcallFuncName() << '\n';
  }

  OS << "};\n"
     << "constexpr size_t NumLibcallImpls = "
     << Libcalls.getRuntimeLibcallImplDefList().size() + 1
     << ";\n\n"
        "enum FuncArgTypeID : char {\n"
        "  NoFuncArgType = 0,\n";

  for (const auto *R : Libcalls.getFuncArgTypeList()) {
    if (R->getName() == "NoneType")
      continue;
    OS << "  " << R->getName() << ",\n";
  }

  OS << "};\n\n"
        "enum class RuntimeLibrary : unsigned char {\n"
        "  UnknownLibrary = 0,\n";
  for (StringRef Name : collectLibraryNames()) {
    OS << "  ";
    emitLibFuncSuffix(OS, Name);
    OS << ",\n";
  }

  OS << "};\n"
        "} // End namespace RTLIB\n"
        "} // End namespace llvm\n";
}

// StringMap uses xxh3_64bits, truncated to uint32_t.
static uint64_t hash(StringRef Str) {
  return static_cast<uint32_t>(xxh3_64bits(Str));
}

static void emitHashFunction(raw_ostream &OS) {
  OS << "static inline uint64_t hash(StringRef Str) {\n"
        "  return static_cast<uint32_t>(xxh3_64bits(Str));\n"
        "}\n\n";
}

/// Return the table size, maximum number of collisions for the set of hashes
static std::pair<int, int>
computePerfectHashParameters(ArrayRef<uint64_t> Hashes) {
  // Chosen based on experimentation with llvm/benchmarks/RuntimeLibcalls.cpp
  const int SizeOverhead = 4;

  // Index derived from hash -> number of collisions.
  DenseMap<uint64_t, int> Table;

  unsigned NumHashes = Hashes.size();

  for (int MaxCollisions = 1;; ++MaxCollisions) {
    for (unsigned N = NextPowerOf2(NumHashes - 1); N < SizeOverhead * NumHashes;
         N <<= 1) {
      Table.clear();

      bool NeedResize = false;
      for (uint64_t H : Hashes) {
        uint64_t Idx = H % static_cast<uint64_t>(N);
        if (++Table[Idx] > MaxCollisions) {
          // Need to resize the final table if we increased the collision count.
          NeedResize = true;
          break;
        }
      }

      if (!NeedResize)
        return {N, MaxCollisions};
    }
  }
}

static std::vector<unsigned>
constructPerfectHashTable(ArrayRef<RuntimeLibcallImpl> Keywords,
                          ArrayRef<uint64_t> Hashes,
                          ArrayRef<unsigned> TableValues, int Size,
                          int Collisions, StringToOffsetTable &OffsetTable) {
  std::vector<unsigned> Lookup(Size * Collisions);

  for (auto [HashValue, TableValue] : zip(Hashes, TableValues)) {
    uint64_t Idx = (HashValue % static_cast<uint64_t>(Size)) *
                   static_cast<uint64_t>(Collisions);

    bool Found = false;
    for (int J = 0; J < Collisions; ++J) {
      unsigned &Entry = Lookup[Idx + J];
      if (Entry == 0) {
        Entry = TableValue;
        Found = true;
        break;
      }
    }

    if (!Found)
      reportFatalInternalError("failure to hash");
  }

  return Lookup;
}

/// Generate hash table based lookup by name.
void RuntimeLibcallEmitter::emitNameMatchHashTable(
    raw_ostream &OS, StringToOffsetTable &OffsetTable) const {
  ArrayRef<RuntimeLibcallImpl> RuntimeLibcallImplDefList =
      Libcalls.getRuntimeLibcallImplDefList();
  std::vector<uint64_t> Hashes(RuntimeLibcallImplDefList.size());
  std::vector<unsigned> TableValues(RuntimeLibcallImplDefList.size());
  DenseSet<StringRef> SeenFuncNames;

  size_t MaxFuncNameSize = 0;
  size_t Index = 0;

  for (const RuntimeLibcallImpl &LibCallImpl : RuntimeLibcallImplDefList) {
    StringRef ImplName = LibCallImpl.getLibcallFuncName();
    if (SeenFuncNames.insert(ImplName).second) {
      MaxFuncNameSize = std::max(MaxFuncNameSize, ImplName.size());
      TableValues[Index] = LibCallImpl.getEnumVal();
      Hashes[Index++] = hash(ImplName);
    }
  }

  // Trim excess elements from non-unique entries.
  Hashes.resize(SeenFuncNames.size());
  TableValues.resize(SeenFuncNames.size());

  LLVM_DEBUG({
    for (const RuntimeLibcallImpl &LibCallImpl : RuntimeLibcallImplDefList) {
      StringRef ImplName = LibCallImpl.getLibcallFuncName();
      if (ImplName.size() == MaxFuncNameSize) {
        dbgs() << "Maximum runtime libcall name size: " << ImplName << '('
               << MaxFuncNameSize << ")\n";
      }
    }
  });

  // Early exiting on the symbol name provides a significant speedup in the miss
  // case on the set of symbols in a clang binary. Emit this as an inlinable
  // precondition in the header.
  //
  // The empty check is also used to get sensible behavior on anonymous
  // functions.
  //
  // TODO: It may make more sense to split the search by string size more. There
  // are a few outliers, most call names are small.
  {
    IfDefEmitter IfDef(OS, "GET_LOOKUP_LIBCALL_IMPL_NAME_BODY");

    OS << "  size_t Size = Name.size();\n"
          "  if (Size == 0 || Size > "
       << MaxFuncNameSize
       << ")\n"
          "    return enum_seq(RTLIB::Unsupported, RTLIB::Unsupported);\n"
          " return lookupLibcallImplNameImpl(Name);\n";
  }

  auto [Size, Collisions] = computePerfectHashParameters(Hashes);
  std::vector<unsigned> Lookup =
      constructPerfectHashTable(RuntimeLibcallImplDefList, Hashes, TableValues,
                                Size, Collisions, OffsetTable);

  LLVM_DEBUG(dbgs() << "Runtime libcall perfect hashing parameters: Size = "
                    << Size << ", maximum collisions = " << Collisions << '\n');

  IfDefEmitter IfDef(OS, "DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME");
  emitHashFunction(OS);

  OS << "iota_range<RTLIB::LibcallImpl> RTLIB::RuntimeLibcallsInfo::"
        "lookupLibcallImplNameImpl(StringRef Name) {\n";

  // Emit RTLIB::LibcallImpl values
  OS << "  static constexpr uint16_t HashTableNameToEnum[" << Lookup.size()
     << "] = {\n";

  for (unsigned TableVal : Lookup)
    OS << "    " << TableVal << ",\n";

  OS << "  };\n\n";

  OS << "  unsigned Idx = (hash(Name) % " << Size << ") * " << Collisions
     << ";\n\n"
        "  for (int I = 0; I != "
     << Collisions << R"(; ++I) {
    const uint16_t Entry = HashTableNameToEnum[Idx + I];
    const uint16_t StrOffset = RuntimeLibcallNameOffsetTable[Entry];
    const uint8_t StrSize = RuntimeLibcallNameSizeTable[Entry];
    StringRef Str(
      &RTLIB::RuntimeLibcallsInfo::RuntimeLibcallImplNameTableStorage[StrOffset],
      StrSize);
    if (Str == Name)
      return libcallImplNameHit(Entry, StrOffset);
  }

  return enum_seq(RTLIB::Unsupported, RTLIB::Unsupported);
}
)";
}

void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallNames(
    raw_ostream &OS) const {
  // Emit the implementation names
  StringToOffsetTable Table(/*AppendZero=*/true,
                            "RTLIB::RuntimeLibcallsInfo::");

  {
    IfDefEmitter IfDef(OS, "GET_INIT_RUNTIME_LIBCALL_NAMES");

    for (const RuntimeLibcallImpl &LibCallImpl :
         Libcalls.getRuntimeLibcallImplDefList())
      Table.GetOrAddStringOffset(LibCallImpl.getLibcallFuncName());

    Table.EmitStringTableDef(OS, "RuntimeLibcallImplNameTable");
    OS << R"(
const uint16_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameOffsetTable[] = {
)";

    OS << formatv("  {}, // {}\n", Table.GetStringOffset(""),
                  ""); // Unsupported entry
    for (const RuntimeLibcallImpl &LibCallImpl :
         Libcalls.getRuntimeLibcallImplDefList()) {
      StringRef ImplName = LibCallImpl.getLibcallFuncName();
      OS << formatv("  {}, // {}\n", Table.GetStringOffset(ImplName), ImplName);
    }
    OS << "};\n";

    OS << R"(
const uint8_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameSizeTable[] = {
)";

    OS << "  0,\n";
    for (const RuntimeLibcallImpl &LibCallImpl :
         Libcalls.getRuntimeLibcallImplDefList())
      OS << "  " << LibCallImpl.getLibcallFuncName().size() << ",\n";
    OS << "};\n\n";

    // Emit the reverse mapping from implementation libraries to RTLIB::Libcall
    OS << "const RTLIB::Libcall llvm::RTLIB::RuntimeLibcallsInfo::"
          "ImplToLibcall[RTLIB::NumLibcallImpls] = {\n"
          "  RTLIB::UNKNOWN_LIBCALL, // RTLIB::Unsupported\n";

    for (const RuntimeLibcallImpl &LibCallImpl :
         Libcalls.getRuntimeLibcallImplDefList()) {
      const RuntimeLibcall *Provides = LibCallImpl.getProvides();
      OS << "  ";
      Provides->emitEnumEntry(OS);
      OS << ", // ";
      LibCallImpl.emitEnumEntry(OS);
      OS << '\n';
    }

    OS << "};\n\n";
  }

  emitNameMatchHashTable(OS, Table);
}

using Signature = std::vector<StringRef>;

static Signature getSignature(const Record *R) {
  const auto *Tys = R->getValueAsListInit("ArgumentTypes");
  Signature Sig;
  Sig.reserve(Tys->size() + 1);
  const Record *RetType = R->getValueAsOptionalDef("ReturnType");
  if (RetType && RetType->getName() != "NoneType")
    Sig.push_back(RetType->getName());
  for (unsigned I = 0, E = Tys->size(); I < E; ++I)
    Sig.push_back(Tys->getElementAsRecord(I)->getName());
  return Sig;
}

void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallSignatures(
    raw_ostream &OS) const {
  SequenceToOffsetTable<Signature> SignatureTable("NoFuncArgType");

  for (const RuntimeLibcall &LC : Libcalls.getRuntimeLibcallDefList())
    SignatureTable.add(getSignature(LC.getDef()));
  SignatureTable.layout();

  IfDefEmitter IfDef(OS, "GET_INIT_RUNTIME_LIBCALL_SIGNATURES");

  OS << R"(
const FuncArgTypeID RTLIB::RuntimeLibcallsInfo::SignatureTable[] = {
)";
  SignatureTable.emit(OS, [](raw_ostream &OS, StringRef E) { OS << E; });
  OS << "};\n";

  OS << R"(
const uint16_t RTLIB::RuntimeLibcallsInfo::SignatureOffset[] = {
)";
  for (const RuntimeLibcall &LC : Libcalls.getRuntimeLibcallDefList()) {
    const Record *LibcallDef = LC.getDef();
    OS << formatv("  {}, // {}\n", SignatureTable.get(getSignature(LibcallDef)),
                  LibcallDef->getName());
  }
  OS << "};\n";
}

static void emitMaskedVectorLibcallSwitch(
    raw_ostream &OS, StringRef FuncName, bool ToUnmasked,
    ArrayRef<std::pair<const RuntimeLibcall *, const RuntimeLibcall *>>
        MaskedToUnmasked) {
  OS << "RTLIB::Libcall RTLIB::RuntimeLibcallsInfo::" << FuncName
     << "(RTLIB::Libcall LC) {\n"
        "  switch (LC) {\n";
  for (auto [Masked, Unmasked] : MaskedToUnmasked) {
    OS << "  case ";
    if (ToUnmasked) {
      Masked->emitEnumEntry(OS);
      OS << ":\n    return ";
      Unmasked->emitEnumEntry(OS);
    } else {
      Unmasked->emitEnumEntry(OS);
      OS << ":\n    return ";
      Masked->emitEnumEntry(OS);
    }

    OS << ";\n";
  }

  OS << "  default:\n"
        "    return RTLIB::UNKNOWN_LIBCALL;\n"
        "  }\n"
        "}\n";
}

void RuntimeLibcallEmitter::emitMaskedVectorLibcallMapping(
    raw_ostream &OS) const {
  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALL_MASKED_VECTOR_LIBCALL_MAPPING");

  SmallVector<std::pair<const RuntimeLibcall *, const RuntimeLibcall *>, 0>
      MaskedToUnmasked;
  for (const RuntimeLibcall &LC : Libcalls.getRuntimeLibcallDefList()) {
    const Record *Def = LC.getDef();
    if (Def->isSubClassOf("MaskedRuntimeLibcall")) {
      MaskedToUnmasked.emplace_back(
          &LC, Libcalls.getRuntimeLibcall(Def->getValueAsDef("Unmasked")));
    }
  }

  emitMaskedVectorLibcallSwitch(OS, "getUnmaskedVectorLibcall",
                                /*ToUnmasked=*/true, MaskedToUnmasked);
  OS << '\n';
  emitMaskedVectorLibcallSwitch(OS, "getMaskedVectorLibcall",
                                /*ToUnmasked=*/false, MaskedToUnmasked);
}

void RuntimeLibcallEmitter::emitPredicateGroups(
    raw_ostream &OS, const Record *R,
    DenseMap<PredicateWithCC, LibcallsWithCC> &Pred2Funcs,
    SetVector<PredicateWithCC> &PredicateSorter, unsigned BaseIndent) const {
  SmallVector<PredicateWithCC, 0> SortedPredicates =
      PredicateSorter.takeVector();

  llvm::sort(SortedPredicates, [](PredicateWithCC A, PredicateWithCC B) {
    StringRef AName = A.Availability ? A.Availability->getName() : "";
    StringRef BName = B.Availability ? B.Availability->getName() : "";
    if (AName != BName)
      return AName < BName;
    // Break name ties on the calling convention for a deterministic order.
    StringRef ACC = A.CallingConv ? A.CallingConv->getName() : "";
    StringRef BCC = B.CallingConv ? B.CallingConv->getName() : "";
    return ACC < BCC;
  });

  for (PredicateWithCC Entry : SortedPredicates) {
    AvailabilityPredicate SubsetPredicate(Entry.Availability);
    unsigned IndentDepth = BaseIndent;

    auto It = Pred2Funcs.find(Entry);
    if (It == Pred2Funcs.end())
      continue;

    // Shared-core deduplication can empty a bucket.
    if (It->second.LibcallImpls.empty())
      continue;

    if (!SubsetPredicate.isAlwaysAvailable()) {
      IndentDepth = BaseIndent + 2;

      OS << indent(IndentDepth);
      SubsetPredicate.emitIf(OS);
    }

    LibcallsWithCC &FuncsWithCC = It->second;

    std::vector<const RuntimeLibcallImpl *> &Funcs = FuncsWithCC.LibcallImpls;

    // Records which impls are available, not which is selected, so a libcall
    // may have more than one. Order is irrelevant (each entry is a setAvailable
    // call); sort by the provided libcall, breaking ties on the impl enum for a
    // deterministic total order.
    llvm::sort(Funcs, [](const RuntimeLibcallImpl *A,
                         const RuntimeLibcallImpl *B) {
      return std::make_pair(A->getProvides()->getEnumVal(), A->getEnumVal()) <
             std::make_pair(B->getProvides()->getEnumVal(), B->getEnumVal());
    });

    OS << indent(IndentDepth + 2)
       << "static const RTLIB::LibcallImpl LibraryCalls";
    SubsetPredicate.emitTableVariableNameSuffix(OS);
    if (FuncsWithCC.CallingConv)
      OS << '_' << FuncsWithCC.CallingConv->getName();

    OS << "[] = {\n";
    for (const RuntimeLibcallImpl *LibCallImpl : Funcs) {
      OS << indent(IndentDepth + 6);
      LibCallImpl->emitEnumEntry(OS);
      OS << ", // " << LibCallImpl->getLibcallFuncName() << '\n';
    }

    OS << indent(IndentDepth + 2) << "};\n\n"
       << indent(IndentDepth + 2)
       << "for (const RTLIB::LibcallImpl Impl : LibraryCalls";
    SubsetPredicate.emitTableVariableNameSuffix(OS);
    if (FuncsWithCC.CallingConv)
      OS << '_' << FuncsWithCC.CallingConv->getName();

    OS << ") {\n" << indent(IndentDepth + 4) << "setAvailable(Impl);\n";

    if (FuncsWithCC.CallingConv) {
      StringRef CCEnum =
          FuncsWithCC.CallingConv->getValueAsString("CallingConv");
      OS << indent(IndentDepth + 4) << "setLibcallImplCallingConv(Impl, "
         << CCEnum << ");\n";
    }

    OS << indent(IndentDepth + 2) << "}\n";
    OS << '\n';

    if (!SubsetPredicate.isAlwaysAvailable()) {
      OS << indent(IndentDepth);
      SubsetPredicate.emitEndIf(OS);
      OS << '\n';
    }
  }
}

void RuntimeLibcallEmitter::emitLibraryVariant(raw_ostream &OS,
                                               ExpandedLibrary &EL) const {
  AvailabilityPredicate LibPred(EL.Lib->getValueAsDef("Pred"));

  if (!LibPred.isAlwaysAvailable()) {
    OS << indent(2);
    LibPred.emitIf(OS);
  } else {
    // Own block scope so per-variant `LibraryCalls` tables do not collide.
    OS << indent(2) << "{\n";
  }

  emitPredicateGroups(OS, EL.Lib, EL.Pred2Funcs, EL.PredicateSorter,
                      /*BaseIndent=*/2);

  if (!LibPred.isAlwaysAvailable()) {
    OS << indent(2);
    LibPred.emitEndIf(OS);
  } else {
    OS << indent(2) << "}\n";
  }
}

void RuntimeLibcallEmitter::emitLibraryFunction(
    raw_ostream &OS, StringRef Name, ArrayRef<const Record *> Libs,
    ArrayRef<LibraryExclusion> Exclusions) const {
  OS << "void llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibFuncs_";
  emitLibFuncSuffix(OS, Name);
  OS << "(const llvm::Triple &TT, "
        "ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, "
        "StringRef ABIName, "
        "LongDoubleFormat LongDoubleFormat, CallingConv::ID DefaultCC) {\n";

  SmallVector<ExpandedLibrary, 2> Expanded;
  for (const Record *Lib : Libs) {
    ExpandedLibrary EL;
    EL.Lib = Lib;

    // Expand this library's members with a library-local Func2Preds.
    SetTheory Sets;
    DenseMap<const RuntimeLibcallImpl *,
             std::pair<std::vector<const Record *>, const Record *>>
        Func2Preds;
    Sets.addExpander("LibcallImpls", std::make_unique<LibcallPredicateExpander>(
                                         Libcalls, Func2Preds));

    SetTheory::RecSet Elements;
    Sets.evaluate(Lib->getValueInit("Impls"), Elements, Lib->getLoc());

    EL.PredicateSorter.insert(
        PredicateWithCC()); // No predicate or CC override first.

    for (const Record *Elt : Elements) {
      const RuntimeLibcallImpl *LibCallImpl =
          Libcalls.getRuntimeLibcallImpl(Elt);
      if (!LibCallImpl) {
        PrintError(Lib, "entry for LibcallLibrary is not a RuntimeLibcallImpl");
        PrintNote(Elt->getLoc(), "invalid entry `" + Elt->getName() + "`");
        continue;
      }

      auto It = Func2Preds.find(LibCallImpl);
      if (It == Func2Preds.end()) {
        EL.Pred2Funcs[PredicateWithCC()].LibcallImpls.push_back(LibCallImpl);
        EL.Unconditional.insert(LibCallImpl);
        continue;
      }

      for (const Record *Pred : It->second.first) {
        const Record *CC = It->second.second;
        PredicateWithCC Key(Pred, CC);
        auto &Entry = EL.Pred2Funcs[Key];
        Entry.LibcallImpls.push_back(LibCallImpl);
        Entry.CallingConv = CC;
        EL.PredicateSorter.insert(Key);
      }
    }

    Expanded.push_back(std::move(EL));
  }

  // Impls unconditional in every variant are emitted once and stripped from
  // each variant, so the shared core is not repeated.
  SetVector<const RuntimeLibcallImpl *> SharedCore;
  if (Expanded.size() > 1) {
    for (const RuntimeLibcallImpl *Impl : Expanded.front().Unconditional) {
      if (all_of(drop_begin(Expanded), [&](const ExpandedLibrary &EL) {
            return EL.Unconditional.contains(Impl);
          }))
        SharedCore.insert(Impl);
    }
  }

  if (!SharedCore.empty()) {
    // Emit the shared core once, then strip it from every variant.
    DenseMap<PredicateWithCC, LibcallsWithCC> CorePred2Funcs;
    SetVector<PredicateWithCC> CoreSorter;
    CoreSorter.insert(PredicateWithCC());
    for (const RuntimeLibcallImpl *Impl : SharedCore)
      CorePred2Funcs[PredicateWithCC()].LibcallImpls.push_back(Impl);
    emitPredicateGroups(OS, Libs.front(), CorePred2Funcs, CoreSorter,
                        /*BaseIndent=*/0);

    for (ExpandedLibrary &EL : Expanded) {
      auto &Funcs = EL.Pred2Funcs[PredicateWithCC()].LibcallImpls;
      llvm::erase_if(Funcs, [&](const RuntimeLibcallImpl *Impl) {
        return SharedCore.contains(Impl);
      });
    }
  }

  // Mark a variant deferred when it re-adds an impl its own consumer excludes
  // (same triple, via LibraryRef). Such a variant must be emitted after the
  // exclusion so the re-add wins while the exclusion still suppresses every
  // other variant's contribution.
  for (ExpandedLibrary &EL : Expanded) {
    const Record *ELPred = EL.Lib->getValueAsDef("Pred");
    SetVector<const RuntimeLibcallImpl *> Impls;
    for (const auto &[Key, Funcs] : EL.Pred2Funcs)
      Impls.insert(Funcs.LibcallImpls.begin(), Funcs.LibcallImpls.end());

    for (const LibraryExclusion &Excl : Exclusions) {
      if (Excl.TriplePred != ELPred)
        continue;
      if (any_of(Excl.Impls, [&](const RuntimeLibcallImpl *Impl) {
            return Impls.contains(Impl);
          })) {
        EL.Deferred = true;
        break;
      }
    }
  }

  // Emit each non-deferred variant under its own Pred.
  for (ExpandedLibrary &EL : Expanded) {
    if (!EL.Deferred)
      emitLibraryVariant(OS, EL);
  }

  // Emit each consumer's LibraryRef opt-outs.
  for (const LibraryExclusion &Excl : Exclusions) {
    OS << '\n' << indent(2);
    AvailabilityPredicate ExcludePred(Excl.TriplePred);
    ExcludePred.emitIf(OS);
    for (const RuntimeLibcallImpl *Impl : Excl.Impls) {
      OS << indent(4) << "setUnavailable(";
      Impl->emitEnumEntry(OS);
      OS << "); // " << Impl->getLibcallFuncName() << '\n';
    }

    OS << indent(2);
    ExcludePred.emitEndIf(OS);
  }

  // Deferred variants: emitted after exclusions so a target's own re-adds
  // override its own LibraryRef opt-outs (the exclusion still applied above
  // to every other variant's contributions).
  for (ExpandedLibrary &EL : Expanded) {
    if (EL.Deferred)
      emitLibraryVariant(OS, EL);
  }

  OS << "}\n\n";
}

// The setAvailableLibFuncs_ suffix (and merge key) for a library: its shared
// LibraryName normally, or its own def name if isolated (so it does not merge).
static StringRef libFuncKey(const Record *Lib) {
  return Lib->getValueAsBit("Isolated") ? Lib->getName()
                                        : Lib->getValueAsString("LibraryName");
}

MapVector<StringRef, std::vector<const Record *>>
RuntimeLibcallEmitter::collectLibrariesByName() const {
  MapVector<StringRef, std::vector<const Record *>> LibsByName;
  for (const Record *Lib : Records.getAllDerivedDefinitions("LibcallLibrary"))
    LibsByName[libFuncKey(Lib)].push_back(Lib);
  return LibsByName;
}

std::vector<StringRef> RuntimeLibcallEmitter::collectLibraryNames() const {
  std::vector<StringRef> Names;
  for (const Record *Lib : Records.getAllDerivedDefinitions("LibcallLibrary"))
    Names.push_back(Lib->getValueAsString("LibraryName"));
  llvm::sort(Names);
  Names.erase(llvm::unique(Names), Names.end());
  return Names;
}

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, StringRef ABIName, "
          "LongDoubleFormat LongDoubleFormat, CallingConv::ID DefaultCC);\n";
  }

  OS << "bool setAvailableLibraryLibcalls(RTLIB::RuntimeLibrary Library, "
        "const llvm::Triple &TT, ExceptionHandling ExceptionModel, "
        "FloatABI::ABIType FloatABI, StringRef ABIName, "
        "LongDoubleFormat LongDoubleFormat);\n";
}

std::vector<RuntimeLibcallEmitter::SystemLibraryDispatch>
RuntimeLibcallEmitter::collectSystemLibraryDispatch() const {
  std::vector<SystemLibraryDispatch> Systems;
  for (const Record *R :
       Records.getAllDerivedDefinitions("SystemRuntimeLibrary")) {
    SystemLibraryDispatch &S = Systems.emplace_back();
    S.System = R;
    if (const Record *DefaultCCClass =
            R->getValueAsDef("DefaultLibcallCallingConv"))
      S.DefaultCC = DefaultCCClass->getValueAsString("CallingConv").trim();

    // A library referenced more than once is dispatched once.
    const DagInit *MemberDag =
        R->getValueAsDef("MemberList")->getValueAsDag("MemberList");
    for (const Init *Arg : MemberDag->getArgs()) {
      const auto *DI = dyn_cast<DefInit>(Arg);
      const Record *Lib = DI ? DI->getDef() : nullptr;
      if (Lib && Lib->isSubClassOf("LibraryRef"))
        Lib = Lib->getValueAsDef("Library");

      if (!Lib || !Lib->isSubClassOf("LibcallLibrary")) {
        PrintError(R, "SystemRuntimeLibrary member `" + Arg->getAsString() +
                          "` is not a LibcallLibrary or LibraryRef");
        continue;
      }

      S.Libs.insert({Lib->getValueAsString("LibraryName"), libFuncKey(Lib)});
    }
  }

  return Systems;
}

void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
    raw_ostream &OS, ArrayRef<SystemLibraryDispatch> Systems) const {
  // Collect each shared library's LibraryRef opt-outs, keyed by library name,
  // so its library function can emit them.
  MapVector<StringRef, std::vector<LibraryExclusion>> ExclusionsByLibName;
  for (const SystemLibraryDispatch &S : Systems) {
    const Record *R = S.System;
    const DagInit *MemberDag =
        R->getValueAsDef("MemberList")->getValueAsDag("MemberList");
    for (const Init *Arg : MemberDag->getArgs()) {
      const auto *DI = dyn_cast<DefInit>(Arg);
      if (!DI || !DI->getDef()->isSubClassOf("LibraryRef"))
        continue;
      const Record *Def = DI->getDef();
      LibraryExclusion Excl{R->getValueAsDef("TriplePred"), {}};
      for (const Record *ExcludeRec : Def->getValueAsListOfDefs("Exclude")) {
        if (const RuntimeLibcallImpl *Impl =
                Libcalls.getRuntimeLibcallImpl(ExcludeRec))
          Excl.Impls.push_back(Impl);
      }

      if (!Excl.Impls.empty()) {
        StringRef LibName =
            Def->getValueAsDef("Library")->getValueAsString("LibraryName");
        ExclusionsByLibName[LibName].push_back(std::move(Excl));
      }
    }
  }

  for (const auto &[Name, Libs] : collectLibrariesByName())
    emitLibraryFunction(OS, Name, Libs, ExclusionsByLibName.lookup(Name));

  OS << "void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets("
        "const llvm::Triple &TT, ExceptionHandling ExceptionModel, "
        "FloatABI::ABIType FloatABI, "
        "StringRef ABIName, LongDoubleFormat LongDoubleFormat) {\n";

  for (const SystemLibraryDispatch &S : Systems) {
    OS << '\n';

    AvailabilityPredicate TopLevelPredicate(
        S.System->getValueAsDef("TriplePred"));

    OS << indent(2);
    TopLevelPredicate.emitIf(OS);

    // The default is a property of the target, and is passed to the libraries
    // as an argument.
    StringRef DefaultCCArg = "CallingConv::C";
    if (!S.DefaultCC.empty()) {
      OS << "    const CallingConv::ID DefaultCC = " << S.DefaultCC << ";\n"
         << "    for (CallingConv::ID &Entry : LibcallImplCallingConvs) {\n"
            "      Entry = DefaultCC;\n"
            "    }\n\n";
      DefaultCCArg = "DefaultCC";
    }

    // Dispatch each library to setAvailableLibFuncs_<FuncSuffix> under an
    // isLibraryAvailable(Name) guard. LibraryRef exclusions are applied inside
    // the library function.
    for (auto [Name, FuncSuffix] : S.Libs) {
      OS << indent(4) << "if (isLibraryAvailable(";
      emitRuntimeLibraryEnumerator(OS, Name);
      OS << "))\n" << indent(6) << "setAvailableLibFuncs_";
      emitLibFuncSuffix(OS, FuncSuffix);
      OS << "(TT, ExceptionModel, FloatABI, ABIName, LongDoubleFormat, "
         << DefaultCCArg << ");\n";
    }
    if (!S.Libs.empty())
      OS << '\n';

    OS << indent(4) << "return;\n" << indent(2);
    TopLevelPredicate.emitEndIf(OS);
  }

  // FIXME: This should be a fatal error. A few contexts are improperly relying
  // on RuntimeLibcalls constructed with fully unknown triples.
  OS << "  LLVM_DEBUG(dbgs() << \"no system runtime library applied to target "
        "\\'\" << TT.str() << \"\\'\\n\");\n"
        "}\n\n";
}

void RuntimeLibcallEmitter::emitLibraryByNameSetCalls(
    raw_ostream &OS, ArrayRef<SystemLibraryDispatch> Systems) const {
  // Libraries a SystemRuntimeLibrary uses are enabled by
  // setTargetRuntimeLibcallSets instead.
  DenseSet<StringRef> SystemLibNames;
  for (const SystemLibraryDispatch &S : Systems) {
    for (auto [LibName, FuncSuffix] : S.Libs)
      SystemLibNames.insert(LibName);
  }

  OS << "bool llvm::RTLIB::RuntimeLibcallsInfo::setAvailableLibraryLibcalls("
        "RTLIB::RuntimeLibrary Library, const llvm::Triple &TT, "
        "ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, "
        "StringRef ABIName, LongDoubleFormat LongDoubleFormat) {\n"
        "  switch (Library) {\n";

  for (const auto &[Name, Libs] : collectLibrariesByName()) {
    if (Libs.front()->getValueAsBit("Isolated") ||
        SystemLibNames.contains(Name))
      continue;

    OS << "  case ";
    emitRuntimeLibraryEnumerator(OS, Name);
    OS << ":\n" << indent(4) << "setAvailableLibFuncs_";
    emitLibFuncSuffix(OS, Name);
    OS << "(TT, ExceptionModel, FloatABI, ABIName, LongDoubleFormat, "
          "CallingConv::C);\n"
       << indent(4) << "return true;\n";
  }

  OS << "  default:\n"
        "    return false;\n"
        "  }\n"
        "}\n\n";
}

// Scalar FP type suffixes in the argument order of RTLIB::getFPLibCall, paired
// with the llvm::Type predicate used by the IR-level mapping.
static constexpr std::pair<StringRef, StringRef> ScalarFPSuffixes[] = {
    {"F32", "isFloatTy()"},         {"F64", "isDoubleTy()"},
    {"F80", "isX86_FP80Ty()"},      {"F128", "isFP128Ty()"},
    {"PPCF128", "isPPC_FP128Ty()"},
};

static std::vector<FPLibcallFamily>
collectFPLibcallFamilies(const RecordKeeper &Records) {
  std::vector<FPLibcallFamily> Families;
  for (const Record *R :
       Records.getAllDerivedDefinitions("RuntimeLibcallFamily"))
    Families.emplace_back(R);
  llvm::sort(Families, [](const FPLibcallFamily &A, const FPLibcallFamily &B) {
    return A.Base < B.Base;
  });
  return Families;
}

DenseSet<StringRef> RuntimeLibcallEmitter::collectLibcallNames() const {
  DenseSet<StringRef> LibcallNames;
  for (const RuntimeLibcall &LC : Libcalls.getRuntimeLibcallDefList())
    LibcallNames.insert(LC.getName());
  return LibcallNames;
}

void RuntimeLibcallEmitter::checkFPLibcallFamilies(
    ArrayRef<FPLibcallFamily> Families,
    const DenseSet<StringRef> &LibcallNames) const {
  std::vector<std::pair<StringRef, StringRef>> IntrinsicToBase;
  for (const FPLibcallFamily &Family : Families)
    for (StringRef Intrinsic : Family.Intrinsics)
      IntrinsicToBase.emplace_back(Intrinsic, Family.Base);
  llvm::sort(IntrinsicToBase);

  for (size_t I = 1, E = IntrinsicToBase.size(); I < E; ++I) {
    if (IntrinsicToBase[I].first == IntrinsicToBase[I - 1].first)
      PrintFatalError(
          "intrinsic '" + IntrinsicToBase[I].first +
          "' is mapped by multiple RuntimeLibcallFamily records ('" +
          IntrinsicToBase[I - 1].second + "' and '" +
          IntrinsicToBase[I].second + "')");
  }

  for (const FPLibcallFamily &Family : Families) {
    bool AnyScalarLibcall = any_of(
        ScalarFPSuffixes, [&](const std::pair<StringRef, StringRef> &Entry) {
          return LibcallNames.contains((Family.Base + "_" + Entry.first).str());
        });
    if (!AnyScalarLibcall)
      PrintFatalError("no runtime libcall found for base name '" + Family.Base +
                      "'");
  }
}

/// Generate the declarations for the RTLIB::get<base>(EVT) selectors.
void RuntimeLibcallEmitter::emitFPLibcallSelectorDecls(
    raw_ostream &OS, ArrayRef<FPLibcallFamily> Families) const {
  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALL_FP_SELECTOR_DECLS");
  for (const FPLibcallFamily &Family : Families)
    OS << "LLVM_ABI Libcall get" << Family.Base << "(EVT VT);\n";
}

/// Generate the backend RTLIB::get<base>(EVT) selectors from the floating-point
/// libcall families.
void RuntimeLibcallEmitter::emitFPLibcallSelectors(
    raw_ostream &OS, ArrayRef<FPLibcallFamily> Families,
    const DenseSet<StringRef> &LibcallNames) const {
  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALL_FP_SELECTORS");

  // Only emit a libcall enumerator if it actually exists in the declared set.
  auto scalarEnum = [&](StringRef Base, StringRef Suffix) -> std::string {
    if (LibcallNames.contains((Base + "_" + Suffix).str()))
      return ("RTLIB::" + Base + "_" + Suffix).str();
    return "RTLIB::UNKNOWN_LIBCALL";
  };

  for (const FPLibcallFamily &Family : Families) {
    StringRef Base = Family.Base;
    OS << "RTLIB::Libcall llvm::RTLIB::get" << Base << "(EVT VT) {\n";

    if (!Family.VectorSuffixes.empty()) {
      OS << "  if (VT.isVector()) {\n"
            "    if (!VT.isSimple())\n"
            "      return RTLIB::UNKNOWN_LIBCALL;\n"
            "    switch (VT.getSimpleVT().SimpleTy) {\n";
      for (StringRef Suffix : Family.VectorSuffixes) {
        OS << "    case MVT::" << Suffix.lower()
           << ":\n      return RTLIB::" << Base << "_" << Suffix << ";\n";
      }
      OS << "    default:\n"
            "      return RTLIB::UNKNOWN_LIBCALL;\n"
            "    }\n"
            "  }\n";
    }

    OS << "  return getFPLibCall(VT";
    for (auto [Suffix, Pred] : ScalarFPSuffixes)
      OS << ", " << scalarEnum(Base, Suffix);
    OS << ");\n}\n\n";
  }
}

/// Emit the mapping from floating-point math intrinsics to the runtime libcall
/// they may lower to, keyed by intrinsic ID and floating-point type. This is
/// the IR-level counterpart to the backend's RTLIB::getXXX(EVT) selectors.
void RuntimeLibcallEmitter::emitGetLibcallForIntrinsic(
    raw_ostream &OS, ArrayRef<FPLibcallFamily> Families,
    const DenseSet<StringRef> &LibcallNames) const {
  IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALL_INTRINSIC_TO_LIBCALL");

  std::vector<std::pair<StringRef, StringRef>> IntrinsicToBase;
  for (const FPLibcallFamily &Family : Families)
    for (StringRef Intrinsic : Family.Intrinsics)
      IntrinsicToBase.emplace_back(Intrinsic, Family.Base);
  llvm::sort(IntrinsicToBase);

  MapVector<StringRef, SmallVector<StringRef, 2>> BaseToIntrinsics;
  for (auto [Intrinsic, Base] : IntrinsicToBase)
    BaseToIntrinsics[Base].push_back(Intrinsic);

  OS << "RTLIB::Libcall "
        "llvm::RTLIB::RuntimeLibcallsInfo::getLibcallForIntrinsic("
        "Intrinsic::ID ID, FunctionType *FTy) {\n"
        "  Type *Ty = FTy->getReturnType();\n"
        "  if (!Ty->isFloatingPointTy()) {\n"
        "    for (Type *ParamTy : FTy->params()) {\n"
        "      if (ParamTy->isFloatingPointTy()) {\n"
        "        Ty = ParamTy;\n"
        "        break;\n"
        "      }\n"
        "    }\n"
        "  }\n"
        "  if (!Ty->isFloatingPointTy())\n"
        "    return RTLIB::UNKNOWN_LIBCALL;\n"
        "  switch (ID) {\n";

  for (const auto &[Base, Intrinsics] : BaseToIntrinsics) {
    SmallVector<std::pair<StringRef, StringRef>, 5> Arms;
    for (auto [Suffix, Pred] : ScalarFPSuffixes)
      if (LibcallNames.contains((Base + "_" + Suffix).str()))
        Arms.emplace_back(Suffix, Pred);

    for (StringRef Intrinsic : Intrinsics)
      OS << "  case Intrinsic::" << Intrinsic << ":\n";
    for (auto [Suffix, Pred] : Arms)
      OS << "    if (Ty->" << Pred << ")\n      return RTLIB::" << Base << "_"
         << Suffix << ";\n";
    OS << "    return RTLIB::UNKNOWN_LIBCALL;\n";
  }

  OS << "  default:\n"
        "    return RTLIB::UNKNOWN_LIBCALL;\n"
        "  }\n"
        "}\n";
}

void RuntimeLibcallEmitter::run(raw_ostream &OS) {
  emitSourceFileHeader("Runtime LibCalls Source Fragment", OS, Records);
  emitGetRuntimeLibcallEnum(OS);

  emitGetInitRuntimeLibcallNames(OS);
  emitGetInitRuntimeLibcallSignatures(OS);
  emitMaskedVectorLibcallMapping(OS);

  emitRuntimeLibcallsInfoMemberDecls(OS);

  {
    IfDefEmitter IfDef(OS, "GET_RUNTIME_LIBCALLS_INFO");
    std::vector<SystemLibraryDispatch> Systems = collectSystemLibraryDispatch();
    emitSystemRuntimeLibrarySetCalls(OS, Systems);
    emitLibraryByNameSetCalls(OS, Systems);
  }

  std::vector<FPLibcallFamily> FPFamilies = collectFPLibcallFamilies(Records);
  DenseSet<StringRef> LibcallNames = collectLibcallNames();
  checkFPLibcallFamilies(FPFamilies, LibcallNames);
  emitFPLibcallSelectorDecls(OS, FPFamilies);
  emitFPLibcallSelectors(OS, FPFamilies, LibcallNames);
  emitGetLibcallForIntrinsic(OS, FPFamilies, LibcallNames);
}

static TableGen::Emitter::OptClass<RuntimeLibcallEmitter>
    X("gen-runtime-libcalls", "Generate RuntimeLibcalls");
