1 //===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===//
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
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"
21 const RecordKeeper
&Records
;
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
<< ")";
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")) {
53 auto OutputVTName
= OutputVT
->getValueAsString("LLVMName");
54 switch (OutputVTSize
) {
56 llvm_unreachable("Unhandled case");
58 FloatTy
= (OutputVTName
== "bf16") ? "BFloatTy" : "HalfTy";
67 FloatTy
= "X86_FP80Ty";
70 FloatTy
= (OutputVTName
== "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";
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) ||
79 OS
<< "Type::getInt" << OutputVTSize
<< "Ty(Context)";
81 OS
<< "Type::getIntNTy(Context, " << OutputVTSize
<< ")";
83 llvm_unreachable("Unhandled case");
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
;
107 std::map
<StringRef
, VTRange
> VTRanges
;
109 auto UpdateVTRange
= [&VTRanges
](const char *Key
, StringRef Name
,
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, "
123 for (const auto *VT
: VTsByNumber
) {
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
);
155 OS
<< " GET_VT_ATTR("
158 << VT
->getValueAsInt("Size") << ", "
159 << VT
->getValueAsBit("isOverloaded") << ", "
160 << (IsInteger
? Name
[0] == 'i' ? 3 : 1 : 0) << ", "
161 << (IsFP
? Name
[0] == 'f' ? 3 : 1 : 0) << ", "
163 << IsScalable
<< ", "
164 << IsRISCVVecTuple
<< ", "
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";
180 OS
<< "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";
181 for (const auto *VT
: VTsByNumber
) {
182 if (!VT
|| !VT
->getValueAsBit("isVector"))
184 const auto *ElTy
= VT
->getValueAsDef("ElementType");
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";
197 OS
<< "#ifdef GET_VT_EVT\n";
198 for (const auto *VT
: VTsByNumber
) {
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
)
209 OS
<< " GET_VT_EVT(" << VT
->getValueAsString("LLVMName") << ", ";
210 vTtoGetLlvmTyString(OS
, VT
);
216 static TableGen::Emitter::OptClass
<VTEmitter
> X("gen-vt", "Generate ValueType");