diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:31:57 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:33:27 +0900 |
commit | df025ebf872052c0761d44a3ef9b65e9675af8a8 (patch) | |
tree | 9b4e94583e2536546d6606270bcdf846c95e1ba2 /llvm/utils/TableGen/Basic/VTEmitter.cpp | |
parent | 4428c9d0b1344179f85a72e183a44796976521e3 (diff) | |
parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
download | llvm-users/chapuni/cov/single/loop.zip llvm-users/chapuni/cov/single/loop.tar.gz llvm-users/chapuni/cov/single/loop.tar.bz2 |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/loopusers/chapuni/cov/single/loop
Conflicts:
clang/lib/CodeGen/CoverageMappingGen.cpp
Diffstat (limited to 'llvm/utils/TableGen/Basic/VTEmitter.cpp')
-rw-r--r-- | llvm/utils/TableGen/Basic/VTEmitter.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/Basic/VTEmitter.cpp b/llvm/utils/TableGen/Basic/VTEmitter.cpp new file mode 100644 index 0000000..d02932d --- /dev/null +++ b/llvm/utils/TableGen/Basic/VTEmitter.cpp @@ -0,0 +1,216 @@ +//===- VTEmitter.cpp - Generate properties from ValueTypes.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 "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <cassert> +#include <map> +using namespace llvm; + +namespace { + +class VTEmitter { +private: + const RecordKeeper &Records; + +public: + VTEmitter(const RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &OS); +}; + +} // End anonymous namespace. + +static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) { + bool IsVector = VT->getValueAsBit("isVector"); + bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple"); + + if (IsRISCVVecTuple) { + unsigned NElem = VT->getValueAsInt("nElem"); + unsigned Sz = VT->getValueAsInt("Size"); + OS << "TargetExtType::get(Context, \"riscv.vector.tuple\", " + "ScalableVectorType::get(Type::getInt8Ty(Context), " + << (Sz / (NElem * 8)) << "), " << NElem << ")"; + return; + } + + if (IsVector) + OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed") + << "VectorType::get("; + + auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT; + int64_t OutputVTSize = OutputVT->getValueAsInt("Size"); + + if (OutputVT->getValueAsBit("isFP")) { + StringRef FloatTy; + auto OutputVTName = OutputVT->getValueAsString("LLVMName"); + switch (OutputVTSize) { + default: + llvm_unreachable("Unhandled case"); + case 16: + FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy"; + break; + case 32: + FloatTy = "FloatTy"; + break; + case 64: + FloatTy = "DoubleTy"; + break; + case 80: + FloatTy = "X86_FP80Ty"; + break; + case 128: + FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty"; + break; + } + OS << "Type::get" << FloatTy << "(Context)"; + } else if (OutputVT->getValueAsBit("isInteger")) { + // We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int128 + if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 && + OutputVTSize <= 128) || + OutputVTSize == 1) + OS << "Type::getInt" << OutputVTSize << "Ty(Context)"; + else + OS << "Type::getIntNTy(Context, " << OutputVTSize << ")"; + } else + llvm_unreachable("Unhandled case"); + + if (IsVector) + OS << ", " << VT->getValueAsInt("nElem") << ")"; +} + +void VTEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("ValueTypes Source Fragment", OS, Records); + + std::vector<const Record *> VTsByNumber{512}; + for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) { + auto Number = VT->getValueAsInt("Value"); + assert(0 <= Number && Number < (int)VTsByNumber.size() && + "ValueType should be uint16_t"); + assert(!VTsByNumber[Number] && "Duplicate ValueType"); + VTsByNumber[Number] = VT; + } + + struct VTRange { + StringRef First; + StringRef Last; + bool Closed; + }; + + std::map<StringRef, VTRange> VTRanges; + + auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name, + bool Valid) { + if (Valid) { + if (!VTRanges.count(Key)) + VTRanges[Key].First = Name; + assert(!VTRanges[Key].Closed && "Gap detected!"); + VTRanges[Key].Last = Name; + } else if (VTRanges.count(Key)) { + VTRanges[Key].Closed = true; + } + }; + + OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, " + "NElem, EltTy)\n"; + for (const auto *VT : VTsByNumber) { + if (!VT) + continue; + auto Name = VT->getValueAsString("LLVMName"); + auto Value = VT->getValueAsInt("Value"); + bool IsInteger = VT->getValueAsBit("isInteger"); + bool IsFP = VT->getValueAsBit("isFP"); + bool IsVector = VT->getValueAsBit("isVector"); + bool IsScalable = VT->getValueAsBit("isScalable"); + bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple"); + int64_t NF = VT->getValueAsInt("NF"); + bool IsNormalValueType = VT->getValueAsBit("isNormalValueType"); + int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0; + StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName() + : "INVALID_SIMPLE_VALUE_TYPE"; + + UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name, + IsInteger && IsVector && !IsScalable); + UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name, + IsInteger && IsScalable); + UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name, + IsFP && IsVector && !IsScalable); + UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable); + UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable); + UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable); + UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple); + UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector); + UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector); + UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector); + UpdateVTRange("VALUETYPE", Name, IsNormalValueType); + + // clang-format off + OS << " GET_VT_ATTR(" + << Name << ", " + << Value << ", " + << VT->getValueAsInt("Size") << ", " + << VT->getValueAsBit("isOverloaded") << ", " + << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", " + << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", " + << IsVector << ", " + << IsScalable << ", " + << IsRISCVVecTuple << ", " + << NF << ", " + << NElem << ", " + << EltName << ")\n"; + // clang-format on + } + OS << "#endif\n\n"; + + OS << "#ifdef GET_VT_RANGES\n"; + for (const auto &KV : VTRanges) { + assert(KV.second.Closed); + OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n" + << " LAST_" << KV.first << " = " << KV.second.Last << ",\n"; + } + OS << "#endif\n\n"; + + OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n"; + for (const auto *VT : VTsByNumber) { + if (!VT || !VT->getValueAsBit("isVector")) + continue; + const auto *ElTy = VT->getValueAsDef("ElementType"); + assert(ElTy); + // clang-format off + OS << " GET_VT_VECATTR(" + << VT->getValueAsString("LLVMName") << ", " + << VT->getValueAsBit("isScalable") << ", " + << VT->getValueAsBit("isRISCVVecTuple") << ", " + << VT->getValueAsInt("nElem") << ", " + << ElTy->getName() << ")\n"; + // clang-format on + } + OS << "#endif\n\n"; + + OS << "#ifdef GET_VT_EVT\n"; + for (const auto *VT : VTsByNumber) { + if (!VT) + continue; + bool IsInteger = VT->getValueAsBit("isInteger"); + bool IsVector = VT->getValueAsBit("isVector"); + bool IsFP = VT->getValueAsBit("isFP"); + bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple"); + + if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple) + continue; + + OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", "; + vTtoGetLlvmTyString(OS, VT); + OS << ")\n"; + } + OS << "#endif\n\n"; +} + +static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType"); |