xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Basic/VTEmitter.cpp (revision 60d78908f57cf2100d5aeafa7db5d97cda3c5607)
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 //===----------------------------------------------------------------------===//
8 
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;
16 
17 namespace {
18 
19 class VTEmitter {
20 private:
21   const RecordKeeper &Records;
22 
23 public:
24   VTEmitter(const RecordKeeper &R) : Records(R) {}
25 
26   void run(raw_ostream &OS);
27 };
28 
29 } // End anonymous namespace.
30 
31 static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) {
32   bool IsVector = VT->getValueAsBit("isVector");
33   bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
34 
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;
42   }
43 
44   if (IsVector)
45     OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")
46        << "VectorType::get(";
47 
48   auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;
49   int64_t OutputVTSize = OutputVT->getValueAsInt("Size");
50 
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;
72     }
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");
84   }
85 
86   if (IsVector)
87     OS << ", " << VT->getValueAsInt("nElem") << ")";
88 }
89 
90 void VTEmitter::run(raw_ostream &OS) {
91   emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);
92 
93   std::vector<const Record *> VTsByNumber{512};
94   for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) {
95     auto Number = VT->getValueAsInt("Value");
96     assert(0 <= Number && Number < (int)VTsByNumber.size() &&
97            "ValueType should be uint16_t");
98     assert(!VTsByNumber[Number] && "Duplicate ValueType");
99     VTsByNumber[Number] = VT;
100   }
101 
102   struct VTRange {
103     StringRef First;
104     StringRef Last;
105     bool Closed;
106   };
107 
108   std::map<StringRef, VTRange> VTRanges;
109 
110   auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,
111                                    bool Valid) {
112     if (Valid) {
113       auto [It, Inserted] = VTRanges.try_emplace(Key);
114       if (Inserted)
115         It->second.First = Name;
116       assert(!It->second.Closed && "Gap detected!");
117       It->second.Last = Name;
118     } else if (auto It = VTRanges.find(Key); It != VTRanges.end()) {
119       It->second.Closed = true;
120     }
121   };
122 
123   OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, "
124         "NElem, EltTy)\n";
125   for (const auto *VT : VTsByNumber) {
126     if (!VT)
127       continue;
128     auto Name = VT->getValueAsString("LLVMName");
129     auto Value = VT->getValueAsInt("Value");
130     bool IsInteger = VT->getValueAsBit("isInteger");
131     bool IsFP = VT->getValueAsBit("isFP");
132     bool IsVector = VT->getValueAsBit("isVector");
133     bool IsScalable = VT->getValueAsBit("isScalable");
134     bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
135     int64_t NF = VT->getValueAsInt("NF");
136     bool IsNormalValueType =  VT->getValueAsBit("isNormalValueType");
137     int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;
138     StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()
139                                  : "INVALID_SIMPLE_VALUE_TYPE";
140 
141     UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,
142                   IsInteger && IsVector && !IsScalable);
143     UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,
144                   IsInteger && IsScalable);
145     UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,
146                   IsFP && IsVector && !IsScalable);
147     UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);
148     UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);
149     UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);
150     UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple);
151     UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);
152     UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);
153     UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);
154     UpdateVTRange("VALUETYPE", Name, IsNormalValueType);
155 
156     // clang-format off
157     OS << "  GET_VT_ATTR("
158        << Name << ", "
159        << Value << ", "
160        << VT->getValueAsInt("Size") << ", "
161        << VT->getValueAsBit("isOverloaded") << ", "
162        << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "
163        << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "
164        << IsVector << ", "
165        << IsScalable << ", "
166        << IsRISCVVecTuple << ", "
167        << NF << ", "
168        << NElem << ", "
169        << EltName << ")\n";
170     // clang-format on
171   }
172   OS << "#endif\n\n";
173 
174   OS << "#ifdef GET_VT_RANGES\n";
175   for (const auto &KV : VTRanges) {
176     assert(KV.second.Closed);
177     OS << "  FIRST_" << KV.first << " = " << KV.second.First << ",\n"
178        << "  LAST_" << KV.first << " = " << KV.second.Last << ",\n";
179   }
180   OS << "#endif\n\n";
181 
182   OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";
183   for (const auto *VT : VTsByNumber) {
184     if (!VT || !VT->getValueAsBit("isVector"))
185       continue;
186     const auto *ElTy = VT->getValueAsDef("ElementType");
187     assert(ElTy);
188     // clang-format off
189     OS << "  GET_VT_VECATTR("
190        << VT->getValueAsString("LLVMName") << ", "
191        << VT->getValueAsBit("isScalable") << ", "
192        << VT->getValueAsBit("isRISCVVecTuple") << ", "
193        << VT->getValueAsInt("nElem") << ", "
194        << ElTy->getName() << ")\n";
195     // clang-format on
196   }
197   OS << "#endif\n\n";
198 
199   OS << "#ifdef GET_VT_EVT\n";
200   for (const auto *VT : VTsByNumber) {
201     if (!VT)
202       continue;
203     bool IsInteger = VT->getValueAsBit("isInteger");
204     bool IsVector = VT->getValueAsBit("isVector");
205     bool IsFP = VT->getValueAsBit("isFP");
206     bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
207 
208     if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple)
209       continue;
210 
211     OS << "  GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";
212     vTtoGetLlvmTyString(OS, VT);
213     OS << ")\n";
214   }
215   OS << "#endif\n\n";
216 }
217 
218 static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");
219