Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Basic/VTEmitter.cpp
213799 views
//===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/ADT/StringRef.h"9#include "llvm/Support/raw_ostream.h"10#include "llvm/TableGen/Record.h"11#include "llvm/TableGen/TableGenBackend.h"12#include <cassert>13#include <map>14using namespace llvm;1516namespace {1718class VTEmitter {19private:20const RecordKeeper &Records;2122public:23VTEmitter(const RecordKeeper &R) : Records(R) {}2425void run(raw_ostream &OS);26};2728} // End anonymous namespace.2930static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) {31bool IsVector = VT->getValueAsBit("isVector");32bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");3334if (IsRISCVVecTuple) {35unsigned NElem = VT->getValueAsInt("nElem");36unsigned Sz = VT->getValueAsInt("Size");37OS << "TargetExtType::get(Context, \"riscv.vector.tuple\", "38"ScalableVectorType::get(Type::getInt8Ty(Context), "39<< (Sz / (NElem * 8)) << "), " << NElem << ")";40return;41}4243if (IsVector)44OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")45<< "VectorType::get(";4647auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;48int64_t OutputVTSize = OutputVT->getValueAsInt("Size");4950if (OutputVT->getValueAsBit("isFP")) {51StringRef FloatTy;52auto OutputVTName = OutputVT->getValueAsString("LLVMName");53switch (OutputVTSize) {54default:55llvm_unreachable("Unhandled case");56case 16:57FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy";58break;59case 32:60FloatTy = "FloatTy";61break;62case 64:63FloatTy = "DoubleTy";64break;65case 80:66FloatTy = "X86_FP80Ty";67break;68case 128:69FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";70break;71}72OS << "Type::get" << FloatTy << "(Context)";73} else if (OutputVT->getValueAsBit("isInteger")) {74// We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int12875if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&76OutputVTSize <= 128) ||77OutputVTSize == 1)78OS << "Type::getInt" << OutputVTSize << "Ty(Context)";79else80OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";81} else {82llvm_unreachable("Unhandled case");83}8485if (IsVector)86OS << ", " << VT->getValueAsInt("nElem") << ")";87}8889void VTEmitter::run(raw_ostream &OS) {90emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);9192std::vector<const Record *> VTsByNumber{512};93for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) {94auto Number = VT->getValueAsInt("Value");95assert(0 <= Number && Number < (int)VTsByNumber.size() &&96"ValueType should be uint16_t");97assert(!VTsByNumber[Number] && "Duplicate ValueType");98VTsByNumber[Number] = VT;99}100101struct VTRange {102StringRef First;103StringRef Last;104bool Closed;105};106107std::map<StringRef, VTRange> VTRanges;108109auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,110bool Valid) {111if (Valid) {112auto [It, Inserted] = VTRanges.try_emplace(Key);113if (Inserted)114It->second.First = Name;115assert(!It->second.Closed && "Gap detected!");116It->second.Last = Name;117} else if (auto It = VTRanges.find(Key); It != VTRanges.end()) {118It->second.Closed = true;119}120};121122OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, "123"NElem, EltTy)\n";124for (const auto *VT : VTsByNumber) {125if (!VT)126continue;127auto Name = VT->getValueAsString("LLVMName");128auto Value = VT->getValueAsInt("Value");129bool IsInteger = VT->getValueAsBit("isInteger");130bool IsFP = VT->getValueAsBit("isFP");131bool IsVector = VT->getValueAsBit("isVector");132bool IsScalable = VT->getValueAsBit("isScalable");133bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");134int64_t NF = VT->getValueAsInt("NF");135bool IsNormalValueType = VT->getValueAsBit("isNormalValueType");136int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;137StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()138: "INVALID_SIMPLE_VALUE_TYPE";139140UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,141IsInteger && IsVector && !IsScalable);142UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,143IsInteger && IsScalable);144UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,145IsFP && IsVector && !IsScalable);146UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);147UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);148UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);149UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple);150UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);151UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);152UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);153UpdateVTRange("VALUETYPE", Name, IsNormalValueType);154155// clang-format off156OS << " GET_VT_ATTR("157<< Name << ", "158<< Value << ", "159<< VT->getValueAsInt("Size") << ", "160<< VT->getValueAsBit("isOverloaded") << ", "161<< (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "162<< (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "163<< IsVector << ", "164<< IsScalable << ", "165<< IsRISCVVecTuple << ", "166<< NF << ", "167<< NElem << ", "168<< EltName << ")\n";169// clang-format on170}171OS << "#endif\n\n";172173OS << "#ifdef GET_VT_RANGES\n";174for (const auto &KV : VTRanges) {175assert(KV.second.Closed);176OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n"177<< " LAST_" << KV.first << " = " << KV.second.Last << ",\n";178}179OS << "#endif\n\n";180181OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";182for (const auto *VT : VTsByNumber) {183if (!VT || !VT->getValueAsBit("isVector"))184continue;185const auto *ElTy = VT->getValueAsDef("ElementType");186assert(ElTy);187// clang-format off188OS << " GET_VT_VECATTR("189<< VT->getValueAsString("LLVMName") << ", "190<< VT->getValueAsBit("isScalable") << ", "191<< VT->getValueAsBit("isRISCVVecTuple") << ", "192<< VT->getValueAsInt("nElem") << ", "193<< ElTy->getName() << ")\n";194// clang-format on195}196OS << "#endif\n\n";197198OS << "#ifdef GET_VT_EVT\n";199for (const auto *VT : VTsByNumber) {200if (!VT)201continue;202bool IsInteger = VT->getValueAsBit("isInteger");203bool IsVector = VT->getValueAsBit("isVector");204bool IsFP = VT->getValueAsBit("isFP");205bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");206207if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple)208continue;209210OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";211vTtoGetLlvmTyString(OS, VT);212OS << ")\n";213}214OS << "#endif\n\n";215}216217static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");218219220