aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/Basic/VTEmitter.cpp
diff options
context:
space:
mode:
authorNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 18:31:57 +0900
committerNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 18:33:27 +0900
commitdf025ebf872052c0761d44a3ef9b65e9675af8a8 (patch)
tree9b4e94583e2536546d6606270bcdf846c95e1ba2 /llvm/utils/TableGen/Basic/VTEmitter.cpp
parent4428c9d0b1344179f85a72e183a44796976521e3 (diff)
parentbdcf47e4bcb92889665825654bb80a8bbe30379e (diff)
downloadllvm-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.cpp216
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");