Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Basic/VTEmitter.cpp
213799 views
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
220