1//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===//
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 is responsible for emitting a description of the target
10// instruction set for the code generator.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Basic/SequenceToOffsetTable.h"
15#include "Common/CodeGenDAGPatterns.h"
16#include "Common/CodeGenInstruction.h"
17#include "Common/CodeGenSchedule.h"
18#include "Common/CodeGenTarget.h"
19#include "Common/PredicateExpander.h"
20#include "Common/SubtargetFeatureInfo.h"
21#include "Common/Types.h"
22#include "TableGenBackends.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringExtras.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/raw_ostream.h"
29#include "llvm/TableGen/Error.h"
30#include "llvm/TableGen/Record.h"
31#include "llvm/TableGen/TGTimer.h"
32#include "llvm/TableGen/TableGenBackend.h"
33#include <cassert>
34#include <cstdint>
35#include <iterator>
36#include <map>
37#include <string>
38#include <utility>
39#include <vector>
40
41using namespace llvm;
42
43static cl::OptionCategory InstrInfoEmitterCat("Options for -gen-instr-info");
44static cl::opt<bool> ExpandMIOperandInfo(
45 "instr-info-expand-mi-operand-info",
46 cl::desc("Expand operand's MIOperandInfo DAG into suboperands"),
47 cl::cat(InstrInfoEmitterCat), cl::init(Val: true));
48
49namespace {
50
51class InstrInfoEmitter {
52 const RecordKeeper &Records;
53 const CodeGenDAGPatterns CDP;
54 const CodeGenSchedModels &SchedModels;
55
56public:
57 InstrInfoEmitter(const RecordKeeper &R)
58 : Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
59
60 // run - Output the instruction set description.
61 void run(raw_ostream &OS);
62
63private:
64 void emitEnums(raw_ostream &OS,
65 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
66
67 typedef std::vector<std::string> OperandInfoTy;
68 typedef std::vector<OperandInfoTy> OperandInfoListTy;
69 typedef std::map<OperandInfoTy, unsigned> OperandInfoMapTy;
70
71 /// Generate member functions in the target-specific GenInstrInfo class.
72 ///
73 /// This method is used to custom expand TIIPredicate definitions.
74 /// See file llvm/Target/TargetInstPredicates.td for a description of what is
75 /// a TIIPredicate and how to use it.
76 void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
77 bool ExpandDefinition = true);
78
79 /// Expand TIIPredicate definitions to functions that accept a const MCInst
80 /// reference.
81 void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
82
83 /// Write verifyInstructionPredicates methods.
84 void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
85 void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
86 const Record *InstrInfo,
87 std::map<std::vector<const Record *>, unsigned> &EL,
88 const OperandInfoMapTy &OperandInfo, raw_ostream &OS);
89 void emitOperandTypeMappings(
90 raw_ostream &OS, const CodeGenTarget &Target,
91 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
92 void emitOperandNameMappings(
93 raw_ostream &OS, const CodeGenTarget &Target,
94 ArrayRef<const CodeGenInstruction *> TargetInstructions);
95 void emitLogicalOperandSizeMappings(
96 raw_ostream &OS, StringRef Namespace,
97 ArrayRef<const CodeGenInstruction *> TargetInstructions);
98
99 // Operand information.
100 unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
101 OperandInfoMapTy &OperandInfoMap);
102 void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList);
103 OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst);
104};
105
106} // end anonymous namespace
107
108//===----------------------------------------------------------------------===//
109// Operand Info Emission.
110//===----------------------------------------------------------------------===//
111
112InstrInfoEmitter::OperandInfoTy
113InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
114 OperandInfoTy Result;
115
116 for (auto &Op : Inst.Operands) {
117 // Handle aggregate operands and normal operands the same way by expanding
118 // either case into a list of operands for this op.
119 std::vector<CGIOperandList::OperandInfo> OperandList;
120
121 // This might be a multiple operand thing. Targets like X86 have registers
122 // in their multi-operand operands. It may also be an anonymous operand,
123 // which has a single operand, but no declared class for the operand.
124 const DagInit *MIOI = Op.MIOperandInfo;
125
126 if (!MIOI || MIOI->getNumArgs() == 0) {
127 // Single, anonymous, operand.
128 OperandList.push_back(x: Op);
129 } else {
130 for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
131 OperandList.push_back(x: Op);
132
133 auto *OpR = cast<DefInit>(Val: MIOI->getArg(Num: j))->getDef();
134 OperandList.back().Rec = OpR;
135 }
136 }
137
138 for (const auto &[OpInfo, Constraint] :
139 zip_equal(t&: OperandList, u: Op.Constraints)) {
140 const Record *OpR = OpInfo.Rec;
141 std::string Res;
142
143 if (OpR->isSubClassOf(Name: "RegisterOperand"))
144 OpR = OpR->getValueAsDef(FieldName: "RegClass");
145 if (OpR->isSubClassOf(Name: "RegisterClass"))
146 Res += getQualifiedName(R: OpR) + "RegClassID, ";
147 else if (OpR->isSubClassOf(Name: "PointerLikeRegClass"))
148 Res += utostr(X: OpR->getValueAsInt(FieldName: "RegClassKind")) + ", ";
149 else
150 // -1 means the operand does not have a fixed register class.
151 Res += "-1, ";
152
153 // Fill in applicable flags.
154 Res += "0";
155
156 // Ptr value whose register class is resolved via callback.
157 if (OpR->isSubClassOf(Name: "PointerLikeRegClass"))
158 Res += "|(1<<MCOI::LookupPtrRegClass)";
159
160 // Predicate operands. Check to see if the original unexpanded operand
161 // was of type PredicateOp.
162 if (Op.Rec->isSubClassOf(Name: "PredicateOp"))
163 Res += "|(1<<MCOI::Predicate)";
164
165 // Optional def operands. Check to see if the original unexpanded operand
166 // was of type OptionalDefOperand.
167 if (Op.Rec->isSubClassOf(Name: "OptionalDefOperand"))
168 Res += "|(1<<MCOI::OptionalDef)";
169
170 // Branch target operands. Check to see if the original unexpanded
171 // operand was of type BranchTargetOperand.
172 if (Op.Rec->isSubClassOf(Name: "BranchTargetOperand"))
173 Res += "|(1<<MCOI::BranchTarget)";
174
175 // Fill in operand type.
176 Res += ", ";
177 assert(!Op.OperandType.empty() && "Invalid operand type.");
178 Res += Op.OperandType;
179
180 // Fill in constraint info.
181 Res += ", ";
182
183 if (Constraint.isNone()) {
184 Res += "0";
185 } else if (Constraint.isEarlyClobber()) {
186 Res += "MCOI_EARLY_CLOBBER";
187 } else {
188 assert(Constraint.isTied());
189 Res += "MCOI_TIED_TO(" + utostr(X: Constraint.getTiedOperand()) + ")";
190 }
191
192 Result.push_back(x: Res);
193 }
194 }
195
196 return Result;
197}
198
199unsigned
200InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList,
201 OperandInfoMapTy &OperandInfoMap) {
202 const CodeGenTarget &Target = CDP.getTargetInfo();
203 unsigned Offset = 0;
204 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
205 OperandInfoTy OperandInfo = GetOperandInfo(Inst: *Inst);
206 if (OperandInfoMap.try_emplace(k: OperandInfo, args&: Offset).second) {
207 OperandInfoList.push_back(x: OperandInfo);
208 Offset += OperandInfo.size();
209 }
210 }
211 return Offset;
212}
213
214void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
215 OperandInfoListTy &OperandInfoList) {
216 unsigned Offset = 0;
217 for (auto &OperandInfo : OperandInfoList) {
218 OS << " /* " << Offset << " */";
219 for (auto &Info : OperandInfo)
220 OS << " { " << Info << " },";
221 OS << '\n';
222 Offset += OperandInfo.size();
223 }
224}
225
226/// Generate a table and function for looking up the indices of operands by
227/// name.
228///
229/// This code generates:
230/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
231/// for each operand name.
232/// - A 2-dimensional table called OperandMap for mapping OpName enum values to
233/// operand indices.
234/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
235/// for looking up the operand index for an instruction, given a value from
236/// OpName enum
237///
238/// Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
239/// we can just skip them. Hence accept just the TargetInstructions.
240void InstrInfoEmitter::emitOperandNameMappings(
241 raw_ostream &OS, const CodeGenTarget &Target,
242 ArrayRef<const CodeGenInstruction *> TargetInstructions) {
243 StringRef Namespace = Target.getInstNamespace();
244
245 /// To facilitate assigning OpName enum values in the sorted alphabetical
246 /// order, we go through an indirection from OpName -> ID, and Enum -> ID.
247 /// This allows us to build the OpList and assign IDs to OpNames in a single
248 /// scan of the instructions below.
249
250 // Map of operand names to their ID.
251 std::map<StringRef, unsigned> OperandNameToID;
252 // Map from operand name enum value -> ID.
253 std::vector<unsigned> OperandEnumToID;
254
255 /// The keys of this map is a map which have OpName ID values as their keys
256 /// and instruction operand indices as their values. The values of this map
257 /// are lists of instruction names. This map helps to unique entries among
258 /// instructions that have identical OpName -> Operand index mapping.
259 std::map<std::map<unsigned, unsigned>, std::vector<StringRef>> OperandMap;
260
261 // Max operand index seen.
262 unsigned MaxOperandNo = 0;
263
264 // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
265 // we can just skip them.
266 for (const CodeGenInstruction *Inst : TargetInstructions) {
267 if (!Inst->TheDef->getValueAsBit(FieldName: "UseNamedOperandTable"))
268 continue;
269 std::map<unsigned, unsigned> OpList;
270 for (const auto &Info : Inst->Operands) {
271 unsigned ID =
272 OperandNameToID.try_emplace(k: Info.Name, args: OperandNameToID.size())
273 .first->second;
274 OpList[ID] = Info.MIOperandNo;
275 MaxOperandNo = std::max(a: MaxOperandNo, b: Info.MIOperandNo);
276 }
277 OperandMap[OpList].push_back(x: Inst->TheDef->getName());
278 }
279
280 const size_t NumOperandNames = OperandNameToID.size();
281 OperandEnumToID.reserve(n: NumOperandNames);
282 for (const auto &Op : OperandNameToID)
283 OperandEnumToID.push_back(x: Op.second);
284
285 OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
286 OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
287 OS << "namespace llvm::" << Namespace << " {\n";
288 OS << "enum class OpName {\n";
289 for (const auto &[I, Op] : enumerate(First&: OperandNameToID))
290 OS << " " << Op.first << " = " << I << ",\n";
291 OS << " NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
292 OS << "}; // enum class OpName\n\n";
293 OS << "LLVM_READONLY\n";
294 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name);\n";
295 OS << "} // end namespace llvm::" << Namespace << '\n';
296 OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
297
298 OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
299 OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
300 OS << "namespace llvm::" << Namespace << " {\n";
301 OS << "LLVM_READONLY\n";
302 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name) {\n";
303 OS << " assert(Name != OpName::NUM_OPERAND_NAMES);\n";
304 if (NumOperandNames != 0) {
305 assert(MaxOperandNo <= INT16_MAX &&
306 "Too many operands for the operand name -> index table");
307 StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
308 OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames
309 << "] = {\n";
310 for (const auto &Entry : OperandMap) {
311 const std::map<unsigned, unsigned> &OpList = Entry.first;
312
313 // Emit a row of the OperandMap table.
314 OS << " {";
315 for (unsigned ID : OperandEnumToID) {
316 auto Iter = OpList.find(x: ID);
317 OS << (Iter != OpList.end() ? (int)Iter->second : -1) << ", ";
318 }
319 OS << "},\n";
320 }
321 OS << " };\n";
322
323 OS << " switch(Opcode) {\n";
324 for (const auto &[TableIndex, Entry] : enumerate(First&: OperandMap)) {
325 for (StringRef Name : Entry.second)
326 OS << " case " << Namespace << "::" << Name << ":\n";
327 OS << " return OperandMap[" << TableIndex
328 << "][static_cast<unsigned>(Name)];\n";
329 }
330 OS << " default: return -1;\n";
331 OS << " }\n";
332 } else {
333 // There are no operands, so no need to emit anything
334 OS << " return -1;\n";
335 }
336 OS << "}\n";
337 OS << "} // end namespace llvm::" << Namespace << '\n';
338 OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
339}
340
341/// Generate an enum for all the operand types for this target, under the
342/// llvm::TargetNamespace::OpTypes namespace.
343/// Operand types are all definitions derived of the Operand Target.td class.
344///
345void InstrInfoEmitter::emitOperandTypeMappings(
346 raw_ostream &OS, const CodeGenTarget &Target,
347 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
348 StringRef Namespace = Target.getInstNamespace();
349
350 // These generated functions are used only by the X86 target
351 // (in bolt/lib/Target/X86/X86MCPlusBuilder.cpp). So emit them only
352 // for X86.
353 if (Namespace != "X86")
354 return;
355
356 ArrayRef<const Record *> Operands =
357 Records.getAllDerivedDefinitions(ClassName: "Operand");
358 ArrayRef<const Record *> RegisterOperands =
359 Records.getAllDerivedDefinitions(ClassName: "RegisterOperand");
360 ArrayRef<const Record *> RegisterClasses =
361 Records.getAllDerivedDefinitions(ClassName: "RegisterClass");
362
363 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
364 OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
365 OS << "namespace llvm::" << Namespace << "::OpTypes {\n";
366 OS << "enum OperandType {\n";
367
368 unsigned EnumVal = 0;
369 for (ArrayRef<const Record *> RecordsToAdd :
370 {Operands, RegisterOperands, RegisterClasses}) {
371 for (const Record *Op : RecordsToAdd) {
372 if (!Op->isAnonymous())
373 OS << " " << Op->getName() << " = " << EnumVal << ",\n";
374 ++EnumVal;
375 }
376 }
377
378 OS << " OPERAND_TYPE_LIST_END"
379 << "\n};\n";
380 OS << "} // end namespace llvm::" << Namespace << "::OpTypes\n";
381 OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
382
383 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
384 OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
385 OS << "namespace llvm::" << Namespace << " {\n";
386 OS << "LLVM_READONLY\n";
387 OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
388 auto getInstrName = [&](int I) -> StringRef {
389 return NumberedInstructions[I]->TheDef->getName();
390 };
391 // TODO: Factor out duplicate operand lists to compress the tables.
392 std::vector<size_t> OperandOffsets;
393 std::vector<const Record *> OperandRecords;
394 size_t CurrentOffset = 0;
395 for (const CodeGenInstruction *Inst : NumberedInstructions) {
396 OperandOffsets.push_back(x: CurrentOffset);
397 for (const auto &Op : Inst->Operands) {
398 const DagInit *MIOI = Op.MIOperandInfo;
399 if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
400 // Single, anonymous, operand.
401 OperandRecords.push_back(x: Op.Rec);
402 ++CurrentOffset;
403 } else {
404 for (const Init *Arg : MIOI->getArgs()) {
405 OperandRecords.push_back(x: cast<DefInit>(Val: Arg)->getDef());
406 ++CurrentOffset;
407 }
408 }
409 }
410 }
411
412 // Emit the table of offsets (indexes) into the operand type table.
413 // Size the unsigned integer offset to save space.
414 assert(OperandRecords.size() <= UINT32_MAX &&
415 "Too many operands for offset table");
416 OS << " static constexpr " << getMinimalTypeForRange(Range: OperandRecords.size());
417 OS << " Offsets[] = {\n";
418 for (const auto &[Idx, Offset] : enumerate(First&: OperandOffsets))
419 OS << " " << Offset << ", // " << getInstrName(Idx) << '\n';
420 OS << " };\n";
421
422 // Add an entry for the end so that we don't need to special case it below.
423 OperandOffsets.push_back(x: OperandRecords.size());
424
425 // Emit the actual operand types in a flat table.
426 // Size the signed integer operand type to save space.
427 assert(EnumVal <= INT16_MAX &&
428 "Too many operand types for operand types table");
429 OS << "\n using namespace OpTypes;\n";
430 OS << " static";
431 OS << (EnumVal <= INT8_MAX ? " constexpr int8_t" : " constexpr int16_t");
432 OS << " OpcodeOperandTypes[] = {";
433 size_t CurOffset = 0;
434 for (auto [Idx, OpR] : enumerate(First&: OperandRecords)) {
435 // We print each Opcode's operands in its own row.
436 if (Idx == OperandOffsets[CurOffset]) {
437 OS << "\n /* " << getInstrName(CurOffset) << " */\n ";
438 while (OperandOffsets[++CurOffset] == Idx)
439 OS << "/* " << getInstrName(CurOffset) << " */\n ";
440 }
441 if ((OpR->isSubClassOf(Name: "Operand") || OpR->isSubClassOf(Name: "RegisterOperand") ||
442 OpR->isSubClassOf(Name: "RegisterClass")) &&
443 !OpR->isAnonymous())
444 OS << OpR->getName();
445 else
446 OS << -1;
447 OS << ", ";
448 }
449 OS << "\n };\n";
450
451 OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
452 OS << "}\n";
453 OS << "} // end namespace llvm::" << Namespace << '\n';
454 OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
455
456 OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
457 OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
458 OS << "namespace llvm::" << Namespace << " {\n";
459 OS << "LLVM_READONLY\n";
460 OS << "static int getMemOperandSize(int OpType) {\n";
461 OS << " switch (OpType) {\n";
462 std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
463 for (const Record *Op : Operands) {
464 if (!Op->isSubClassOf(Name: "X86MemOperand"))
465 continue;
466 if (int Size = Op->getValueAsInt(FieldName: "Size"))
467 SizeToOperandName[Size].push_back(Elt: Op->getName());
468 }
469 OS << " default: return 0;\n";
470 for (const auto &[Size, OperandNames] : SizeToOperandName) {
471 for (const StringRef &OperandName : OperandNames)
472 OS << " case OpTypes::" << OperandName << ":\n";
473 OS << " return " << Size << ";\n\n";
474 }
475 OS << " }\n}\n";
476 OS << "} // end namespace llvm::" << Namespace << '\n';
477 OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n";
478}
479
480// Fixed/Predefined instructions do not have UseLogicalOperandMappings
481// enabled, so we can just skip them. Hence accept TargetInstructions.
482void InstrInfoEmitter::emitLogicalOperandSizeMappings(
483 raw_ostream &OS, StringRef Namespace,
484 ArrayRef<const CodeGenInstruction *> TargetInstructions) {
485 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
486 std::map<unsigned, std::vector<std::string>> InstMap;
487
488 size_t LogicalOpListSize = 0U;
489 std::vector<unsigned> LogicalOpList;
490
491 for (const auto *Inst : TargetInstructions) {
492 if (!Inst->TheDef->getValueAsBit(FieldName: "UseLogicalOperandMappings"))
493 continue;
494
495 LogicalOpList.clear();
496 llvm::transform(Range: Inst->Operands, d_first: std::back_inserter(x&: LogicalOpList),
497 F: [](const CGIOperandList::OperandInfo &Op) -> unsigned {
498 auto *MIOI = Op.MIOperandInfo;
499 if (!MIOI || MIOI->getNumArgs() == 0)
500 return 1;
501 return MIOI->getNumArgs();
502 });
503 LogicalOpListSize = std::max(a: LogicalOpList.size(), b: LogicalOpListSize);
504
505 auto I =
506 LogicalOpSizeMap.try_emplace(k: LogicalOpList, args: LogicalOpSizeMap.size())
507 .first;
508 InstMap[I->second].push_back(
509 x: (Namespace + "::" + Inst->TheDef->getName()).str());
510 }
511
512 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
513 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
514 OS << "namespace llvm::" << Namespace << " {\n";
515 OS << "LLVM_READONLY static unsigned\n";
516 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
517 if (!InstMap.empty()) {
518 std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
519 LogicalOpSizeMap.size());
520 for (auto &P : LogicalOpSizeMap) {
521 LogicalOpSizeList[P.second] = &P.first;
522 }
523 OS << " static const unsigned SizeMap[][" << LogicalOpListSize
524 << "] = {\n";
525 for (auto &R : LogicalOpSizeList) {
526 const auto &Row = *R;
527 OS << " {";
528 int i;
529 for (i = 0; i < static_cast<int>(Row.size()); ++i) {
530 OS << Row[i] << ", ";
531 }
532 for (; i < static_cast<int>(LogicalOpListSize); ++i) {
533 OS << "0, ";
534 }
535 OS << "}, \n";
536 }
537 OS << " };\n";
538
539 OS << " switch (Opcode) {\n";
540 OS << " default: return LogicalOpIdx;\n";
541 for (auto &P : InstMap) {
542 auto OpMapIdx = P.first;
543 const auto &Insts = P.second;
544 for (const auto &Inst : Insts) {
545 OS << " case " << Inst << ":\n";
546 }
547 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
548 }
549 OS << " }\n";
550 } else {
551 OS << " return LogicalOpIdx;\n";
552 }
553 OS << "}\n";
554
555 OS << "LLVM_READONLY static inline unsigned\n";
556 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
557 OS << " auto S = 0U;\n";
558 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
559 OS << " S += getLogicalOperandSize(Opcode, i);\n";
560 OS << " return S;\n";
561 OS << "}\n";
562
563 OS << "} // end namespace llvm::" << Namespace << '\n';
564 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
565}
566
567void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
568 StringRef TargetName) {
569 ArrayRef<const Record *> TIIPredicates =
570 Records.getAllDerivedDefinitions(ClassName: "TIIPredicate");
571
572 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
573 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
574
575 OS << "namespace llvm {\n";
576 OS << "class MCInst;\n";
577 OS << "class FeatureBitset;\n\n";
578
579 OS << "namespace " << TargetName << "_MC {\n\n";
580
581 for (const Record *Rec : TIIPredicates) {
582 OS << "bool " << Rec->getValueAsString(FieldName: "FunctionName")
583 << "(const MCInst &MI);\n";
584 }
585
586 OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
587 "&Features);\n";
588
589 OS << "\n} // end namespace " << TargetName << "_MC\n";
590 OS << "} // end namespace llvm\n\n";
591
592 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
593
594 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
595 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
596
597 OS << "namespace llvm::" << TargetName << "_MC {\n";
598
599 PredicateExpander PE(TargetName);
600 PE.setExpandForMC(true);
601
602 for (const Record *Rec : TIIPredicates) {
603 OS << "bool " << Rec->getValueAsString(FieldName: "FunctionName");
604 OS << "(const MCInst &MI) {\n";
605
606 OS << PE.getIndent();
607 PE.expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Body"));
608 OS << "\n}\n\n";
609 }
610
611 OS << "} // end namespace llvm::" << TargetName << "_MC\n";
612
613 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
614}
615
616static std::string
617getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset) {
618 std::string Name = "CEFBS";
619 for (const Record *Feature : FeatureBitset)
620 Name += ("_" + Feature->getName()).str();
621 return Name;
622}
623
624void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
625 const CodeGenTarget &Target) {
626 const auto &All = SubtargetFeatureInfo::getAll(Records);
627 SubtargetFeatureInfoMap SubtargetFeatures;
628 SubtargetFeatures.insert(first: All.begin(), last: All.end());
629
630 OS << "#if (defined(ENABLE_INSTR_PREDICATE_VERIFIER) && !defined(NDEBUG)) "
631 << "||\\\n"
632 << " defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
633 << "#define GET_COMPUTE_FEATURES\n"
634 << "#endif\n";
635 OS << "#ifdef GET_COMPUTE_FEATURES\n"
636 << "#undef GET_COMPUTE_FEATURES\n"
637 << "namespace llvm::" << Target.getName() << "_MC {\n";
638
639 // Emit the subtarget feature enumeration.
640 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
641 OS);
642 // Emit the available features compute function.
643 OS << "inline ";
644 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
645 TargetName: Target.getName(), ClassName: "", FuncName: "computeAvailableFeatures", SubtargetFeatures, OS);
646
647 std::vector<std::vector<const Record *>> FeatureBitsets;
648 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
649 FeatureBitsets.emplace_back();
650 for (const Record *Predicate :
651 Inst->TheDef->getValueAsListOfDefs(FieldName: "Predicates")) {
652 const auto &I = SubtargetFeatures.find(x: Predicate);
653 if (I != SubtargetFeatures.end())
654 FeatureBitsets.back().push_back(x: I->second.TheDef);
655 }
656 }
657
658 llvm::sort(C&: FeatureBitsets, Comp: [&](ArrayRef<const Record *> A,
659 ArrayRef<const Record *> B) {
660 if (A.size() < B.size())
661 return true;
662 if (A.size() > B.size())
663 return false;
664 for (auto Pair : zip(t&: A, u&: B)) {
665 if (std::get<0>(t&: Pair)->getName() < std::get<1>(t&: Pair)->getName())
666 return true;
667 if (std::get<0>(t&: Pair)->getName() > std::get<1>(t&: Pair)->getName())
668 return false;
669 }
670 return false;
671 });
672 FeatureBitsets.erase(first: llvm::unique(R&: FeatureBitsets), last: FeatureBitsets.end());
673 OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
674 << " enum : " << getMinimalTypeForRange(Range: FeatureBitsets.size()) << " {\n"
675 << " CEFBS_None,\n";
676 for (const auto &FeatureBitset : FeatureBitsets) {
677 if (FeatureBitset.empty())
678 continue;
679 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
680 }
681 OS << " };\n\n"
682 << " static constexpr FeatureBitset FeatureBitsets[] = {\n"
683 << " {}, // CEFBS_None\n";
684 for (const auto &FeatureBitset : FeatureBitsets) {
685 if (FeatureBitset.empty())
686 continue;
687 OS << " {";
688 for (const auto &Feature : FeatureBitset) {
689 const auto &I = SubtargetFeatures.find(x: Feature);
690 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
691 OS << I->second.getEnumBitName() << ", ";
692 }
693 OS << "},\n";
694 }
695 OS << " };\n"
696 << " static constexpr " << getMinimalTypeForRange(Range: FeatureBitsets.size())
697 << " RequiredFeaturesRefs[] = {\n";
698 unsigned InstIdx = 0;
699 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
700 OS << " CEFBS";
701 unsigned NumPredicates = 0;
702 for (const Record *Predicate :
703 Inst->TheDef->getValueAsListOfDefs(FieldName: "Predicates")) {
704 const auto &I = SubtargetFeatures.find(x: Predicate);
705 if (I != SubtargetFeatures.end()) {
706 OS << '_' << I->second.TheDef->getName();
707 NumPredicates++;
708 }
709 }
710 if (!NumPredicates)
711 OS << "_None";
712 OS << ", // " << Inst->TheDef->getName() << " = " << InstIdx << '\n';
713 InstIdx++;
714 }
715 OS << " };\n\n"
716 << " assert(Opcode < " << InstIdx << ");\n"
717 << " return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
718 << "}\n\n";
719
720 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
721 << "#endif // GET_COMPUTE_FEATURES\n\n";
722
723 OS << "#ifdef GET_AVAILABLE_OPCODE_CHECKER\n"
724 << "#undef GET_AVAILABLE_OPCODE_CHECKER\n"
725 << "namespace llvm::" << Target.getName() << "_MC {\n";
726 OS << "bool isOpcodeAvailable("
727 << "unsigned Opcode, const FeatureBitset &Features) {\n"
728 << " FeatureBitset AvailableFeatures = "
729 << "computeAvailableFeatures(Features);\n"
730 << " FeatureBitset RequiredFeatures = "
731 << "computeRequiredFeatures(Opcode);\n"
732 << " FeatureBitset MissingFeatures =\n"
733 << " (AvailableFeatures & RequiredFeatures) ^\n"
734 << " RequiredFeatures;\n"
735 << " return !MissingFeatures.any();\n"
736 << "}\n";
737 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
738 << "#endif // GET_AVAILABLE_OPCODE_CHECKER\n\n";
739
740 OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
741 << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
742 << "#include <sstream>\n\n";
743
744 OS << "namespace llvm::" << Target.getName() << "_MC {\n";
745
746 // Emit the name table for error messages.
747 OS << "#ifndef NDEBUG\n";
748 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
749 OS << "#endif // NDEBUG\n\n";
750
751 // Emit the predicate verifier.
752 OS << "void verifyInstructionPredicates(\n"
753 << " unsigned Opcode, const FeatureBitset &Features) {\n"
754 << "#ifndef NDEBUG\n";
755 OS << " FeatureBitset AvailableFeatures = "
756 "computeAvailableFeatures(Features);\n";
757 OS << " FeatureBitset RequiredFeatures = "
758 << "computeRequiredFeatures(Opcode);\n";
759 OS << " FeatureBitset MissingFeatures =\n"
760 << " (AvailableFeatures & RequiredFeatures) ^\n"
761 << " RequiredFeatures;\n"
762 << " if (MissingFeatures.any()) {\n"
763 << " std::ostringstream Msg;\n"
764 << " Msg << \"Attempting to emit \" << &" << Target.getName()
765 << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
766 << " << \" instruction but the \";\n"
767 << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
768 << " if (MissingFeatures.test(i))\n"
769 << " Msg << SubtargetFeatureNames[i] << \" \";\n"
770 << " Msg << \"predicate(s) are not met\";\n"
771 << " report_fatal_error(Msg.str().c_str());\n"
772 << " }\n"
773 << "#endif // NDEBUG\n";
774 OS << "}\n";
775 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n";
776 OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
777}
778
779void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
780 StringRef TargetName,
781 bool ExpandDefinition) {
782 ArrayRef<const Record *> TIIPredicates =
783 Records.getAllDerivedDefinitions(ClassName: "TIIPredicate");
784 if (TIIPredicates.empty())
785 return;
786
787 PredicateExpander PE(TargetName);
788 PE.setExpandForMC(false);
789
790 for (const Record *Rec : TIIPredicates) {
791 OS << (ExpandDefinition ? "" : "static ") << "bool ";
792 if (ExpandDefinition)
793 OS << TargetName << "InstrInfo::";
794 OS << Rec->getValueAsString(FieldName: "FunctionName");
795 OS << "(const MachineInstr &MI)";
796 if (!ExpandDefinition) {
797 OS << ";\n";
798 continue;
799 }
800
801 OS << " {\n";
802 OS << PE.getIndent();
803 PE.expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Body"));
804 OS << "\n}\n\n";
805 }
806}
807
808//===----------------------------------------------------------------------===//
809// Main Output.
810//===----------------------------------------------------------------------===//
811
812// run - Emit the main instruction description records for the target...
813void InstrInfoEmitter::run(raw_ostream &OS) {
814 TGTimer &Timer = Records.getTimer();
815 Timer.startTimer(Name: "Analyze DAG patterns");
816
817 emitSourceFileHeader(Desc: "Target Instruction Enum Values and Descriptors", OS);
818
819 const CodeGenTarget &Target = CDP.getTargetInfo();
820 ArrayRef<const CodeGenInstruction *> NumberedInstructions =
821 Target.getInstructionsByEnumValue();
822
823 emitEnums(OS, NumberedInstructions);
824
825 StringRef TargetName = Target.getName();
826 const Record *InstrInfo = Target.getInstructionSet();
827
828 // Collect all of the operand info records.
829 Timer.startTimer(Name: "Collect operand info");
830 OperandInfoListTy OperandInfoList;
831 OperandInfoMapTy OperandInfoMap;
832 unsigned OperandInfoSize =
833 CollectOperandInfo(OperandInfoList, OperandInfoMap);
834
835 // Collect all of the instruction's implicit uses and defs.
836 // Also collect which features are enabled by instructions to control
837 // emission of various mappings.
838
839 bool HasUseLogicalOperandMappings = false;
840 bool HasUseNamedOperandTable = false;
841
842 Timer.startTimer(Name: "Collect uses/defs");
843 std::map<std::vector<const Record *>, unsigned> EmittedLists;
844 std::vector<std::vector<const Record *>> ImplicitLists;
845 unsigned ImplicitListSize = 0;
846 for (const CodeGenInstruction *Inst : NumberedInstructions) {
847 HasUseLogicalOperandMappings |=
848 Inst->TheDef->getValueAsBit(FieldName: "UseLogicalOperandMappings");
849 HasUseNamedOperandTable |=
850 Inst->TheDef->getValueAsBit(FieldName: "UseNamedOperandTable");
851
852 std::vector<const Record *> ImplicitOps = Inst->ImplicitUses;
853 llvm::append_range(C&: ImplicitOps, R: Inst->ImplicitDefs);
854 if (EmittedLists.try_emplace(k: ImplicitOps, args&: ImplicitListSize).second) {
855 ImplicitLists.push_back(x: ImplicitOps);
856 ImplicitListSize += ImplicitOps.size();
857 }
858 }
859
860 OS << "#if defined(GET_INSTRINFO_MC_DESC) || "
861 "defined(GET_INSTRINFO_CTOR_DTOR)\n";
862 OS << "namespace llvm {\n\n";
863
864 OS << "struct " << TargetName << "InstrTable {\n";
865 OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
866 OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
867 "\"Unwanted padding between Insts and OperandInfo\");\n";
868 OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
869 OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), "
870 "\"Unwanted padding between OperandInfo and ImplicitOps\");\n";
871 OS << " MCPhysReg ImplicitOps[" << std::max(a: ImplicitListSize, b: 1U) << "];\n";
872 OS << "};\n\n";
873
874 OS << "} // end namespace llvm\n";
875 OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
876 "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
877
878 OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
879 OS << "#undef GET_INSTRINFO_MC_DESC\n";
880 OS << "namespace llvm {\n\n";
881
882 // Emit all of the MCInstrDesc records in reverse ENUM ordering.
883 Timer.startTimer(Name: "Emit InstrDesc records");
884 OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
885 OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
886 << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
887
888 OS << "extern const " << TargetName << "InstrTable " << TargetName
889 << "Descs = {\n {\n";
890 SequenceToOffsetTable<StringRef> InstrNames;
891 unsigned Num = NumberedInstructions.size();
892 for (const CodeGenInstruction *Inst : reverse(C&: NumberedInstructions)) {
893 // Keep a list of the instruction names.
894 InstrNames.add(Seq: Inst->TheDef->getName());
895 // Emit the record into the table.
896 emitRecord(Inst: *Inst, Num: --Num, InstrInfo, EL&: EmittedLists, OperandInfo: OperandInfoMap, OS);
897 }
898
899 OS << " }, {\n";
900
901 // Emit all of the operand info records.
902 Timer.startTimer(Name: "Emit operand info");
903 EmitOperandInfo(OS, OperandInfoList);
904
905 OS << " }, {\n";
906
907 // Emit all of the instruction's implicit uses and defs.
908 Timer.startTimer(Name: "Emit uses/defs");
909 for (auto &List : ImplicitLists) {
910 OS << " /* " << EmittedLists[List] << " */";
911 for (auto &Reg : List)
912 OS << ' ' << getQualifiedName(R: Reg) << ',';
913 OS << '\n';
914 }
915
916 OS << " }\n};\n\n";
917
918 // Emit the array of instruction names.
919 Timer.startTimer(Name: "Emit instruction names");
920 InstrNames.layout();
921 InstrNames.emitStringLiteralDef(OS, Decl: Twine("extern const char ") + TargetName +
922 "InstrNameData[]");
923
924 OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
925 Num = 0;
926 for (const CodeGenInstruction *Inst : NumberedInstructions) {
927 // Newline every eight entries.
928 if (Num % 8 == 0)
929 OS << "\n ";
930 OS << InstrNames.get(Seq: Inst->TheDef->getName()) << "U, ";
931 ++Num;
932 }
933 OS << "\n};\n\n";
934
935 bool HasDeprecationFeatures =
936 llvm::any_of(Range&: NumberedInstructions, P: [](const CodeGenInstruction *Inst) {
937 return !Inst->HasComplexDeprecationPredicate &&
938 !Inst->DeprecatedReason.empty();
939 });
940 if (HasDeprecationFeatures) {
941 OS << "extern const uint8_t " << TargetName
942 << "InstrDeprecationFeatures[] = {";
943 Num = 0;
944 for (const CodeGenInstruction *Inst : NumberedInstructions) {
945 if (Num % 8 == 0)
946 OS << "\n ";
947 if (!Inst->HasComplexDeprecationPredicate &&
948 !Inst->DeprecatedReason.empty())
949 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
950 << ", ";
951 else
952 OS << "uint8_t(-1), ";
953 ++Num;
954 }
955 OS << "\n};\n\n";
956 }
957
958 bool HasComplexDeprecationInfos =
959 llvm::any_of(Range&: NumberedInstructions, P: [](const CodeGenInstruction *Inst) {
960 return Inst->HasComplexDeprecationPredicate;
961 });
962 if (HasComplexDeprecationInfos) {
963 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
964 << "InstrComplexDeprecationInfos[] = {";
965 Num = 0;
966 for (const CodeGenInstruction *Inst : NumberedInstructions) {
967 if (Num % 8 == 0)
968 OS << "\n ";
969 if (Inst->HasComplexDeprecationPredicate)
970 // Emit a function pointer to the complex predicate method.
971 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
972 else
973 OS << "nullptr, ";
974 ++Num;
975 }
976 OS << "\n};\n\n";
977 }
978
979 // MCInstrInfo initialization routine.
980 Timer.startTimer(Name: "Emit initialization routine");
981 OS << "static inline void Init" << TargetName
982 << "MCInstrInfo(MCInstrInfo *II) {\n";
983 OS << " II->InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
984 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
985 if (HasDeprecationFeatures)
986 OS << TargetName << "InstrDeprecationFeatures, ";
987 else
988 OS << "nullptr, ";
989 if (HasComplexDeprecationInfos)
990 OS << TargetName << "InstrComplexDeprecationInfos, ";
991 else
992 OS << "nullptr, ";
993 OS << NumberedInstructions.size() << ");\n}\n\n";
994
995 OS << "} // end namespace llvm\n";
996
997 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
998
999 // Create a TargetInstrInfo subclass to hide the MC layer initialization.
1000 OS << "#ifdef GET_INSTRINFO_HEADER\n";
1001 OS << "#undef GET_INSTRINFO_HEADER\n";
1002
1003 Twine ClassName = TargetName + "GenInstrInfo";
1004 OS << "namespace llvm {\n";
1005 OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
1006 << " explicit " << ClassName
1007 << "(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, "
1008 "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
1009 << " ~" << ClassName << "() override = default;\n";
1010
1011 OS << "\n};\n} // end namespace llvm\n";
1012
1013 OS << "#endif // GET_INSTRINFO_HEADER\n\n";
1014
1015 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
1016 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
1017 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
1018 OS << '\n';
1019 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
1020
1021 OS << "#ifdef GET_INSTRINFO_HELPERS\n";
1022 OS << "#undef GET_INSTRINFO_HELPERS\n\n";
1023 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
1024 OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
1025
1026 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
1027 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
1028
1029 OS << "namespace llvm {\n";
1030 OS << "extern const " << TargetName << "InstrTable " << TargetName
1031 << "Descs;\n";
1032 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
1033 OS << "extern const char " << TargetName << "InstrNameData[];\n";
1034 if (HasDeprecationFeatures)
1035 OS << "extern const uint8_t " << TargetName
1036 << "InstrDeprecationFeatures[];\n";
1037 if (HasComplexDeprecationInfos)
1038 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
1039 << "InstrComplexDeprecationInfos[];\n";
1040 OS << ClassName << "::" << ClassName
1041 << "(unsigned CFSetupOpcode, unsigned CFDestroyOpcode, unsigned "
1042 "CatchRetOpcode, unsigned ReturnOpcode)\n"
1043 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
1044 "ReturnOpcode) {\n"
1045 << " InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
1046 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
1047 if (HasDeprecationFeatures)
1048 OS << TargetName << "InstrDeprecationFeatures, ";
1049 else
1050 OS << "nullptr, ";
1051 if (HasComplexDeprecationInfos)
1052 OS << TargetName << "InstrComplexDeprecationInfos, ";
1053 else
1054 OS << "nullptr, ";
1055 OS << NumberedInstructions.size() << ");\n}\n";
1056 OS << "} // end namespace llvm\n";
1057
1058 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
1059
1060 ArrayRef<const CodeGenInstruction *> TargetInstructions =
1061 Target.getTargetInstructionsByEnumValue();
1062
1063 if (HasUseNamedOperandTable) {
1064 Timer.startTimer(Name: "Emit operand name mappings");
1065 emitOperandNameMappings(OS, Target, TargetInstructions);
1066 }
1067
1068 Timer.startTimer(Name: "Emit operand type mappings");
1069 emitOperandTypeMappings(OS, Target, NumberedInstructions);
1070
1071 if (HasUseLogicalOperandMappings) {
1072 Timer.startTimer(Name: "Emit logical operand size mappings");
1073 emitLogicalOperandSizeMappings(OS, Namespace: TargetName, TargetInstructions);
1074 }
1075
1076 Timer.startTimer(Name: "Emit helper methods");
1077 emitMCIIHelperMethods(OS, TargetName);
1078
1079 Timer.startTimer(Name: "Emit verifier methods");
1080 emitFeatureVerifier(OS, Target);
1081
1082 Timer.startTimer(Name: "Emit map table");
1083 EmitMapTable(RK: Records, OS);
1084}
1085
1086void InstrInfoEmitter::emitRecord(
1087 const CodeGenInstruction &Inst, unsigned Num, const Record *InstrInfo,
1088 std::map<std::vector<const Record *>, unsigned> &EmittedLists,
1089 const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) {
1090 int MinOperands = 0;
1091 if (!Inst.Operands.empty())
1092 // Each logical operand can be multiple MI operands.
1093 MinOperands =
1094 Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands;
1095 // Even the logical output operand may be multiple MI operands.
1096 int DefOperands = 0;
1097 if (Inst.Operands.NumDefs) {
1098 auto &Opnd = Inst.Operands[Inst.Operands.NumDefs - 1];
1099 DefOperands = Opnd.MIOperandNo + Opnd.MINumOperands;
1100 }
1101
1102 OS << " { ";
1103 OS << Num << ",\t" << MinOperands << ",\t" << DefOperands << ",\t"
1104 << Inst.TheDef->getValueAsInt(FieldName: "Size") << ",\t"
1105 << SchedModels.getSchedClassIdx(Inst) << ",\t";
1106
1107 const CodeGenTarget &Target = CDP.getTargetInfo();
1108
1109 // Emit the implicit use/def list...
1110 OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
1111 std::vector<const Record *> ImplicitOps = Inst.ImplicitUses;
1112 llvm::append_range(C&: ImplicitOps, R: Inst.ImplicitDefs);
1113
1114 // Emit the operand info offset.
1115 OperandInfoTy OperandInfo = GetOperandInfo(Inst);
1116 OS << OperandInfoMap.find(x: OperandInfo)->second << ",\t";
1117
1118 // Emit implicit operand base.
1119 OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps]
1120 << ",\t0";
1121
1122 // Emit all of the target independent flags...
1123 if (Inst.isPreISelOpcode)
1124 OS << "|(1ULL<<MCID::PreISelOpcode)";
1125 if (Inst.isPseudo)
1126 OS << "|(1ULL<<MCID::Pseudo)";
1127 if (Inst.isMeta)
1128 OS << "|(1ULL<<MCID::Meta)";
1129 if (Inst.isReturn)
1130 OS << "|(1ULL<<MCID::Return)";
1131 if (Inst.isEHScopeReturn)
1132 OS << "|(1ULL<<MCID::EHScopeReturn)";
1133 if (Inst.isBranch)
1134 OS << "|(1ULL<<MCID::Branch)";
1135 if (Inst.isIndirectBranch)
1136 OS << "|(1ULL<<MCID::IndirectBranch)";
1137 if (Inst.isCompare)
1138 OS << "|(1ULL<<MCID::Compare)";
1139 if (Inst.isMoveImm)
1140 OS << "|(1ULL<<MCID::MoveImm)";
1141 if (Inst.isMoveReg)
1142 OS << "|(1ULL<<MCID::MoveReg)";
1143 if (Inst.isBitcast)
1144 OS << "|(1ULL<<MCID::Bitcast)";
1145 if (Inst.isAdd)
1146 OS << "|(1ULL<<MCID::Add)";
1147 if (Inst.isTrap)
1148 OS << "|(1ULL<<MCID::Trap)";
1149 if (Inst.isSelect)
1150 OS << "|(1ULL<<MCID::Select)";
1151 if (Inst.isBarrier)
1152 OS << "|(1ULL<<MCID::Barrier)";
1153 if (Inst.hasDelaySlot)
1154 OS << "|(1ULL<<MCID::DelaySlot)";
1155 if (Inst.isCall)
1156 OS << "|(1ULL<<MCID::Call)";
1157 if (Inst.canFoldAsLoad)
1158 OS << "|(1ULL<<MCID::FoldableAsLoad)";
1159 if (Inst.mayLoad)
1160 OS << "|(1ULL<<MCID::MayLoad)";
1161 if (Inst.mayStore)
1162 OS << "|(1ULL<<MCID::MayStore)";
1163 if (Inst.mayRaiseFPException)
1164 OS << "|(1ULL<<MCID::MayRaiseFPException)";
1165 if (Inst.isPredicable)
1166 OS << "|(1ULL<<MCID::Predicable)";
1167 if (Inst.isConvertibleToThreeAddress)
1168 OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
1169 if (Inst.isCommutable)
1170 OS << "|(1ULL<<MCID::Commutable)";
1171 if (Inst.isTerminator)
1172 OS << "|(1ULL<<MCID::Terminator)";
1173 if (Inst.isReMaterializable)
1174 OS << "|(1ULL<<MCID::Rematerializable)";
1175 if (Inst.isNotDuplicable)
1176 OS << "|(1ULL<<MCID::NotDuplicable)";
1177 if (Inst.Operands.hasOptionalDef)
1178 OS << "|(1ULL<<MCID::HasOptionalDef)";
1179 if (Inst.usesCustomInserter)
1180 OS << "|(1ULL<<MCID::UsesCustomInserter)";
1181 if (Inst.hasPostISelHook)
1182 OS << "|(1ULL<<MCID::HasPostISelHook)";
1183 if (Inst.Operands.isVariadic)
1184 OS << "|(1ULL<<MCID::Variadic)";
1185 if (Inst.hasSideEffects)
1186 OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
1187 if (Inst.isAsCheapAsAMove)
1188 OS << "|(1ULL<<MCID::CheapAsAMove)";
1189 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
1190 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
1191 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
1192 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
1193 if (Inst.isRegSequence)
1194 OS << "|(1ULL<<MCID::RegSequence)";
1195 if (Inst.isExtractSubreg)
1196 OS << "|(1ULL<<MCID::ExtractSubreg)";
1197 if (Inst.isInsertSubreg)
1198 OS << "|(1ULL<<MCID::InsertSubreg)";
1199 if (Inst.isConvergent)
1200 OS << "|(1ULL<<MCID::Convergent)";
1201 if (Inst.variadicOpsAreDefs)
1202 OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
1203 if (Inst.isAuthenticated)
1204 OS << "|(1ULL<<MCID::Authenticated)";
1205
1206 // Emit all of the target-specific flags...
1207 const BitsInit *TSF = Inst.TheDef->getValueAsBitsInit(FieldName: "TSFlags");
1208 if (!TSF)
1209 PrintFatalError(ErrorLoc: Inst.TheDef->getLoc(), Msg: "no TSFlags?");
1210 uint64_t Value = 0;
1211 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
1212 if (const auto *Bit = dyn_cast<BitInit>(Val: TSF->getBit(Bit: i)))
1213 Value |= uint64_t(Bit->getValue()) << i;
1214 else
1215 PrintFatalError(ErrorLoc: Inst.TheDef->getLoc(),
1216 Msg: "Invalid TSFlags bit in " + Inst.TheDef->getName());
1217 }
1218 OS << ", 0x";
1219 OS.write_hex(N: Value);
1220 OS << "ULL";
1221
1222 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << '\n';
1223}
1224
1225// emitEnums - Print out enum values for all of the instructions.
1226void InstrInfoEmitter::emitEnums(
1227 raw_ostream &OS,
1228 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
1229 OS << "#ifdef GET_INSTRINFO_ENUM\n";
1230 OS << "#undef GET_INSTRINFO_ENUM\n";
1231
1232 const CodeGenTarget &Target = CDP.getTargetInfo();
1233 StringRef Namespace = Target.getInstNamespace();
1234
1235 if (Namespace.empty())
1236 PrintFatalError(Msg: "No instructions defined!");
1237
1238 OS << "namespace llvm::" << Namespace << " {\n";
1239
1240 OS << " enum {\n";
1241 for (const CodeGenInstruction *Inst : NumberedInstructions)
1242 OS << " " << Inst->TheDef->getName()
1243 << "\t= " << Target.getInstrIntValue(R: Inst->TheDef) << ",\n";
1244 OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << '\n';
1245 OS << " };\n\n";
1246 OS << "} // end namespace llvm::" << Namespace << '\n';
1247 OS << "#endif // GET_INSTRINFO_ENUM\n\n";
1248
1249 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
1250 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
1251 OS << "namespace llvm::" << Namespace << "::Sched {\n\n";
1252 OS << " enum {\n";
1253 auto ExplictClasses = SchedModels.explicitSchedClasses();
1254 for (const auto &[Idx, Class] : enumerate(First&: ExplictClasses))
1255 OS << " " << Class.Name << "\t= " << Idx << ",\n";
1256 OS << " SCHED_LIST_END = " << ExplictClasses.size() << '\n';
1257 OS << " };\n";
1258 OS << "} // end namespace llvm::" << Namespace << "::Sched\n";
1259
1260 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
1261}
1262
1263static TableGen::Emitter::OptClass<InstrInfoEmitter>
1264 X("gen-instr-info", "Generate instruction descriptions");
1265