Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp
35315 views
1
//===- GlobalISelMatchTableExecutorEmitter.cpp ----------------------------===//
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 "GlobalISelMatchTableExecutorEmitter.h"
10
#include "GlobalISelMatchTable.h"
11
12
using namespace llvm;
13
using namespace llvm::gi;
14
15
void GlobalISelMatchTableExecutorEmitter::emitSubtargetFeatureBitsetImpl(
16
raw_ostream &OS, ArrayRef<RuleMatcher> Rules) {
17
SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
18
OS, &HwModes);
19
20
// Separate subtarget features by how often they must be recomputed.
21
SubtargetFeatureInfoMap ModuleFeatures;
22
std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
23
std::inserter(ModuleFeatures, ModuleFeatures.end()),
24
[](const SubtargetFeatureInfoMap::value_type &X) {
25
return !X.second.mustRecomputePerFunction();
26
});
27
SubtargetFeatureInfoMap FunctionFeatures;
28
std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
29
std::inserter(FunctionFeatures, FunctionFeatures.end()),
30
[](const SubtargetFeatureInfoMap::value_type &X) {
31
return X.second.mustRecomputePerFunction();
32
});
33
34
SubtargetFeatureInfo::emitComputeAvailableFeatures(
35
getTarget().getName(), getClassName(), "computeAvailableModuleFeatures",
36
ModuleFeatures, OS, "", &HwModes);
37
38
OS << "void " << getClassName()
39
<< "::setupGeneratedPerFunctionState(MachineFunction &MF) {\n"
40
" AvailableFunctionFeatures = computeAvailableFunctionFeatures("
41
"(const "
42
<< getTarget().getName()
43
<< "Subtarget *)&MF.getSubtarget(), &MF);\n"
44
"}\n";
45
46
SubtargetFeatureInfo::emitComputeAvailableFeatures(
47
getTarget().getName(), getClassName(), "computeAvailableFunctionFeatures",
48
FunctionFeatures, OS, "const MachineFunction *MF");
49
50
// Emit a table containing the PredicateBitsets objects needed by the matcher
51
// and an enum for the matcher to reference them with.
52
std::vector<std::pair<std::vector<Record *>, int>> FeatureBitsets;
53
FeatureBitsets.reserve(Rules.size());
54
for (auto &Rule : Rules)
55
FeatureBitsets.emplace_back(Rule.getRequiredFeatures(),
56
Rule.getHwModeIdx());
57
llvm::sort(FeatureBitsets,
58
[&](const std::pair<std::vector<Record *>, int> &A,
59
const std::pair<std::vector<Record *>, int> &B) {
60
if (A.first.size() < B.first.size())
61
return true;
62
if (A.first.size() > B.first.size())
63
return false;
64
for (auto [First, Second] : zip(A.first, B.first)) {
65
if (First->getName() < Second->getName())
66
return true;
67
if (First->getName() > Second->getName())
68
return false;
69
}
70
71
return (A.second < B.second);
72
});
73
FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());
74
OS << "// Feature bitsets.\n"
75
<< "enum {\n"
76
<< " GIFBS_Invalid,\n";
77
for (const auto &FeatureBitset : FeatureBitsets) {
78
if (FeatureBitset.first.empty() && FeatureBitset.second < 0)
79
continue;
80
OS << " "
81
<< getNameForFeatureBitset(FeatureBitset.first, FeatureBitset.second)
82
<< ",\n";
83
}
84
OS << "};\n"
85
<< "constexpr static PredicateBitset FeatureBitsets[] {\n"
86
<< " {}, // GIFBS_Invalid\n";
87
for (const auto &FeatureBitset : FeatureBitsets) {
88
if (FeatureBitset.first.empty() && FeatureBitset.second < 0)
89
continue;
90
OS << " {";
91
for (const auto &Feature : FeatureBitset.first) {
92
const auto &I = SubtargetFeatures.find(Feature);
93
assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
94
OS << I->second.getEnumBitName() << ", ";
95
}
96
// HwModeIdx
97
if (FeatureBitset.second >= 0) {
98
OS << "Feature_HwMode" << FeatureBitset.second << "Bit, ";
99
}
100
OS << "},\n";
101
}
102
OS << "};\n\n";
103
}
104
105
void GlobalISelMatchTableExecutorEmitter::emitComplexPredicates(
106
raw_ostream &OS, ArrayRef<Record *> ComplexOperandMatchers) {
107
// Emit complex predicate table and an enum to reference them with.
108
OS << "// ComplexPattern predicates.\n"
109
<< "enum {\n"
110
<< " GICP_Invalid,\n";
111
for (const auto &Record : ComplexOperandMatchers)
112
OS << " GICP_" << Record->getName() << ",\n";
113
OS << "};\n"
114
<< "// See constructor for table contents\n\n";
115
116
OS << getClassName() << "::ComplexMatcherMemFn\n"
117
<< getClassName() << "::ComplexPredicateFns[] = {\n"
118
<< " nullptr, // GICP_Invalid\n";
119
for (const auto &Record : ComplexOperandMatchers)
120
OS << " &" << getClassName()
121
<< "::" << Record->getValueAsString("MatcherFn") << ", // "
122
<< Record->getName() << "\n";
123
OS << "};\n\n";
124
}
125
126
void GlobalISelMatchTableExecutorEmitter::emitCustomOperandRenderers(
127
raw_ostream &OS, ArrayRef<StringRef> CustomOperandRenderers) {
128
OS << "// Custom renderers.\n"
129
<< "enum {\n"
130
<< " GICR_Invalid,\n";
131
for (const auto &Fn : CustomOperandRenderers)
132
OS << " GICR_" << Fn << ",\n";
133
OS << "};\n";
134
135
OS << getClassName() << "::CustomRendererFn\n"
136
<< getClassName() << "::CustomRenderers[] = {\n"
137
<< " nullptr, // GICR_Invalid\n";
138
for (const auto &Fn : CustomOperandRenderers)
139
OS << " &" << getClassName() << "::" << Fn << ",\n";
140
OS << "};\n\n";
141
}
142
143
void GlobalISelMatchTableExecutorEmitter::emitTypeObjects(
144
raw_ostream &OS, ArrayRef<LLTCodeGen> TypeObjects) {
145
OS << "// LLT Objects.\n"
146
<< "enum {\n";
147
for (const auto &TypeObject : TypeObjects) {
148
OS << " ";
149
TypeObject.emitCxxEnumValue(OS);
150
OS << ",\n";
151
}
152
OS << "};\n"
153
<< "const static size_t NumTypeObjects = " << TypeObjects.size() << ";\n"
154
<< "const static LLT TypeObjects[] = {\n";
155
for (const auto &TypeObject : TypeObjects) {
156
OS << " ";
157
TypeObject.emitCxxConstructorCall(OS);
158
OS << ",\n";
159
}
160
OS << "};\n\n";
161
}
162
163
void GlobalISelMatchTableExecutorEmitter::emitMatchTable(
164
raw_ostream &OS, const MatchTable &Table) {
165
emitEncodingMacrosDef(OS);
166
OS << "const uint8_t *" << getClassName() << "::getMatchTable() const {\n";
167
Table.emitDeclaration(OS);
168
OS << " return ";
169
Table.emitUse(OS);
170
OS << ";\n}\n";
171
emitEncodingMacrosUndef(OS);
172
OS << "\n";
173
}
174
175
void GlobalISelMatchTableExecutorEmitter::emitExecutorImpl(
176
raw_ostream &OS, const MatchTable &Table, ArrayRef<LLTCodeGen> TypeObjects,
177
ArrayRef<RuleMatcher> Rules, ArrayRef<Record *> ComplexOperandMatchers,
178
ArrayRef<StringRef> CustomOperandRenderers, StringRef IfDefName) {
179
OS << "#ifdef " << IfDefName << "\n";
180
emitTypeObjects(OS, TypeObjects);
181
emitSubtargetFeatureBitsetImpl(OS, Rules);
182
emitComplexPredicates(OS, ComplexOperandMatchers);
183
emitMIPredicateFns(OS);
184
emitI64ImmPredicateFns(OS);
185
emitAPFloatImmPredicateFns(OS);
186
emitAPIntImmPredicateFns(OS);
187
emitTestSimplePredicate(OS);
188
emitCustomOperandRenderers(OS, CustomOperandRenderers);
189
emitAdditionalImpl(OS);
190
emitRunCustomAction(OS);
191
192
emitMatchTable(OS, Table);
193
194
OS << "#endif // ifdef " << IfDefName << "\n\n";
195
}
196
197
void GlobalISelMatchTableExecutorEmitter::emitPredicateBitset(
198
raw_ostream &OS, StringRef IfDefName) {
199
unsigned Size = SubtargetFeatures.size() + HwModes.size();
200
OS << "#ifdef " << IfDefName << "\n"
201
<< "const unsigned MAX_SUBTARGET_PREDICATES = " << Size << ";\n"
202
<< "using PredicateBitset = "
203
"llvm::Bitset<MAX_SUBTARGET_PREDICATES>;\n"
204
<< "#endif // ifdef " << IfDefName << "\n\n";
205
}
206
207
void GlobalISelMatchTableExecutorEmitter::emitTemporariesDecl(
208
raw_ostream &OS, StringRef IfDefName) {
209
OS << "#ifdef " << IfDefName << "\n"
210
<< " mutable MatcherState State;\n"
211
<< " typedef "
212
"ComplexRendererFns("
213
<< getClassName() << "::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
214
215
<< " typedef void(" << getClassName()
216
<< "::*CustomRendererFn)(MachineInstrBuilder &, const "
217
"MachineInstr &, int) "
218
"const;\n"
219
<< " const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, "
220
"CustomRendererFn> "
221
"ExecInfo;\n"
222
<< " static " << getClassName()
223
<< "::ComplexMatcherMemFn ComplexPredicateFns[];\n"
224
<< " static " << getClassName()
225
<< "::CustomRendererFn CustomRenderers[];\n"
226
<< " bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "
227
"override;\n"
228
<< " bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "
229
"const override;\n"
230
<< " bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
231
"&Imm) const override;\n"
232
<< " const uint8_t *getMatchTable() const override;\n"
233
<< " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"
234
", const MatcherState &State) "
235
"const override;\n"
236
<< " bool testSimplePredicate(unsigned PredicateID) const override;\n"
237
<< " bool runCustomAction(unsigned FnID, const MatcherState &State, "
238
"NewMIVector &OutMIs) "
239
"const override;\n"
240
<< "#endif // ifdef " << IfDefName << "\n\n";
241
}
242
243
void GlobalISelMatchTableExecutorEmitter::emitTemporariesInit(
244
raw_ostream &OS, unsigned MaxTemporaries, StringRef IfDefName) {
245
OS << "#ifdef " << IfDefName << "\n"
246
<< ", State(" << MaxTemporaries << "),\n"
247
<< "ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets"
248
<< ", ComplexPredicateFns, CustomRenderers)\n"
249
<< "#endif // ifdef " << IfDefName << "\n\n";
250
251
emitAdditionalTemporariesInit(OS);
252
}
253
254
void GlobalISelMatchTableExecutorEmitter::emitPredicatesDecl(
255
raw_ostream &OS, StringRef IfDefName) {
256
OS << "#ifdef " << IfDefName << "\n"
257
<< "PredicateBitset AvailableModuleFeatures;\n"
258
<< "mutable PredicateBitset AvailableFunctionFeatures;\n"
259
<< "PredicateBitset getAvailableFeatures() const {\n"
260
<< " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
261
<< "}\n"
262
<< "PredicateBitset\n"
263
<< "computeAvailableModuleFeatures(const " << getTarget().getName()
264
<< "Subtarget *Subtarget) const;\n"
265
<< "PredicateBitset\n"
266
<< "computeAvailableFunctionFeatures(const " << getTarget().getName()
267
<< "Subtarget *Subtarget,\n"
268
<< " const MachineFunction *MF) const;\n"
269
<< "void setupGeneratedPerFunctionState(MachineFunction &MF) override;\n"
270
<< "#endif // ifdef " << IfDefName << "\n";
271
}
272
273
void GlobalISelMatchTableExecutorEmitter::emitPredicatesInit(
274
raw_ostream &OS, StringRef IfDefName) {
275
OS << "#ifdef " << IfDefName << "\n"
276
<< "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
277
<< "AvailableFunctionFeatures()\n"
278
<< "#endif // ifdef " << IfDefName << "\n";
279
}
280
281