Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/VTEmitter.cpp
35258 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 <array>13#include <cassert>14#include <map>15using namespace llvm;1617namespace {1819class VTEmitter {20private:21RecordKeeper &Records;2223public:24VTEmitter(RecordKeeper &R) : Records(R) {}2526void run(raw_ostream &OS);27};2829} // End anonymous namespace.3031static void VTtoGetLLVMTyString(raw_ostream &OS, const Record *VT) {32bool IsVector = VT->getValueAsBit("isVector");33if (IsVector)34OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")35<< "VectorType::get(";3637auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;38int64_t OutputVTSize = OutputVT->getValueAsInt("Size");3940if (OutputVT->getValueAsBit("isFP")) {41StringRef FloatTy;42auto OutputVTName = OutputVT->getValueAsString("LLVMName");43switch (OutputVTSize) {44default:45llvm_unreachable("Unhandled case");46case 16:47FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy";48break;49case 32:50FloatTy = "FloatTy";51break;52case 64:53FloatTy = "DoubleTy";54break;55case 80:56FloatTy = "X86_FP80Ty";57break;58case 128:59FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";60break;61}62OS << "Type::get" << FloatTy << "(Context)";63} else if (OutputVT->getValueAsBit("isInteger")) {64// We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int12865if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&66OutputVTSize <= 128) ||67OutputVTSize == 1)68OS << "Type::getInt" << OutputVTSize << "Ty(Context)";69else70OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";71} else72llvm_unreachable("Unhandled case");7374if (IsVector)75OS << ", " << VT->getValueAsInt("nElem") << ")";76}7778void VTEmitter::run(raw_ostream &OS) {79emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);8081std::array<const Record *, 256> VTsByNumber = {};82auto ValueTypes = Records.getAllDerivedDefinitions("ValueType");83for (auto *VT : ValueTypes) {84auto Number = VT->getValueAsInt("Value");85assert(0 <= Number && Number < (int)VTsByNumber.size() &&86"ValueType should be uint8_t");87assert(!VTsByNumber[Number] && "Duplicate ValueType");88VTsByNumber[Number] = VT;89}9091struct VTRange {92StringRef First;93StringRef Last;94bool Closed;95};9697std::map<StringRef, VTRange> VTRanges;9899auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,100bool Valid) {101if (Valid) {102if (!VTRanges.count(Key))103VTRanges[Key].First = Name;104assert(!VTRanges[Key].Closed && "Gap detected!");105VTRanges[Key].Last = Name;106} else if (VTRanges.count(Key)) {107VTRanges[Key].Closed = true;108}109};110111OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n";112for (const auto *VT : VTsByNumber) {113if (!VT)114continue;115auto Name = VT->getValueAsString("LLVMName");116auto Value = VT->getValueAsInt("Value");117bool IsInteger = VT->getValueAsBit("isInteger");118bool IsFP = VT->getValueAsBit("isFP");119bool IsVector = VT->getValueAsBit("isVector");120bool IsScalable = VT->getValueAsBit("isScalable");121bool IsNormalValueType = VT->getValueAsBit("isNormalValueType");122int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;123StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()124: "INVALID_SIMPLE_VALUE_TYPE";125126UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,127IsInteger && IsVector && !IsScalable);128UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,129IsInteger && IsScalable);130UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,131IsFP && IsVector && !IsScalable);132UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);133UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);134UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);135UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);136UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);137UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);138UpdateVTRange("VALUETYPE", Name, IsNormalValueType);139140// clang-format off141OS << " GET_VT_ATTR("142<< Name << ", "143<< Value << ", "144<< VT->getValueAsInt("Size") << ", "145<< VT->getValueAsBit("isOverloaded") << ", "146<< (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "147<< (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "148<< IsVector << ", "149<< IsScalable << ", "150<< NElem << ", "151<< EltName << ")\n";152// clang-format on153}154OS << "#endif\n\n";155156OS << "#ifdef GET_VT_RANGES\n";157for (const auto &KV : VTRanges) {158assert(KV.second.Closed);159OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n"160<< " LAST_" << KV.first << " = " << KV.second.Last << ",\n";161}162OS << "#endif\n\n";163164OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy)\n";165for (const auto *VT : VTsByNumber) {166if (!VT || !VT->getValueAsBit("isVector"))167continue;168const auto *ElTy = VT->getValueAsDef("ElementType");169assert(ElTy);170// clang-format off171OS << " GET_VT_VECATTR("172<< VT->getValueAsString("LLVMName") << ", "173<< VT->getValueAsBit("isScalable") << ", "174<< VT->getValueAsInt("nElem") << ", "175<< ElTy->getName() << ")\n";176// clang-format on177}178OS << "#endif\n\n";179180OS << "#ifdef GET_VT_EVT\n";181for (const auto *VT : VTsByNumber) {182if (!VT)183continue;184bool IsInteger = VT->getValueAsBit("isInteger");185bool IsVector = VT->getValueAsBit("isVector");186bool IsFP = VT->getValueAsBit("isFP");187188if (!IsInteger && !IsVector && !IsFP)189continue;190191OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";192VTtoGetLLVMTyString(OS, VT);193OS << ")\n";194}195OS << "#endif\n\n";196}197198static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");199200201