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>
16using namespace llvm;
17
18namespace {
19
20class VTEmitter {
21private:
22 RecordKeeper &Records;
23
24public:
25 VTEmitter(RecordKeeper &R) : Records(R) {}
26
27 void run(raw_ostream &OS);
28};
29
30} // End anonymous namespace.
31
32void VTEmitter::run(raw_ostream &OS) {
33 emitSourceFileHeader(Desc: "ValueTypes Source Fragment", OS, Record: Records);
34
35 std::array<const Record *, 256> VTsByNumber = {};
36 auto ValueTypes = Records.getAllDerivedDefinitions(ClassName: "ValueType");
37 for (auto *VT : ValueTypes) {
38 auto Number = VT->getValueAsInt(FieldName: "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;
43 }
44
45 struct VTRange {
46 StringRef First;
47 StringRef Last;
48 bool Closed;
49 };
50
51 std::map<StringRef, VTRange> VTRanges;
52
53 auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,
54 bool Valid) {
55 if (Valid) {
56 if (!VTRanges.count(x: Key))
57 VTRanges[Key].First = Name;
58 assert(!VTRanges[Key].Closed && "Gap detected!");
59 VTRanges[Key].Last = Name;
60 } else if (VTRanges.count(x: Key)) {
61 VTRanges[Key].Closed = true;
62 }
63 };
64
65 OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n";
66 for (const auto *VT : VTsByNumber) {
67 if (!VT)
68 continue;
69 auto Name = VT->getValueAsString(FieldName: "LLVMName");
70 auto Value = VT->getValueAsInt(FieldName: "Value");
71 bool IsInteger = VT->getValueAsInt(FieldName: "isInteger");
72 bool IsFP = VT->getValueAsInt(FieldName: "isFP");
73 bool IsVector = VT->getValueAsInt(FieldName: "isVector");
74 bool IsScalable = VT->getValueAsInt(FieldName: "isScalable");
75
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);
89
90 // clang-format off
91 OS << " GET_VT_ATTR("
92 << Name << ", "
93 << Value << ", "
94 << VT->getValueAsInt(FieldName: "Size") << ", "
95 << VT->getValueAsInt(FieldName: "isOverloaded") << ", "
96 << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "
97 << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "
98 << IsVector << ", "
99 << IsScalable << ")\n";
100 // clang-format on
101 }
102 OS << "#endif\n\n";
103
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";
109 }
110 OS << "#endif\n\n";
111
112 OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy, ElSz)\n";
113 for (const auto *VT : VTsByNumber) {
114 if (!VT || !VT->getValueAsInt(FieldName: "isVector"))
115 continue;
116 const auto *ElTy = VT->getValueAsDef(FieldName: "ElementType");
117 assert(ElTy);
118 // clang-format off
119 OS << " GET_VT_VECATTR("
120 << VT->getValueAsString(FieldName: "LLVMName") << ", "
121 << VT->getValueAsInt(FieldName: "isScalable") << ", "
122 << VT->getValueAsInt(FieldName: "nElem") << ", "
123 << ElTy->getName() << ", "
124 << ElTy->getValueAsInt(FieldName: "Size") << ")\n";
125 // clang-format on
126 }
127 OS << "#endif\n\n";
128}
129
130static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");
131

source code of llvm/utils/TableGen/VTEmitter.cpp