brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 87f5f4b Raw
222 lines · cpp
1//===- VTEmitter.cpp - Generate properties from ValueTypes.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 "llvm/ADT/StringRef.h"10#include "llvm/Support/raw_ostream.h"11#include "llvm/TableGen/Record.h"12#include "llvm/TableGen/TableGenBackend.h"13#include <cassert>14#include <map>15using namespace llvm;16 17namespace {18 19class VTEmitter {20private:21  const RecordKeeper &Records;22 23public:24  VTEmitter(const RecordKeeper &R) : Records(R) {}25 26  void run(raw_ostream &OS);27};28 29} // End anonymous namespace.30 31static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) {32  bool IsVector = VT->getValueAsBit("isVector");33  bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");34 35  if (IsRISCVVecTuple) {36    unsigned NF = VT->getValueAsInt("NF");37    unsigned Sz = VT->getValueAsInt("Size");38    OS << "TargetExtType::get(Context, \"riscv.vector.tuple\", "39          "ScalableVectorType::get(Type::getInt8Ty(Context), "40       << (Sz / (NF * 8)) << "), " << NF << ")";41    return;42  }43 44  if (IsVector)45    OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")46       << "VectorType::get(";47 48  auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;49  int64_t OutputVTSize = OutputVT->getValueAsInt("Size");50 51  if (OutputVT->getValueAsBit("isFP")) {52    StringRef FloatTy;53    auto OutputVTName = OutputVT->getValueAsString("LLVMName");54    switch (OutputVTSize) {55    default:56      llvm_unreachable("Unhandled case");57    case 16:58      FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy";59      break;60    case 32:61      FloatTy = "FloatTy";62      break;63    case 64:64      FloatTy = "DoubleTy";65      break;66    case 80:67      FloatTy = "X86_FP80Ty";68      break;69    case 128:70      FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";71      break;72    }73    OS << "Type::get" << FloatTy << "(Context)";74  } else if (OutputVT->getValueAsBit("isInteger")) {75    // We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int12876    if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&77         OutputVTSize <= 128) ||78        OutputVTSize == 1)79      OS << "Type::getInt" << OutputVTSize << "Ty(Context)";80    else81      OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";82  } else {83    llvm_unreachable("Unhandled case");84  }85 86  if (IsVector)87    OS << ", " << VT->getValueAsInt("nElem") << ")";88}89 90void VTEmitter::run(raw_ostream &OS) {91  emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);92 93  std::vector<const Record *> VTsByNumber{512};94  unsigned Number = 0;95  std::vector<const Record *> Defs(96      Records.getAllDerivedDefinitions("ValueType"));97  // Emit VTs in the order they were declared so that VTRanges stay contiguous.98  llvm::sort(Defs, LessRecordByID());99  for (auto *VT : Defs) {100    ++Number;101    assert(Number < VTsByNumber.size() && "ValueType should be uint16_t");102    VTsByNumber[Number] = VT;103  }104 105  struct VTRange {106    StringRef First;107    StringRef Last;108    bool Closed;109  };110 111  std::map<StringRef, VTRange> VTRanges;112 113  auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,114                                   bool Valid) {115    if (Valid) {116      auto [It, Inserted] = VTRanges.try_emplace(Key);117      if (Inserted)118        It->second.First = Name;119      assert(!It->second.Closed && "Gap detected!");120      It->second.Last = Name;121    } else if (auto It = VTRanges.find(Key); It != VTRanges.end()) {122      It->second.Closed = true;123    }124  };125 126  OS << "#ifdef GET_VT_ATTR // (Ty, sz, Any, Int, FP, Vec, Sc, Tup, NF, "127        "NElem, EltTy)\n";128  for (const auto *VT : VTsByNumber) {129    if (!VT)130      continue;131    auto Name = VT->getValueAsString("LLVMName");132    bool IsInteger = VT->getValueAsBit("isInteger");133    bool IsFP = VT->getValueAsBit("isFP");134    bool IsVector = VT->getValueAsBit("isVector");135    bool IsScalable = VT->getValueAsBit("isScalable");136    bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");137    bool IsCheriCapability = VT->getValueAsBit("isCheriCapability");138    int64_t NF = VT->getValueAsInt("NF");139    bool IsNormalValueType =  VT->getValueAsBit("isNormalValueType");140    int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;141    StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()142                                 : "INVALID_SIMPLE_VALUE_TYPE";143 144    UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,145                  IsInteger && IsVector && !IsScalable);146    UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,147                  IsInteger && IsScalable);148    UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,149                  IsFP && IsVector && !IsScalable);150    UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);151    UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);152    UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);153    UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple);154    UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);155    UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);156    UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);157    UpdateVTRange("VALUETYPE", Name, IsNormalValueType);158    UpdateVTRange("CHERI_CAPABILITY_VALUETYPE", Name, IsCheriCapability);159 160    // clang-format off161    OS << "  GET_VT_ATTR("162       << Name << ", "163       << VT->getValueAsInt("Size") << ", "164       << VT->getValueAsBit("isOverloaded") << ", "165       << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "166       << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "167       << IsVector << ", "168       << IsScalable << ", "169       << IsRISCVVecTuple << ", "170       << NF << ", "171       << NElem << ", "172       << EltName << ")\n";173    // clang-format on174  }175  OS << "#endif\n\n";176 177  OS << "#ifdef GET_VT_RANGES\n";178  for (const auto &KV : VTRanges) {179    assert(KV.second.Closed);180    OS << "  FIRST_" << KV.first << " = " << KV.second.First << ",\n"181       << "  LAST_" << KV.first << " = " << KV.second.Last << ",\n";182  }183  OS << "#endif\n\n";184 185  OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";186  for (const auto *VT : VTsByNumber) {187    if (!VT || !VT->getValueAsBit("isVector"))188      continue;189    const auto *ElTy = VT->getValueAsDef("ElementType");190    assert(ElTy);191    // clang-format off192    OS << "  GET_VT_VECATTR("193       << VT->getValueAsString("LLVMName") << ", "194       << VT->getValueAsBit("isScalable") << ", "195       << VT->getValueAsBit("isRISCVVecTuple") << ", "196       << VT->getValueAsInt("nElem") << ", "197       << ElTy->getName() << ")\n";198    // clang-format on199  }200  OS << "#endif\n\n";201 202  OS << "#ifdef GET_VT_EVT\n";203  for (const auto *VT : VTsByNumber) {204    if (!VT)205      continue;206    bool IsInteger = VT->getValueAsBit("isInteger");207    bool IsVector = VT->getValueAsBit("isVector");208    bool IsFP = VT->getValueAsBit("isFP");209    bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");210 211    if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple)212      continue;213 214    OS << "  GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";215    vTtoGetLlvmTyString(OS, VT);216    OS << ")\n";217  }218  OS << "#endif\n\n";219}220 221static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");222