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"
22 RecordKeeper
&Records
;
25 VTEmitter(RecordKeeper
&R
) : Records(R
) {}
27 void run(raw_ostream
&OS
);
30 } // End anonymous namespace.
32 void VTEmitter::run(raw_ostream
&OS
) {
33 emitSourceFileHeader("ValueTypes Source Fragment", OS
, Records
);
35 std::array
<const Record
*, 256> VTsByNumber
= {};
36 auto ValueTypes
= Records
.getAllDerivedDefinitions("ValueType");
37 for (auto *VT
: ValueTypes
) {
38 auto Number
= VT
->getValueAsInt("Value");
39 assert(0 <= Number
&& Number
< (int)VTsByNumber
.size() &&
40 "ValueType should be uint8_t");
41 assert(!VTsByNumber
[Number
] && "Duplicate ValueType");
42 VTsByNumber
[Number
] = VT
;
51 std::map
<StringRef
, VTRange
> VTRanges
;
53 auto UpdateVTRange
= [&VTRanges
](const char *Key
, StringRef Name
,
56 if (!VTRanges
.count(Key
))
57 VTRanges
[Key
].First
= Name
;
58 assert(!VTRanges
[Key
].Closed
&& "Gap detected!");
59 VTRanges
[Key
].Last
= Name
;
60 } else if (VTRanges
.count(Key
)) {
61 VTRanges
[Key
].Closed
= true;
65 OS
<< "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n";
66 for (const auto *VT
: VTsByNumber
) {
69 auto Name
= VT
->getValueAsString("LLVMName");
70 auto Value
= VT
->getValueAsInt("Value");
71 bool IsInteger
= VT
->getValueAsInt("isInteger");
72 bool IsFP
= VT
->getValueAsInt("isFP");
73 bool IsVector
= VT
->getValueAsInt("isVector");
74 bool IsScalable
= VT
->getValueAsInt("isScalable");
76 UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name
,
77 IsInteger
&& IsVector
&& !IsScalable
);
78 UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name
,
79 IsInteger
&& IsScalable
);
80 UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name
,
81 IsFP
&& IsVector
&& !IsScalable
);
82 UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name
, IsFP
&& IsScalable
);
83 UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name
, IsVector
&& !IsScalable
);
84 UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name
, IsScalable
);
85 UpdateVTRange("VECTOR_VALUETYPE", Name
, IsVector
);
86 UpdateVTRange("INTEGER_VALUETYPE", Name
, IsInteger
&& !IsVector
);
87 UpdateVTRange("FP_VALUETYPE", Name
, IsFP
&& !IsVector
);
88 UpdateVTRange("VALUETYPE", Name
, Value
< 224);
94 << VT
->getValueAsInt("Size") << ", "
95 << VT
->getValueAsInt("isOverloaded") << ", "
96 << (IsInteger
? Name
[0] == 'i' ? 3 : 1 : 0) << ", "
97 << (IsFP
? Name
[0] == 'f' ? 3 : 1 : 0) << ", "
99 << IsScalable
<< ")\n";
104 OS
<< "#ifdef GET_VT_RANGES\n";
105 for (const auto &KV
: VTRanges
) {
106 assert(KV
.second
.Closed
);
107 OS
<< " FIRST_" << KV
.first
<< " = " << KV
.second
.First
<< ",\n"
108 << " LAST_" << KV
.first
<< " = " << KV
.second
.Last
<< ",\n";
112 OS
<< "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy, ElSz)\n";
113 for (const auto *VT
: VTsByNumber
) {
114 if (!VT
|| !VT
->getValueAsInt("isVector"))
116 const auto *ElTy
= VT
->getValueAsDef("ElementType");
119 OS
<< " GET_VT_VECATTR("
120 << VT
->getValueAsString("LLVMName") << ", "
121 << VT
->getValueAsInt("isScalable") << ", "
122 << VT
->getValueAsInt("nElem") << ", "
123 << ElTy
->getName() << ", "
124 << ElTy
->getValueAsInt("Size") << ")\n";
130 static TableGen::Emitter::OptClass
<VTEmitter
> X("gen-vt", "Generate ValueType");