[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / utils / TableGen / VTEmitter.cpp
blobd02932dd5e7fca531a1a3b7962e52af7e8feb5e0
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-exception
6 //
7 //===----------------------------------------------------------------------===//
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>
15 using namespace llvm;
17 namespace {
19 class VTEmitter {
20 private:
21 const RecordKeeper &Records;
23 public:
24 VTEmitter(const RecordKeeper &R) : Records(R) {}
26 void run(raw_ostream &OS);
29 } // End anonymous namespace.
31 static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) {
32 bool IsVector = VT->getValueAsBit("isVector");
33 bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
35 if (IsRISCVVecTuple) {
36 unsigned NElem = VT->getValueAsInt("nElem");
37 unsigned Sz = VT->getValueAsInt("Size");
38 OS << "TargetExtType::get(Context, \"riscv.vector.tuple\", "
39 "ScalableVectorType::get(Type::getInt8Ty(Context), "
40 << (Sz / (NElem * 8)) << "), " << NElem << ")";
41 return;
44 if (IsVector)
45 OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")
46 << "VectorType::get(";
48 auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;
49 int64_t OutputVTSize = OutputVT->getValueAsInt("Size");
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;
73 OS << "Type::get" << FloatTy << "(Context)";
74 } else if (OutputVT->getValueAsBit("isInteger")) {
75 // We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int128
76 if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&
77 OutputVTSize <= 128) ||
78 OutputVTSize == 1)
79 OS << "Type::getInt" << OutputVTSize << "Ty(Context)";
80 else
81 OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";
82 } else
83 llvm_unreachable("Unhandled case");
85 if (IsVector)
86 OS << ", " << VT->getValueAsInt("nElem") << ")";
89 void VTEmitter::run(raw_ostream &OS) {
90 emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);
92 std::vector<const Record *> VTsByNumber{512};
93 for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) {
94 auto Number = VT->getValueAsInt("Value");
95 assert(0 <= Number && Number < (int)VTsByNumber.size() &&
96 "ValueType should be uint16_t");
97 assert(!VTsByNumber[Number] && "Duplicate ValueType");
98 VTsByNumber[Number] = VT;
101 struct VTRange {
102 StringRef First;
103 StringRef Last;
104 bool Closed;
107 std::map<StringRef, VTRange> VTRanges;
109 auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,
110 bool Valid) {
111 if (Valid) {
112 if (!VTRanges.count(Key))
113 VTRanges[Key].First = Name;
114 assert(!VTRanges[Key].Closed && "Gap detected!");
115 VTRanges[Key].Last = Name;
116 } else if (VTRanges.count(Key)) {
117 VTRanges[Key].Closed = true;
121 OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, "
122 "NElem, EltTy)\n";
123 for (const auto *VT : VTsByNumber) {
124 if (!VT)
125 continue;
126 auto Name = VT->getValueAsString("LLVMName");
127 auto Value = VT->getValueAsInt("Value");
128 bool IsInteger = VT->getValueAsBit("isInteger");
129 bool IsFP = VT->getValueAsBit("isFP");
130 bool IsVector = VT->getValueAsBit("isVector");
131 bool IsScalable = VT->getValueAsBit("isScalable");
132 bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
133 int64_t NF = VT->getValueAsInt("NF");
134 bool IsNormalValueType = VT->getValueAsBit("isNormalValueType");
135 int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;
136 StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()
137 : "INVALID_SIMPLE_VALUE_TYPE";
139 UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,
140 IsInteger && IsVector && !IsScalable);
141 UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,
142 IsInteger && IsScalable);
143 UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,
144 IsFP && IsVector && !IsScalable);
145 UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);
146 UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);
147 UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);
148 UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple);
149 UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);
150 UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);
151 UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);
152 UpdateVTRange("VALUETYPE", Name, IsNormalValueType);
154 // clang-format off
155 OS << " GET_VT_ATTR("
156 << Name << ", "
157 << Value << ", "
158 << VT->getValueAsInt("Size") << ", "
159 << VT->getValueAsBit("isOverloaded") << ", "
160 << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "
161 << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "
162 << IsVector << ", "
163 << IsScalable << ", "
164 << IsRISCVVecTuple << ", "
165 << NF << ", "
166 << NElem << ", "
167 << EltName << ")\n";
168 // clang-format on
170 OS << "#endif\n\n";
172 OS << "#ifdef GET_VT_RANGES\n";
173 for (const auto &KV : VTRanges) {
174 assert(KV.second.Closed);
175 OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n"
176 << " LAST_" << KV.first << " = " << KV.second.Last << ",\n";
178 OS << "#endif\n\n";
180 OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";
181 for (const auto *VT : VTsByNumber) {
182 if (!VT || !VT->getValueAsBit("isVector"))
183 continue;
184 const auto *ElTy = VT->getValueAsDef("ElementType");
185 assert(ElTy);
186 // clang-format off
187 OS << " GET_VT_VECATTR("
188 << VT->getValueAsString("LLVMName") << ", "
189 << VT->getValueAsBit("isScalable") << ", "
190 << VT->getValueAsBit("isRISCVVecTuple") << ", "
191 << VT->getValueAsInt("nElem") << ", "
192 << ElTy->getName() << ")\n";
193 // clang-format on
195 OS << "#endif\n\n";
197 OS << "#ifdef GET_VT_EVT\n";
198 for (const auto *VT : VTsByNumber) {
199 if (!VT)
200 continue;
201 bool IsInteger = VT->getValueAsBit("isInteger");
202 bool IsVector = VT->getValueAsBit("isVector");
203 bool IsFP = VT->getValueAsBit("isFP");
204 bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
206 if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple)
207 continue;
209 OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";
210 vTtoGetLlvmTyString(OS, VT);
211 OS << ")\n";
213 OS << "#endif\n\n";
216 static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");