brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 253d9df Raw
186 lines · cpp
1//===- TargetLibraryInfoEmitter.cpp - Properties from TargetLibraryInfo.td ===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SequenceToOffsetTable.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/Support/Debug.h"12#include "llvm/Support/raw_ostream.h"13#include "llvm/TableGen/Error.h"14#include "llvm/TableGen/Record.h"15#include "llvm/TableGen/SetTheory.h"16#include "llvm/TableGen/StringToOffsetTable.h"17#include "llvm/TableGen/TableGenBackend.h"18#include <cstddef>19 20#define DEBUG_TYPE "target-library-info-emitter"21 22using namespace llvm;23 24namespace {25class TargetLibraryInfoEmitter {26private:27  const RecordKeeper &Records;28  SmallVector<const Record *, 1024> AllTargetLibcalls;29 30private:31  void emitTargetLibraryInfoEnum(raw_ostream &OS) const;32  void emitTargetLibraryInfoStringTable(raw_ostream &OS) const;33  void emitTargetLibraryInfoSignatureTable(raw_ostream &OS) const;34 35public:36  TargetLibraryInfoEmitter(const RecordKeeper &R);37 38  void run(raw_ostream &OS);39};40 41} // End anonymous namespace.42 43TargetLibraryInfoEmitter::TargetLibraryInfoEmitter(const RecordKeeper &R)44    : Records(R) {45  ArrayRef<const Record *> All =46      Records.getAllDerivedDefinitions("TargetLibCall");47  AllTargetLibcalls.append(All.begin(), All.end());48  // Make sure that the records are in the same order as the input.49  // TODO Find a better sorting order when all is migrated.50  sort(AllTargetLibcalls, [](const Record *A, const Record *B) {51    return A->getID() < B->getID();52  });53}54 55// Emits the LibFunc enumeration, which is an abstract name for each library56// function.57void TargetLibraryInfoEmitter::emitTargetLibraryInfoEnum(58    raw_ostream &OS) const {59  OS << "#ifdef GET_TARGET_LIBRARY_INFO_ENUM\n";60  OS << "#undef GET_TARGET_LIBRARY_INFO_ENUM\n";61  OS << "enum LibFunc : unsigned {\n";62  OS.indent(2) << "NotLibFunc = 0,\n";63  for (const auto *R : AllTargetLibcalls) {64    OS.indent(2) << "LibFunc_" << R->getName() << ",\n";65  }66  OS.indent(2) << "NumLibFuncs,\n";67  OS.indent(2) << "End_LibFunc = NumLibFuncs,\n";68  if (AllTargetLibcalls.size()) {69    OS.indent(2) << "Begin_LibFunc = LibFunc_"70                 << AllTargetLibcalls[0]->getName() << ",\n";71  } else {72    OS.indent(2) << "Begin_LibFunc = NotLibFunc,\n";73  }74  OS << "};\n";75  OS << "#endif\n\n";76}77 78// The names of the functions are stored in a long string, along with support79// tables for accessing the offsets of the function names from the beginning of80// the string.81void TargetLibraryInfoEmitter::emitTargetLibraryInfoStringTable(82    raw_ostream &OS) const {83  llvm::StringToOffsetTable Table(84      /*AppendZero=*/true,85      "TargetLibraryInfoImpl::", /*UsePrefixForStorageMember=*/false);86  for (const auto *R : AllTargetLibcalls)87    Table.GetOrAddStringOffset(R->getValueAsString("String"));88 89  OS << "#ifdef GET_TARGET_LIBRARY_INFO_STRING_TABLE\n";90  OS << "#undef GET_TARGET_LIBRARY_INFO_STRING_TABLE\n";91  Table.EmitStringTableDef(OS, "StandardNamesStrTable");92  OS << "\n";93  size_t NumEl = AllTargetLibcalls.size() + 1;94  OS << "const llvm::StringTable::Offset "95        "TargetLibraryInfoImpl::StandardNamesOffsets["96     << NumEl97     << "] = "98        "{\n";99  OS.indent(2) << "0, //\n";100  for (const auto *R : AllTargetLibcalls) {101    StringRef Str = R->getValueAsString("String");102    OS.indent(2) << Table.GetStringOffset(Str) << ", // " << Str << "\n";103  }104  OS << "};\n";105  OS << "const uint8_t TargetLibraryInfoImpl::StandardNamesSizeTable[" << NumEl106     << "] = {\n";107  OS << "  0,\n";108  for (const auto *R : AllTargetLibcalls)109    OS.indent(2) << R->getValueAsString("String").size() << ",\n";110  OS << "};\n";111  OS << "#endif\n\n";112  OS << "#ifdef GET_TARGET_LIBRARY_INFO_IMPL_DECL\n";113  OS << "#undef GET_TARGET_LIBRARY_INFO_IMPL_DECL\n";114  OS << "LLVM_ABI static const llvm::StringTable StandardNamesStrTable;\n";115  OS << "LLVM_ABI static const llvm::StringTable::Offset StandardNamesOffsets["116     << NumEl << "];\n";117  OS << "LLVM_ABI static const uint8_t StandardNamesSizeTable[" << NumEl118     << "];\n";119  OS << "#endif\n\n";120}121 122// Since there are much less type signatures then library functions, the type123// signatures are stored reusing existing entries. To access a table entry, an124// offset table is used.125void TargetLibraryInfoEmitter::emitTargetLibraryInfoSignatureTable(126    raw_ostream &OS) const {127  SmallVector<const Record *, 1024> FuncTypeArgs(128      Records.getAllDerivedDefinitions("FuncArgType"));129 130  // Sort the records by ID.131  sort(FuncTypeArgs, [](const Record *A, const Record *B) {132    return A->getID() < B->getID();133  });134 135  using Signature = std::vector<StringRef>;136  SequenceToOffsetTable<Signature> SignatureTable("NoFuncArgType");137  auto GetSignature = [](const Record *R) -> Signature {138    const auto *Tys = R->getValueAsListInit("ArgumentTypes");139    Signature Sig;140    Sig.reserve(Tys->size() + 1);141    const Record *RetType = R->getValueAsOptionalDef("ReturnType");142    if (RetType)143      Sig.push_back(RetType->getName());144    for (unsigned I = 0, E = Tys->size(); I < E; ++I) {145      Sig.push_back(Tys->getElementAsRecord(I)->getName());146    }147    return Sig;148  };149  Signature NoFuncSig({StringRef("Void")});150  SignatureTable.add(NoFuncSig);151  for (const auto *R : AllTargetLibcalls)152    SignatureTable.add(GetSignature(R));153  SignatureTable.layout();154 155  OS << "#ifdef GET_TARGET_LIBRARY_INFO_SIGNATURE_TABLE\n";156  OS << "#undef GET_TARGET_LIBRARY_INFO_SIGNATURE_TABLE\n";157  OS << "enum FuncArgTypeID : char {\n";158  OS.indent(2) << "NoFuncArgType = 0,\n";159  for (const auto *R : FuncTypeArgs) {160    OS.indent(2) << R->getName() << ",\n";161  }162  OS << "};\n";163  OS << "static const FuncArgTypeID SignatureTable[] = {\n";164  SignatureTable.emit(OS, [](raw_ostream &OS, StringRef E) { OS << E; });165  OS << "};\n";166  OS << "static const uint16_t SignatureOffset[] = {\n";167  OS.indent(2) << SignatureTable.get(NoFuncSig) << ", //\n";168  for (const auto *R : AllTargetLibcalls) {169    OS.indent(2) << SignatureTable.get(GetSignature(R)) << ", // "170                 << R->getName() << "\n";171  }172  OS << "};\n";173  OS << "#endif\n\n";174}175 176void TargetLibraryInfoEmitter::run(raw_ostream &OS) {177  emitSourceFileHeader("Target Library Info Source Fragment", OS, Records);178 179  emitTargetLibraryInfoEnum(OS);180  emitTargetLibraryInfoStringTable(OS);181  emitTargetLibraryInfoSignatureTable(OS);182}183 184static TableGen::Emitter::OptClass<TargetLibraryInfoEmitter>185    X("gen-target-library-info", "Generate TargetLibraryInfo");186