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/TargetFeaturesEmitter.cpp
213799 views
1
//===- TargetFeaturesEmitter.cpp - Generate CPU Target feature ----===//
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
// This tablegen backend exports cpu target features
10
// and cpu sub-type.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "TargetFeaturesEmitter.h"
15
#include "llvm/TableGen/Error.h"
16
#include "llvm/TableGen/TableGenBackend.h"
17
#include "llvm/TargetParser/SubtargetFeature.h"
18
19
using namespace llvm;
20
21
using FeatureMapTy = DenseMap<const Record *, unsigned>;
22
using ConstRecVec = std::vector<const Record *>;
23
24
TargetFeaturesEmitter::TargetFeaturesEmitter(const RecordKeeper &R)
25
: Records(R) {
26
ArrayRef<const Record *> Targets = Records.getAllDerivedDefinitions("Target");
27
if (Targets.size() == 0)
28
PrintFatalError("No 'Target' subclasses defined!");
29
if (Targets.size() != 1)
30
PrintFatalError("Multiple subclasses of Target defined!");
31
Target = Targets[0]->getName();
32
}
33
34
FeatureMapTy TargetFeaturesEmitter::enumeration(raw_ostream &OS) {
35
ArrayRef<const Record *> DefList =
36
Records.getAllDerivedDefinitions("SubtargetFeature");
37
38
unsigned N = DefList.size();
39
if (N == 0)
40
return FeatureMapTy();
41
42
if (N + 1 > MAX_SUBTARGET_FEATURES)
43
PrintFatalError(
44
"Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
45
46
OS << "namespace " << Target << " {\n";
47
48
OS << "enum {\n";
49
50
FeatureMapTy FeatureMap;
51
for (unsigned I = 0; I < N; ++I) {
52
const Record *Def = DefList[I];
53
// Print the Feature Name.
54
OS << " " << Def->getName() << " = " << I << ",\n";
55
56
FeatureMap[Def] = I;
57
}
58
59
OS << " " << "NumSubtargetFeatures = " << N << "\n";
60
61
// Close enumeration and namespace
62
OS << "};\n";
63
OS << "} // end namespace " << Target << "\n";
64
return FeatureMap;
65
}
66
67
void TargetFeaturesEmitter::printFeatureMask(
68
raw_ostream &OS, ArrayRef<const Record *> FeatureList,
69
const FeatureMapTy &FeatureMap) {
70
std::array<uint64_t, MAX_SUBTARGET_WORDS> Mask = {};
71
for (const Record *Feature : FeatureList) {
72
unsigned Bit = FeatureMap.lookup(Feature);
73
Mask[Bit / 64] |= 1ULL << (Bit % 64);
74
}
75
76
OS << "{ { { ";
77
for (unsigned I = 0; I != Mask.size(); ++I) {
78
OS << "0x";
79
OS.write_hex(Mask[I]);
80
OS << "ULL, ";
81
}
82
OS << "} } }";
83
}
84
85
void TargetFeaturesEmitter::printFeatureKeyValues(
86
raw_ostream &OS, const FeatureMapTy &FeatureMap) {
87
std::vector<const Record *> FeatureList =
88
Records.getAllDerivedDefinitions("SubtargetFeature");
89
90
// Remove features with empty name.
91
llvm::erase_if(FeatureList, [](const Record *Rec) {
92
return Rec->getValueAsString("Name").empty();
93
});
94
95
if (FeatureList.empty())
96
return;
97
98
llvm::sort(FeatureList, LessRecordFieldName());
99
100
// Begin feature table.
101
OS << "// Sorted (by key) array of values for CPU features.\n"
102
<< "extern const llvm::BasicSubtargetFeatureKV " << "Basic" << Target
103
<< "FeatureKV[] = {\n";
104
105
for (const Record *Feature : FeatureList) {
106
StringRef Name = Feature->getName();
107
StringRef ValueName = Feature->getValueAsString("Name");
108
109
OS << " { " << "\"" << ValueName << "\", " << Target << "::" << Name
110
<< ", ";
111
112
ConstRecVec ImpliesList = Feature->getValueAsListOfDefs("Implies");
113
114
printFeatureMask(OS, ImpliesList, FeatureMap);
115
116
OS << " },\n";
117
}
118
119
// End feature table.
120
OS << "};\n";
121
}
122
123
void TargetFeaturesEmitter::printCPUKeyValues(raw_ostream &OS,
124
const FeatureMapTy &FeatureMap) {
125
// Gather and sort processor information
126
std::vector<const Record *> ProcessorList =
127
Records.getAllDerivedDefinitions("Processor");
128
llvm::sort(ProcessorList, LessRecordFieldName());
129
130
// Begin processor table.
131
OS << "// Sorted (by key) array of values for CPU subtype.\n"
132
<< "extern const llvm::BasicSubtargetSubTypeKV " << "Basic" << Target
133
<< "SubTypeKV[] = {\n";
134
135
for (const Record *Processor : ProcessorList) {
136
StringRef Name = Processor->getValueAsString("Name");
137
ConstRecVec FeatureList = Processor->getValueAsListOfDefs("Features");
138
139
OS << " { " << "\"" << Name << "\", ";
140
141
printFeatureMask(OS, FeatureList, FeatureMap);
142
OS << " },\n";
143
}
144
145
// End processor table.
146
OS << "};\n";
147
}
148
149
void TargetFeaturesEmitter::run(raw_ostream &OS) {
150
OS << "// Autogenerated by TargetFeatureEmitter.cpp\n\n";
151
152
OS << "\n#ifdef GET_SUBTARGETFEATURES_ENUM\n";
153
OS << "#undef GET_SUBTARGETFEATURES_ENUM\n\n";
154
155
OS << "namespace llvm {\n";
156
auto FeatureMap = enumeration(OS);
157
OS << "} // end namespace llvm\n\n";
158
OS << "#endif // GET_SUBTARGETFEATURES_ENUM\n\n";
159
160
OS << "\n#ifdef GET_SUBTARGETFEATURES_KV\n";
161
OS << "#undef GET_SUBTARGETFEATURES_KV\n\n";
162
163
OS << "namespace llvm {\n";
164
printFeatureKeyValues(OS, FeatureMap);
165
OS << "\n";
166
167
printCPUKeyValues(OS, FeatureMap);
168
OS << "\n";
169
OS << "} // end namespace llvm\n\n";
170
OS << "#endif // GET_SUBTARGETFEATURES_KV\n\n";
171
}
172
173
static TableGen::Emitter::OptClass<TargetFeaturesEmitter>
174
X("gen-target-features", "Generate subtarget enumerations");
175
176