[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / utils / TableGen / GlobalISelMatchTableExecutorEmitter.cpp
blob5697899a915a0355fdede013abbd34aa89865426
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 //===----------------------------------------------------------------------===//
9 #include "GlobalISelMatchTableExecutorEmitter.h"
10 #include "GlobalISelMatchTable.h"
12 using namespace llvm;
13 using namespace llvm::gi;
15 void GlobalISelMatchTableExecutorEmitter::emitSubtargetFeatureBitsetImpl(
16 raw_ostream &OS, ArrayRef<RuleMatcher> Rules) {
17 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
18 OS, &HwModes);
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 });
34 SubtargetFeatureInfo::emitComputeAvailableFeatures(
35 getTarget().getName(), getClassName(), "computeAvailableModuleFeatures",
36 ModuleFeatures, OS, "", &HwModes);
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";
46 SubtargetFeatureInfo::emitComputeAvailableFeatures(
47 getTarget().getName(), getClassName(), "computeAvailableFunctionFeatures",
48 FunctionFeatures, OS, "const MachineFunction *MF");
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;
71 return (A.second < B.second);
72 });
73 FeatureBitsets.erase(
74 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
75 FeatureBitsets.end());
76 OS << "// Feature bitsets.\n"
77 << "enum {\n"
78 << " GIFBS_Invalid,\n";
79 for (const auto &FeatureBitset : FeatureBitsets) {
80 if (FeatureBitset.first.empty() && FeatureBitset.second < 0)
81 continue;
82 OS << " "
83 << getNameForFeatureBitset(FeatureBitset.first, FeatureBitset.second)
84 << ",\n";
86 OS << "};\n"
87 << "constexpr static PredicateBitset FeatureBitsets[] {\n"
88 << " {}, // GIFBS_Invalid\n";
89 for (const auto &FeatureBitset : FeatureBitsets) {
90 if (FeatureBitset.first.empty() && FeatureBitset.second < 0)
91 continue;
92 OS << " {";
93 for (const auto &Feature : FeatureBitset.first) {
94 const auto &I = SubtargetFeatures.find(Feature);
95 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
96 OS << I->second.getEnumBitName() << ", ";
98 // HwModeIdx
99 if (FeatureBitset.second >= 0) {
100 OS << "Feature_HwMode" << FeatureBitset.second << "Bit, ";
102 OS << "},\n";
104 OS << "};\n\n";
107 void GlobalISelMatchTableExecutorEmitter::emitComplexPredicates(
108 raw_ostream &OS, ArrayRef<Record *> ComplexOperandMatchers) {
109 // Emit complex predicate table and an enum to reference them with.
110 OS << "// ComplexPattern predicates.\n"
111 << "enum {\n"
112 << " GICP_Invalid,\n";
113 for (const auto &Record : ComplexOperandMatchers)
114 OS << " GICP_" << Record->getName() << ",\n";
115 OS << "};\n"
116 << "// See constructor for table contents\n\n";
118 OS << getClassName() << "::ComplexMatcherMemFn\n"
119 << getClassName() << "::ComplexPredicateFns[] = {\n"
120 << " nullptr, // GICP_Invalid\n";
121 for (const auto &Record : ComplexOperandMatchers)
122 OS << " &" << getClassName()
123 << "::" << Record->getValueAsString("MatcherFn") << ", // "
124 << Record->getName() << "\n";
125 OS << "};\n\n";
128 void GlobalISelMatchTableExecutorEmitter::emitCustomOperandRenderers(
129 raw_ostream &OS, ArrayRef<StringRef> CustomOperandRenderers) {
130 OS << "// Custom renderers.\n"
131 << "enum {\n"
132 << " GICR_Invalid,\n";
133 for (const auto &Fn : CustomOperandRenderers)
134 OS << " GICR_" << Fn << ",\n";
135 OS << "};\n";
137 OS << getClassName() << "::CustomRendererFn\n"
138 << getClassName() << "::CustomRenderers[] = {\n"
139 << " nullptr, // GICR_Invalid\n";
140 for (const auto &Fn : CustomOperandRenderers)
141 OS << " &" << getClassName() << "::" << Fn << ",\n";
142 OS << "};\n\n";
145 void GlobalISelMatchTableExecutorEmitter::emitTypeObjects(
146 raw_ostream &OS, ArrayRef<LLTCodeGen> TypeObjects) {
147 OS << "// LLT Objects.\n"
148 << "enum {\n";
149 for (const auto &TypeObject : TypeObjects) {
150 OS << " ";
151 TypeObject.emitCxxEnumValue(OS);
152 OS << ",\n";
154 OS << "};\n"
155 << "const static size_t NumTypeObjects = " << TypeObjects.size() << ";\n"
156 << "const static LLT TypeObjects[] = {\n";
157 for (const auto &TypeObject : TypeObjects) {
158 OS << " ";
159 TypeObject.emitCxxConstructorCall(OS);
160 OS << ",\n";
162 OS << "};\n\n";
165 void GlobalISelMatchTableExecutorEmitter::emitMatchTable(
166 raw_ostream &OS, const MatchTable &Table) {
167 emitEncodingMacrosDef(OS);
168 OS << "const uint8_t *" << getClassName() << "::getMatchTable() const {\n";
169 Table.emitDeclaration(OS);
170 OS << " return ";
171 Table.emitUse(OS);
172 OS << ";\n}\n";
173 emitEncodingMacrosUndef(OS);
174 OS << "\n";
177 void GlobalISelMatchTableExecutorEmitter::emitExecutorImpl(
178 raw_ostream &OS, const MatchTable &Table, ArrayRef<LLTCodeGen> TypeObjects,
179 ArrayRef<RuleMatcher> Rules, ArrayRef<Record *> ComplexOperandMatchers,
180 ArrayRef<StringRef> CustomOperandRenderers, StringRef IfDefName) {
181 OS << "#ifdef " << IfDefName << "\n";
182 emitTypeObjects(OS, TypeObjects);
183 emitSubtargetFeatureBitsetImpl(OS, Rules);
184 emitComplexPredicates(OS, ComplexOperandMatchers);
185 emitMIPredicateFns(OS);
186 emitI64ImmPredicateFns(OS);
187 emitAPFloatImmPredicateFns(OS);
188 emitAPIntImmPredicateFns(OS);
189 emitTestSimplePredicate(OS);
190 emitCustomOperandRenderers(OS, CustomOperandRenderers);
191 emitAdditionalImpl(OS);
192 emitRunCustomAction(OS);
194 emitMatchTable(OS, Table);
196 OS << "#endif // ifdef " << IfDefName << "\n\n";
199 void GlobalISelMatchTableExecutorEmitter::emitPredicateBitset(
200 raw_ostream &OS, StringRef IfDefName) {
201 unsigned Size = SubtargetFeatures.size() + HwModes.size();
202 OS << "#ifdef " << IfDefName << "\n"
203 << "const unsigned MAX_SUBTARGET_PREDICATES = " << Size << ";\n"
204 << "using PredicateBitset = "
205 "llvm::Bitset<MAX_SUBTARGET_PREDICATES>;\n"
206 << "#endif // ifdef " << IfDefName << "\n\n";
209 void GlobalISelMatchTableExecutorEmitter::emitTemporariesDecl(
210 raw_ostream &OS, StringRef IfDefName) {
211 OS << "#ifdef " << IfDefName << "\n"
212 << " mutable MatcherState State;\n"
213 << " typedef "
214 "ComplexRendererFns("
215 << getClassName() << "::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
217 << " typedef void(" << getClassName()
218 << "::*CustomRendererFn)(MachineInstrBuilder &, const "
219 "MachineInstr &, int) "
220 "const;\n"
221 << " const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, "
222 "CustomRendererFn> "
223 "ExecInfo;\n"
224 << " static " << getClassName()
225 << "::ComplexMatcherMemFn ComplexPredicateFns[];\n"
226 << " static " << getClassName()
227 << "::CustomRendererFn CustomRenderers[];\n"
228 << " bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "
229 "override;\n"
230 << " bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "
231 "const override;\n"
232 << " bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
233 "&Imm) const override;\n"
234 << " const uint8_t *getMatchTable() const override;\n"
235 << " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"
236 ", const MatcherState &State) "
237 "const override;\n"
238 << " bool testSimplePredicate(unsigned PredicateID) const override;\n"
239 << " void runCustomAction(unsigned FnID, const MatcherState &State, "
240 "NewMIVector &OutMIs) "
241 "const override;\n";
242 emitAdditionalTemporariesDecl(OS, " ");
243 OS << "#endif // ifdef " << IfDefName << "\n\n";
246 void GlobalISelMatchTableExecutorEmitter::emitTemporariesInit(
247 raw_ostream &OS, unsigned MaxTemporaries, StringRef IfDefName) {
248 OS << "#ifdef " << IfDefName << "\n"
249 << ", State(" << MaxTemporaries << "),\n"
250 << "ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets"
251 << ", ComplexPredicateFns, CustomRenderers)\n"
252 << "#endif // ifdef " << IfDefName << "\n\n";
254 emitAdditionalTemporariesInit(OS);
257 void GlobalISelMatchTableExecutorEmitter::emitPredicatesDecl(
258 raw_ostream &OS, StringRef IfDefName) {
259 OS << "#ifdef " << IfDefName << "\n"
260 << "PredicateBitset AvailableModuleFeatures;\n"
261 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
262 << "PredicateBitset getAvailableFeatures() const {\n"
263 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
264 << "}\n"
265 << "PredicateBitset\n"
266 << "computeAvailableModuleFeatures(const " << getTarget().getName()
267 << "Subtarget *Subtarget) const;\n"
268 << "PredicateBitset\n"
269 << "computeAvailableFunctionFeatures(const " << getTarget().getName()
270 << "Subtarget *Subtarget,\n"
271 << " const MachineFunction *MF) const;\n"
272 << "void setupGeneratedPerFunctionState(MachineFunction &MF) override;\n"
273 << "#endif // ifdef " << IfDefName << "\n";
276 void GlobalISelMatchTableExecutorEmitter::emitPredicatesInit(
277 raw_ostream &OS, StringRef IfDefName) {
278 OS << "#ifdef " << IfDefName << "\n"
279 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
280 << "AvailableFunctionFeatures()\n"
281 << "#endif // ifdef " << IfDefName << "\n";