Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/VTEmitter.cpp
35258 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 <array>
14
#include <cassert>
15
#include <map>
16
using namespace llvm;
17
18
namespace {
19
20
class VTEmitter {
21
private:
22
RecordKeeper &Records;
23
24
public:
25
VTEmitter(RecordKeeper &R) : Records(R) {}
26
27
void run(raw_ostream &OS);
28
};
29
30
} // End anonymous namespace.
31
32
static void VTtoGetLLVMTyString(raw_ostream &OS, const Record *VT) {
33
bool IsVector = VT->getValueAsBit("isVector");
34
if (IsVector)
35
OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")
36
<< "VectorType::get(";
37
38
auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;
39
int64_t OutputVTSize = OutputVT->getValueAsInt("Size");
40
41
if (OutputVT->getValueAsBit("isFP")) {
42
StringRef FloatTy;
43
auto OutputVTName = OutputVT->getValueAsString("LLVMName");
44
switch (OutputVTSize) {
45
default:
46
llvm_unreachable("Unhandled case");
47
case 16:
48
FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy";
49
break;
50
case 32:
51
FloatTy = "FloatTy";
52
break;
53
case 64:
54
FloatTy = "DoubleTy";
55
break;
56
case 80:
57
FloatTy = "X86_FP80Ty";
58
break;
59
case 128:
60
FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";
61
break;
62
}
63
OS << "Type::get" << FloatTy << "(Context)";
64
} else if (OutputVT->getValueAsBit("isInteger")) {
65
// We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int128
66
if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&
67
OutputVTSize <= 128) ||
68
OutputVTSize == 1)
69
OS << "Type::getInt" << OutputVTSize << "Ty(Context)";
70
else
71
OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";
72
} else
73
llvm_unreachable("Unhandled case");
74
75
if (IsVector)
76
OS << ", " << VT->getValueAsInt("nElem") << ")";
77
}
78
79
void VTEmitter::run(raw_ostream &OS) {
80
emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);
81
82
std::array<const Record *, 256> VTsByNumber = {};
83
auto ValueTypes = Records.getAllDerivedDefinitions("ValueType");
84
for (auto *VT : ValueTypes) {
85
auto Number = VT->getValueAsInt("Value");
86
assert(0 <= Number && Number < (int)VTsByNumber.size() &&
87
"ValueType should be uint8_t");
88
assert(!VTsByNumber[Number] && "Duplicate ValueType");
89
VTsByNumber[Number] = VT;
90
}
91
92
struct VTRange {
93
StringRef First;
94
StringRef Last;
95
bool Closed;
96
};
97
98
std::map<StringRef, VTRange> VTRanges;
99
100
auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,
101
bool Valid) {
102
if (Valid) {
103
if (!VTRanges.count(Key))
104
VTRanges[Key].First = Name;
105
assert(!VTRanges[Key].Closed && "Gap detected!");
106
VTRanges[Key].Last = Name;
107
} else if (VTRanges.count(Key)) {
108
VTRanges[Key].Closed = true;
109
}
110
};
111
112
OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n";
113
for (const auto *VT : VTsByNumber) {
114
if (!VT)
115
continue;
116
auto Name = VT->getValueAsString("LLVMName");
117
auto Value = VT->getValueAsInt("Value");
118
bool IsInteger = VT->getValueAsBit("isInteger");
119
bool IsFP = VT->getValueAsBit("isFP");
120
bool IsVector = VT->getValueAsBit("isVector");
121
bool IsScalable = VT->getValueAsBit("isScalable");
122
bool IsNormalValueType = VT->getValueAsBit("isNormalValueType");
123
int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;
124
StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()
125
: "INVALID_SIMPLE_VALUE_TYPE";
126
127
UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,
128
IsInteger && IsVector && !IsScalable);
129
UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,
130
IsInteger && IsScalable);
131
UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,
132
IsFP && IsVector && !IsScalable);
133
UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);
134
UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);
135
UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);
136
UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);
137
UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);
138
UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);
139
UpdateVTRange("VALUETYPE", Name, IsNormalValueType);
140
141
// clang-format off
142
OS << " GET_VT_ATTR("
143
<< Name << ", "
144
<< Value << ", "
145
<< VT->getValueAsInt("Size") << ", "
146
<< VT->getValueAsBit("isOverloaded") << ", "
147
<< (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "
148
<< (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "
149
<< IsVector << ", "
150
<< IsScalable << ", "
151
<< NElem << ", "
152
<< EltName << ")\n";
153
// clang-format on
154
}
155
OS << "#endif\n\n";
156
157
OS << "#ifdef GET_VT_RANGES\n";
158
for (const auto &KV : VTRanges) {
159
assert(KV.second.Closed);
160
OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n"
161
<< " LAST_" << KV.first << " = " << KV.second.Last << ",\n";
162
}
163
OS << "#endif\n\n";
164
165
OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy)\n";
166
for (const auto *VT : VTsByNumber) {
167
if (!VT || !VT->getValueAsBit("isVector"))
168
continue;
169
const auto *ElTy = VT->getValueAsDef("ElementType");
170
assert(ElTy);
171
// clang-format off
172
OS << " GET_VT_VECATTR("
173
<< VT->getValueAsString("LLVMName") << ", "
174
<< VT->getValueAsBit("isScalable") << ", "
175
<< VT->getValueAsInt("nElem") << ", "
176
<< ElTy->getName() << ")\n";
177
// clang-format on
178
}
179
OS << "#endif\n\n";
180
181
OS << "#ifdef GET_VT_EVT\n";
182
for (const auto *VT : VTsByNumber) {
183
if (!VT)
184
continue;
185
bool IsInteger = VT->getValueAsBit("isInteger");
186
bool IsVector = VT->getValueAsBit("isVector");
187
bool IsFP = VT->getValueAsBit("isFP");
188
189
if (!IsInteger && !IsVector && !IsFP)
190
continue;
191
192
OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";
193
VTtoGetLLVMTyString(OS, VT);
194
OS << ")\n";
195
}
196
OS << "#endif\n\n";
197
}
198
199
static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");
200
201