//===- TargetLibraryInfoEmitter.cpp - Properties from TargetLibraryInfo.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
//
//===----------------------------------------------------------------------===//

#include "SequenceToOffsetTable.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.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"
#include <cstddef>

#define DEBUG_TYPE "target-library-info-emitter"

using namespace llvm;

namespace {
class TargetLibraryInfoEmitter {
private:
  const RecordKeeper &Records;
  SmallVector<const Record *, 1024> AllTargetLibcalls;

private:
  void emitTargetLibraryInfoEnum(raw_ostream &OS) const;
  void emitTargetLibraryInfoStringTable(raw_ostream &OS) const;
  void emitTargetLibraryInfoSignatureTable(raw_ostream &OS) const;

public:
  TargetLibraryInfoEmitter(const RecordKeeper &R);

  void run(raw_ostream &OS);
};

} // End anonymous namespace.

TargetLibraryInfoEmitter::TargetLibraryInfoEmitter(const RecordKeeper &R)
    : Records(R) {
  ArrayRef<const Record *> All =
      Records.getAllDerivedDefinitions("TargetLibCall");
  AllTargetLibcalls.append(All.begin(), All.end());
  // Make sure that the records are in the same order as the input.
  // TODO Find a better sorting order when all is migrated.
  sort(AllTargetLibcalls, [](const Record *A, const Record *B) {
    return A->getID() < B->getID();
  });
}

// Emits the LibFunc enumeration, which is an abstract name for each library
// function.
void TargetLibraryInfoEmitter::emitTargetLibraryInfoEnum(
    raw_ostream &OS) const {
  IfDefEmitter IfDef(OS, "GET_TARGET_LIBRARY_INFO_ENUM");
  OS << "enum LibFunc : unsigned {\n";
  OS.indent(2) << "NotLibFunc = 0,\n";
  for (const auto *R : AllTargetLibcalls)
    OS.indent(2) << "LibFunc_" << R->getName() << ",\n";
  OS.indent(2) << "NumLibFuncs,\n";
  OS.indent(2) << "End_LibFunc = NumLibFuncs,\n";
  if (AllTargetLibcalls.size()) {
    OS.indent(2) << "Begin_LibFunc = LibFunc_"
                 << AllTargetLibcalls[0]->getName() << ",\n";
  } else {
    OS.indent(2) << "Begin_LibFunc = NotLibFunc,\n";
  }
  OS << "};\n";
}

// The names of the functions are stored in a long string, along with support
// tables for accessing the offsets of the function names from the beginning of
// the string.
void TargetLibraryInfoEmitter::emitTargetLibraryInfoStringTable(
    raw_ostream &OS) const {
  llvm::StringToOffsetTable Table(
      /*AppendZero=*/true,
      "TargetLibraryInfoImpl::", /*UsePrefixForStorageMember=*/false);
  for (const auto *R : AllTargetLibcalls)
    Table.GetOrAddStringOffset(R->getValueAsString("String"));

  size_t NumEl = AllTargetLibcalls.size() + 1;

  {
    IfDefEmitter IfDef(OS, "GET_TARGET_LIBRARY_INFO_STRING_TABLE");
    Table.EmitStringTableDef(OS, "StandardNamesStrTable");
    OS << "\n";
    OS << "const llvm::StringTable::Offset "
          "TargetLibraryInfoImpl::StandardNamesOffsets["
       << NumEl
       << "] = "
          "{\n";
    OS.indent(2) << "0, //\n";
    for (const auto *R : AllTargetLibcalls) {
      StringRef Str = R->getValueAsString("String");
      OS.indent(2) << Table.GetStringOffset(Str) << ", // " << Str << "\n";
    }
    OS << "};\n";
    OS << "const uint8_t TargetLibraryInfoImpl::StandardNamesSizeTable["
       << NumEl << "] = {\n";
    OS << "  0,\n";
    for (const auto *R : AllTargetLibcalls)
      OS.indent(2) << R->getValueAsString("String").size() << ",\n";
    OS << "};\n";
  }

  IfDefEmitter IfDef(OS, "GET_TARGET_LIBRARY_INFO_IMPL_DECL");
  OS << "LLVM_ABI static const llvm::StringTable StandardNamesStrTable;\n";
  OS << "LLVM_ABI static const llvm::StringTable::Offset StandardNamesOffsets["
     << NumEl << "];\n";
  OS << "LLVM_ABI static const uint8_t StandardNamesSizeTable[" << NumEl
     << "];\n";
}

// Since there are much less type signatures then library functions, the type
// signatures are stored reusing existing entries. To access a table entry, an
// offset table is used.
void TargetLibraryInfoEmitter::emitTargetLibraryInfoSignatureTable(
    raw_ostream &OS) const {
  SmallVector<const Record *, 1024> FuncTypeArgs(
      Records.getAllDerivedDefinitions("FuncArgType"));

  // Sort the records by ID.
  sort(FuncTypeArgs, [](const Record *A, const Record *B) {
    return A->getID() < B->getID();
  });

  using Signature = std::vector<StringRef>;
  SequenceToOffsetTable<Signature> SignatureTable("NoFuncArgType");
  auto GetSignature = [](const Record *R) -> Signature {
    const auto *Tys = R->getValueAsListInit("ArgumentTypes");
    Signature Sig;
    Sig.reserve(Tys->size() + 1);
    const Record *RetType = R->getValueAsOptionalDef("ReturnType");
    if (RetType)
      Sig.push_back(RetType->getName());
    for (unsigned I = 0, E = Tys->size(); I < E; ++I) {
      Sig.push_back(Tys->getElementAsRecord(I)->getName());
    }
    return Sig;
  };
  Signature NoFuncSig({StringRef("Void")});
  SignatureTable.add(NoFuncSig);
  for (const auto *R : AllTargetLibcalls)
    SignatureTable.add(GetSignature(R));
  SignatureTable.layout();

  IfDefEmitter IfDef(OS, "GET_TARGET_LIBRARY_INFO_SIGNATURE_TABLE");
  OS << "enum FuncArgTypeID : char {\n";
  OS.indent(2) << "NoFuncArgType = 0,\n";
  for (const auto *R : FuncTypeArgs)
    OS.indent(2) << R->getName() << ",\n";
  OS << "};\n";
  OS << "static const FuncArgTypeID SignatureTable[] = {\n";
  SignatureTable.emit(OS, [](raw_ostream &OS, StringRef E) { OS << E; });
  OS << "};\n";
  OS << "static const uint16_t SignatureOffset[] = {\n";
  OS.indent(2) << SignatureTable.get(NoFuncSig) << ", //\n";
  for (const auto *R : AllTargetLibcalls) {
    OS.indent(2) << SignatureTable.get(GetSignature(R)) << ", // "
                 << R->getName() << "\n";
  }
  OS << "};\n";
}

void TargetLibraryInfoEmitter::run(raw_ostream &OS) {
  emitSourceFileHeader("Target Library Info Source Fragment", OS, Records);

  emitTargetLibraryInfoEnum(OS);
  emitTargetLibraryInfoStringTable(OS);
  emitTargetLibraryInfoSignatureTable(OS);
}

static TableGen::Emitter::OptClass<TargetLibraryInfoEmitter>
    X("gen-target-library-info", "Generate TargetLibraryInfo");
