[RISCV] Rename Mips instruction records to start with MIPS_. NFC (#125170)
[llvm-project.git] / llvm / utils / TableGen / InstrInfoEmitter.cpp
blob55e9d576b9b068ea63c5c1c1d415eb345fca6630
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.
12 //===----------------------------------------------------------------------===//
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>
41 using namespace llvm;
43 static cl::OptionCategory InstrInfoEmitterCat("Options for -gen-instr-info");
44 static 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(true));
49 namespace {
51 class InstrInfoEmitter {
52 const RecordKeeper &Records;
53 const CodeGenDAGPatterns CDP;
54 const CodeGenSchedModels &SchedModels;
56 public:
57 InstrInfoEmitter(const RecordKeeper &R)
58 : Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
60 // run - Output the instruction set description.
61 void run(raw_ostream &OS);
63 private:
64 void emitEnums(raw_ostream &OS);
66 typedef std::vector<std::string> OperandInfoTy;
67 typedef std::vector<OperandInfoTy> OperandInfoListTy;
68 typedef std::map<OperandInfoTy, unsigned> OperandInfoMapTy;
70 /// Generate member functions in the target-specific GenInstrInfo class.
71 ///
72 /// This method is used to custom expand TIIPredicate definitions.
73 /// See file llvm/Target/TargetInstPredicates.td for a description of what is
74 /// a TIIPredicate and how to use it.
75 void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
76 bool ExpandDefinition = true);
78 /// Expand TIIPredicate definitions to functions that accept a const MCInst
79 /// reference.
80 void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
82 /// Write verifyInstructionPredicates methods.
83 void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
84 void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
85 const Record *InstrInfo,
86 std::map<std::vector<const Record *>, unsigned> &EL,
87 const OperandInfoMapTy &OperandInfo, raw_ostream &OS);
88 void emitOperandTypeMappings(
89 raw_ostream &OS, const CodeGenTarget &Target,
90 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
91 void emitOperandNameMappings(
92 raw_ostream &OS, const CodeGenTarget &Target,
93 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
94 void emitLogicalOperandSizeMappings(
95 raw_ostream &OS, StringRef Namespace,
96 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
97 void emitLogicalOperandTypeMappings(
98 raw_ostream &OS, StringRef Namespace,
99 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
101 // Operand information.
102 unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
103 OperandInfoMapTy &OperandInfoMap);
104 void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList);
105 OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst);
108 } // end anonymous namespace
110 //===----------------------------------------------------------------------===//
111 // Operand Info Emission.
112 //===----------------------------------------------------------------------===//
114 InstrInfoEmitter::OperandInfoTy
115 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
116 OperandInfoTy Result;
118 for (auto &Op : Inst.Operands) {
119 // Handle aggregate operands and normal operands the same way by expanding
120 // either case into a list of operands for this op.
121 std::vector<CGIOperandList::OperandInfo> OperandList;
123 // This might be a multiple operand thing. Targets like X86 have
124 // registers in their multi-operand operands. It may also be an anonymous
125 // operand, which has a single operand, but no declared class for the
126 // operand.
127 const DagInit *MIOI = Op.MIOperandInfo;
129 if (!MIOI || MIOI->getNumArgs() == 0) {
130 // Single, anonymous, operand.
131 OperandList.push_back(Op);
132 } else {
133 for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
134 OperandList.push_back(Op);
136 auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
137 OperandList.back().Rec = OpR;
141 for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
142 const Record *OpR = OperandList[j].Rec;
143 std::string Res;
145 if (OpR->isSubClassOf("RegisterOperand"))
146 OpR = OpR->getValueAsDef("RegClass");
147 if (OpR->isSubClassOf("RegisterClass"))
148 Res += getQualifiedName(OpR) + "RegClassID, ";
149 else if (OpR->isSubClassOf("PointerLikeRegClass"))
150 Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
151 else
152 // -1 means the operand does not have a fixed register class.
153 Res += "-1, ";
155 // Fill in applicable flags.
156 Res += "0";
158 // Ptr value whose register class is resolved via callback.
159 if (OpR->isSubClassOf("PointerLikeRegClass"))
160 Res += "|(1<<MCOI::LookupPtrRegClass)";
162 // Predicate operands. Check to see if the original unexpanded operand
163 // was of type PredicateOp.
164 if (Op.Rec->isSubClassOf("PredicateOp"))
165 Res += "|(1<<MCOI::Predicate)";
167 // Optional def operands. Check to see if the original unexpanded operand
168 // was of type OptionalDefOperand.
169 if (Op.Rec->isSubClassOf("OptionalDefOperand"))
170 Res += "|(1<<MCOI::OptionalDef)";
172 // Branch target operands. Check to see if the original unexpanded
173 // operand was of type BranchTargetOperand.
174 if (Op.Rec->isSubClassOf("BranchTargetOperand"))
175 Res += "|(1<<MCOI::BranchTarget)";
177 // Fill in operand type.
178 Res += ", ";
179 assert(!Op.OperandType.empty() && "Invalid operand type.");
180 Res += Op.OperandType;
182 // Fill in constraint info.
183 Res += ", ";
185 const CGIOperandList::ConstraintInfo &Constraint = Op.Constraints[j];
186 if (Constraint.isNone())
187 Res += "0";
188 else if (Constraint.isEarlyClobber())
189 Res += "MCOI_EARLY_CLOBBER";
190 else {
191 assert(Constraint.isTied());
192 Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
195 Result.push_back(Res);
199 return Result;
202 unsigned
203 InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList,
204 OperandInfoMapTy &OperandInfoMap) {
205 const CodeGenTarget &Target = CDP.getTargetInfo();
206 unsigned Offset = 0;
207 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
208 OperandInfoTy OperandInfo = GetOperandInfo(*Inst);
209 if (OperandInfoMap.insert({OperandInfo, Offset}).second) {
210 OperandInfoList.push_back(OperandInfo);
211 Offset += OperandInfo.size();
214 return Offset;
217 void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
218 OperandInfoListTy &OperandInfoList) {
219 unsigned Offset = 0;
220 for (auto &OperandInfo : OperandInfoList) {
221 OS << " /* " << Offset << " */";
222 for (auto &Info : OperandInfo)
223 OS << " { " << Info << " },";
224 OS << '\n';
225 Offset += OperandInfo.size();
229 /// Generate a table and function for looking up the indices of operands by
230 /// name.
232 /// This code generates:
233 /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
234 /// for each operand name.
235 /// - A 2-dimensional table called OperandMap for mapping OpName enum values to
236 /// operand indices.
237 /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
238 /// for looking up the operand index for an instruction, given a value from
239 /// OpName enum
240 void InstrInfoEmitter::emitOperandNameMappings(
241 raw_ostream &OS, const CodeGenTarget &Target,
242 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
243 StringRef Namespace = Target.getInstNamespace();
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.
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;
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;
261 // Max operand index seen.
262 unsigned MaxOperandNo = 0;
264 for (const CodeGenInstruction *Inst : NumberedInstructions) {
265 if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
266 continue;
267 std::map<unsigned, unsigned> OpList;
268 for (const auto &Info : Inst->Operands) {
269 unsigned ID =
270 OperandNameToID.try_emplace(Info.Name, OperandNameToID.size())
271 .first->second;
272 OpList[ID] = Info.MIOperandNo;
273 MaxOperandNo = std::max(MaxOperandNo, Info.MIOperandNo);
275 OperandMap[OpList].push_back(Inst->TheDef->getName());
278 const size_t NumOperandNames = OperandNameToID.size();
279 OperandEnumToID.reserve(NumOperandNames);
280 for (const auto &Op : OperandNameToID)
281 OperandEnumToID.push_back(Op.second);
283 OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
284 OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
285 OS << "namespace llvm::" << Namespace << "::OpName {\n";
286 OS << "enum {\n";
287 for (const auto &[I, Op] : enumerate(OperandNameToID))
288 OS << " " << Op.first << " = " << I << ",\n";
289 OS << "};\n";
290 OS << "} // end namespace llvm::" << Namespace << "::OpName\n";
291 OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
293 OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
294 OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
295 OS << "namespace llvm::" << Namespace << " {\n";
296 OS << "LLVM_READONLY\n";
297 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
298 if (NumOperandNames != 0) {
299 assert(MaxOperandNo <= INT16_MAX &&
300 "Too many operands for the operand name -> index table");
301 StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
302 OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames
303 << "] = {\n";
304 for (const auto &Entry : OperandMap) {
305 const std::map<unsigned, unsigned> &OpList = Entry.first;
307 // Emit a row of the OperandMap table.
308 OS << " {";
309 for (unsigned ID : OperandEnumToID) {
310 auto Iter = OpList.find(ID);
311 OS << (Iter != OpList.end() ? (int)Iter->second : -1) << ", ";
313 OS << "},\n";
315 OS << " };\n";
317 OS << " switch(Opcode) {\n";
318 for (const auto &[TableIndex, Entry] : enumerate(OperandMap)) {
319 for (StringRef Name : Entry.second)
320 OS << " case " << Namespace << "::" << Name << ":\n";
321 OS << " return OperandMap[" << TableIndex << "][NamedIdx];\n";
323 OS << " default: return -1;\n";
324 OS << " }\n";
325 } else {
326 // There are no operands, so no need to emit anything
327 OS << " return -1;\n";
329 OS << "}\n";
330 OS << "} // end namespace llvm::" << Namespace << "\n";
331 OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
334 /// Generate an enum for all the operand types for this target, under the
335 /// llvm::TargetNamespace::OpTypes namespace.
336 /// Operand types are all definitions derived of the Operand Target.td class.
337 void InstrInfoEmitter::emitOperandTypeMappings(
338 raw_ostream &OS, const CodeGenTarget &Target,
339 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
341 StringRef Namespace = Target.getInstNamespace();
342 ArrayRef<const Record *> Operands =
343 Records.getAllDerivedDefinitions("Operand");
344 ArrayRef<const Record *> RegisterOperands =
345 Records.getAllDerivedDefinitions("RegisterOperand");
346 ArrayRef<const Record *> RegisterClasses =
347 Records.getAllDerivedDefinitions("RegisterClass");
349 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
350 OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
351 OS << "namespace llvm::" << Namespace << "::OpTypes {\n";
352 OS << "enum OperandType {\n";
354 unsigned EnumVal = 0;
355 for (ArrayRef<const Record *> RecordsToAdd :
356 {Operands, RegisterOperands, RegisterClasses}) {
357 for (const Record *Op : RecordsToAdd) {
358 if (!Op->isAnonymous())
359 OS << " " << Op->getName() << " = " << EnumVal << ",\n";
360 ++EnumVal;
364 OS << " OPERAND_TYPE_LIST_END"
365 << "\n};\n";
366 OS << "} // end namespace llvm::" << Namespace << "::OpTypes\n";
367 OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
369 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
370 OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
371 OS << "namespace llvm::" << Namespace << " {\n";
372 OS << "LLVM_READONLY\n";
373 OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
374 auto getInstrName = [&](int I) -> StringRef {
375 return NumberedInstructions[I]->TheDef->getName();
377 // TODO: Factor out duplicate operand lists to compress the tables.
378 if (!NumberedInstructions.empty()) {
379 std::vector<int> OperandOffsets;
380 std::vector<const Record *> OperandRecords;
381 int CurrentOffset = 0;
382 for (const CodeGenInstruction *Inst : NumberedInstructions) {
383 OperandOffsets.push_back(CurrentOffset);
384 for (const auto &Op : Inst->Operands) {
385 const DagInit *MIOI = Op.MIOperandInfo;
386 if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
387 // Single, anonymous, operand.
388 OperandRecords.push_back(Op.Rec);
389 ++CurrentOffset;
390 } else {
391 for (const Init *Arg : MIOI->getArgs()) {
392 OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
393 ++CurrentOffset;
399 // Emit the table of offsets (indexes) into the operand type table.
400 // Size the unsigned integer offset to save space.
401 assert(OperandRecords.size() <= UINT32_MAX &&
402 "Too many operands for offset table");
403 OS << " static const " << getMinimalTypeForRange(OperandRecords.size());
404 OS << " Offsets[] = {\n";
405 for (int I = 0, E = OperandOffsets.size(); I != E; ++I) {
406 OS << " /* " << getInstrName(I) << " */\n";
407 OS << " " << OperandOffsets[I] << ",\n";
409 OS << " };\n";
411 // Add an entry for the end so that we don't need to special case it below.
412 OperandOffsets.push_back(OperandRecords.size());
414 // Emit the actual operand types in a flat table.
415 // Size the signed integer operand type to save space.
416 assert(EnumVal <= INT16_MAX &&
417 "Too many operand types for operand types table");
418 OS << "\n using namespace OpTypes;\n";
419 OS << " static";
420 OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t");
421 OS << " OpcodeOperandTypes[] = {\n ";
422 for (int I = 0, E = OperandRecords.size(), CurOffset = 0; I != E; ++I) {
423 // We print each Opcode's operands in its own row.
424 if (I == OperandOffsets[CurOffset]) {
425 OS << "\n /* " << getInstrName(CurOffset) << " */\n ";
426 while (OperandOffsets[++CurOffset] == I)
427 OS << "/* " << getInstrName(CurOffset) << " */\n ";
429 const Record *OpR = OperandRecords[I];
430 if ((OpR->isSubClassOf("Operand") ||
431 OpR->isSubClassOf("RegisterOperand") ||
432 OpR->isSubClassOf("RegisterClass")) &&
433 !OpR->isAnonymous())
434 OS << OpR->getName();
435 else
436 OS << -1;
437 OS << ", ";
439 OS << "\n };\n";
441 OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
442 } else {
443 OS << " llvm_unreachable(\"No instructions defined\");\n";
445 OS << "}\n";
446 OS << "} // end namespace llvm::" << Namespace << "\n";
447 OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
449 OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
450 OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
451 OS << "namespace llvm::" << Namespace << " {\n";
452 OS << "LLVM_READONLY\n";
453 OS << "static int getMemOperandSize(int OpType) {\n";
454 OS << " switch (OpType) {\n";
455 std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
456 for (const Record *Op : Operands) {
457 if (!Op->isSubClassOf("X86MemOperand"))
458 continue;
459 if (int Size = Op->getValueAsInt("Size"))
460 SizeToOperandName[Size].push_back(Op->getName());
462 OS << " default: return 0;\n";
463 for (const auto &KV : SizeToOperandName) {
464 for (const StringRef &OperandName : KV.second)
465 OS << " case OpTypes::" << OperandName << ":\n";
466 OS << " return " << KV.first << ";\n\n";
468 OS << " }\n}\n";
469 OS << "} // end namespace llvm::" << Namespace << "\n";
470 OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n";
473 void InstrInfoEmitter::emitLogicalOperandSizeMappings(
474 raw_ostream &OS, StringRef Namespace,
475 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
476 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
478 std::map<unsigned, std::vector<std::string>> InstMap;
480 size_t LogicalOpListSize = 0U;
481 std::vector<unsigned> LogicalOpList;
482 for (const auto *Inst : NumberedInstructions) {
483 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
484 continue;
486 LogicalOpList.clear();
487 llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList),
488 [](const CGIOperandList::OperandInfo &Op) -> unsigned {
489 auto *MIOI = Op.MIOperandInfo;
490 if (!MIOI || MIOI->getNumArgs() == 0)
491 return 1;
492 return MIOI->getNumArgs();
494 LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize);
496 auto I =
497 LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first;
498 InstMap[I->second].push_back(
499 (Namespace + "::" + Inst->TheDef->getName()).str());
502 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
503 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
504 OS << "namespace llvm::" << Namespace << " {\n";
505 OS << "LLVM_READONLY static unsigned\n";
506 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
507 if (!InstMap.empty()) {
508 std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
509 LogicalOpSizeMap.size());
510 for (auto &P : LogicalOpSizeMap) {
511 LogicalOpSizeList[P.second] = &P.first;
513 OS << " static const unsigned SizeMap[][" << LogicalOpListSize
514 << "] = {\n";
515 for (auto &R : LogicalOpSizeList) {
516 const auto &Row = *R;
517 OS << " {";
518 int i;
519 for (i = 0; i < static_cast<int>(Row.size()); ++i) {
520 OS << Row[i] << ", ";
522 for (; i < static_cast<int>(LogicalOpListSize); ++i) {
523 OS << "0, ";
525 OS << "}, ";
526 OS << "\n";
528 OS << " };\n";
530 OS << " switch (Opcode) {\n";
531 OS << " default: return LogicalOpIdx;\n";
532 for (auto &P : InstMap) {
533 auto OpMapIdx = P.first;
534 const auto &Insts = P.second;
535 for (const auto &Inst : Insts) {
536 OS << " case " << Inst << ":\n";
538 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
540 OS << " }\n";
541 } else {
542 OS << " return LogicalOpIdx;\n";
544 OS << "}\n";
546 OS << "LLVM_READONLY static inline unsigned\n";
547 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
548 OS << " auto S = 0U;\n";
549 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
550 OS << " S += getLogicalOperandSize(Opcode, i);\n";
551 OS << " return S;\n";
552 OS << "}\n";
554 OS << "} // end namespace llvm::" << Namespace << "\n";
555 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
558 void InstrInfoEmitter::emitLogicalOperandTypeMappings(
559 raw_ostream &OS, StringRef Namespace,
560 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
561 std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap;
563 std::map<unsigned, std::vector<std::string>> InstMap;
565 size_t OpTypeListSize = 0U;
566 std::vector<std::string> LogicalOpTypeList;
567 for (const auto *Inst : NumberedInstructions) {
568 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
569 continue;
571 LogicalOpTypeList.clear();
572 for (const auto &Op : Inst->Operands) {
573 auto *OpR = Op.Rec;
574 if ((OpR->isSubClassOf("Operand") ||
575 OpR->isSubClassOf("RegisterOperand") ||
576 OpR->isSubClassOf("RegisterClass")) &&
577 !OpR->isAnonymous()) {
578 LogicalOpTypeList.push_back(
579 (Namespace + "::OpTypes::" + Op.Rec->getName()).str());
580 } else {
581 LogicalOpTypeList.push_back("-1");
584 OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize);
586 auto I =
587 LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()})
588 .first;
589 InstMap[I->second].push_back(
590 (Namespace + "::" + Inst->TheDef->getName()).str());
593 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
594 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
595 OS << "namespace llvm::" << Namespace << " {\n";
596 OS << "LLVM_READONLY static int\n";
597 OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
598 if (!InstMap.empty()) {
599 std::vector<const std::vector<std::string> *> LogicalOpTypeList(
600 LogicalOpTypeMap.size());
601 for (auto &P : LogicalOpTypeMap) {
602 LogicalOpTypeList[P.second] = &P.first;
604 OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n";
605 for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) {
606 const auto &Row = *LogicalOpTypeList[r];
607 OS << " {";
608 int i, s = Row.size();
609 for (i = 0; i < s; ++i) {
610 if (i > 0)
611 OS << ", ";
612 OS << Row[i];
614 for (; i < static_cast<int>(OpTypeListSize); ++i) {
615 if (i > 0)
616 OS << ", ";
617 OS << "-1";
619 OS << "}";
620 if (r != rs - 1)
621 OS << ",";
622 OS << "\n";
624 OS << " };\n";
626 OS << " switch (Opcode) {\n";
627 OS << " default: return -1;\n";
628 for (auto &P : InstMap) {
629 auto OpMapIdx = P.first;
630 const auto &Insts = P.second;
631 for (const auto &Inst : Insts) {
632 OS << " case " << Inst << ":\n";
634 OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
636 OS << " }\n";
637 } else {
638 OS << " return -1;\n";
640 OS << "}\n";
641 OS << "} // end namespace llvm::" << Namespace << "\n";
642 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n";
645 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
646 StringRef TargetName) {
647 ArrayRef<const Record *> TIIPredicates =
648 Records.getAllDerivedDefinitions("TIIPredicate");
650 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
651 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
653 OS << "namespace llvm {\n";
654 OS << "class MCInst;\n";
655 OS << "class FeatureBitset;\n\n";
657 OS << "namespace " << TargetName << "_MC {\n\n";
659 for (const Record *Rec : TIIPredicates) {
660 OS << "bool " << Rec->getValueAsString("FunctionName")
661 << "(const MCInst &MI);\n";
664 OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
665 "&Features);\n";
667 OS << "\n} // end namespace " << TargetName << "_MC\n";
668 OS << "} // end namespace llvm\n\n";
670 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
672 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
673 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
675 OS << "namespace llvm::" << TargetName << "_MC {\n";
677 PredicateExpander PE(TargetName);
678 PE.setExpandForMC(true);
680 for (const Record *Rec : TIIPredicates) {
681 OS << "bool " << Rec->getValueAsString("FunctionName");
682 OS << "(const MCInst &MI) {\n";
684 OS << PE.getIndent();
685 PE.expandStatement(OS, Rec->getValueAsDef("Body"));
686 OS << "\n}\n\n";
689 OS << "} // end namespace llvm::" << TargetName << "_MC\n";
691 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
694 static std::string
695 getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset) {
696 std::string Name = "CEFBS";
697 for (const Record *Feature : FeatureBitset)
698 Name += ("_" + Feature->getName()).str();
699 return Name;
702 void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
703 const CodeGenTarget &Target) {
704 const auto &All = SubtargetFeatureInfo::getAll(Records);
705 SubtargetFeatureInfoMap SubtargetFeatures;
706 SubtargetFeatures.insert(All.begin(), All.end());
708 OS << "#if (defined(ENABLE_INSTR_PREDICATE_VERIFIER) && !defined(NDEBUG)) "
709 << "||\\\n"
710 << " defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
711 << "#define GET_COMPUTE_FEATURES\n"
712 << "#endif\n";
713 OS << "#ifdef GET_COMPUTE_FEATURES\n"
714 << "#undef GET_COMPUTE_FEATURES\n"
715 << "namespace llvm::" << Target.getName() << "_MC {\n";
717 // Emit the subtarget feature enumeration.
718 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
719 OS);
720 // Emit the available features compute function.
721 OS << "inline ";
722 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
723 Target.getName(), "", "computeAvailableFeatures", SubtargetFeatures, OS);
725 std::vector<std::vector<const Record *>> FeatureBitsets;
726 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
727 FeatureBitsets.emplace_back();
728 for (const Record *Predicate :
729 Inst->TheDef->getValueAsListOfDefs("Predicates")) {
730 const auto &I = SubtargetFeatures.find(Predicate);
731 if (I != SubtargetFeatures.end())
732 FeatureBitsets.back().push_back(I->second.TheDef);
736 llvm::sort(FeatureBitsets, [&](ArrayRef<const Record *> A,
737 ArrayRef<const Record *> B) {
738 if (A.size() < B.size())
739 return true;
740 if (A.size() > B.size())
741 return false;
742 for (auto Pair : zip(A, B)) {
743 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
744 return true;
745 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
746 return false;
748 return false;
750 FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());
751 OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
752 << " enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
753 << " CEFBS_None,\n";
754 for (const auto &FeatureBitset : FeatureBitsets) {
755 if (FeatureBitset.empty())
756 continue;
757 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
759 OS << " };\n\n"
760 << " static constexpr FeatureBitset FeatureBitsets[] = {\n"
761 << " {}, // CEFBS_None\n";
762 for (const auto &FeatureBitset : FeatureBitsets) {
763 if (FeatureBitset.empty())
764 continue;
765 OS << " {";
766 for (const auto &Feature : FeatureBitset) {
767 const auto &I = SubtargetFeatures.find(Feature);
768 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
769 OS << I->second.getEnumBitName() << ", ";
771 OS << "},\n";
773 OS << " };\n"
774 << " static constexpr " << getMinimalTypeForRange(FeatureBitsets.size())
775 << " RequiredFeaturesRefs[] = {\n";
776 unsigned InstIdx = 0;
777 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
778 OS << " CEFBS";
779 unsigned NumPredicates = 0;
780 for (const Record *Predicate :
781 Inst->TheDef->getValueAsListOfDefs("Predicates")) {
782 const auto &I = SubtargetFeatures.find(Predicate);
783 if (I != SubtargetFeatures.end()) {
784 OS << '_' << I->second.TheDef->getName();
785 NumPredicates++;
788 if (!NumPredicates)
789 OS << "_None";
790 OS << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
791 InstIdx++;
793 OS << " };\n\n"
794 << " assert(Opcode < " << InstIdx << ");\n"
795 << " return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
796 << "}\n\n";
798 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
799 << "#endif // GET_COMPUTE_FEATURES\n\n";
801 OS << "#ifdef GET_AVAILABLE_OPCODE_CHECKER\n"
802 << "#undef GET_AVAILABLE_OPCODE_CHECKER\n"
803 << "namespace llvm::" << Target.getName() << "_MC {\n";
804 OS << "bool isOpcodeAvailable("
805 << "unsigned Opcode, const FeatureBitset &Features) {\n"
806 << " FeatureBitset AvailableFeatures = "
807 << "computeAvailableFeatures(Features);\n"
808 << " FeatureBitset RequiredFeatures = "
809 << "computeRequiredFeatures(Opcode);\n"
810 << " FeatureBitset MissingFeatures =\n"
811 << " (AvailableFeatures & RequiredFeatures) ^\n"
812 << " RequiredFeatures;\n"
813 << " return !MissingFeatures.any();\n"
814 << "}\n";
815 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
816 << "#endif // GET_AVAILABLE_OPCODE_CHECKER\n\n";
818 OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
819 << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
820 << "#include <sstream>\n\n";
822 OS << "namespace llvm::" << Target.getName() << "_MC {\n";
824 // Emit the name table for error messages.
825 OS << "#ifndef NDEBUG\n";
826 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
827 OS << "#endif // NDEBUG\n\n";
829 // Emit the predicate verifier.
830 OS << "void verifyInstructionPredicates(\n"
831 << " unsigned Opcode, const FeatureBitset &Features) {\n"
832 << "#ifndef NDEBUG\n";
833 OS << " FeatureBitset AvailableFeatures = "
834 "computeAvailableFeatures(Features);\n";
835 OS << " FeatureBitset RequiredFeatures = "
836 << "computeRequiredFeatures(Opcode);\n";
837 OS << " FeatureBitset MissingFeatures =\n"
838 << " (AvailableFeatures & RequiredFeatures) ^\n"
839 << " RequiredFeatures;\n"
840 << " if (MissingFeatures.any()) {\n"
841 << " std::ostringstream Msg;\n"
842 << " Msg << \"Attempting to emit \" << &" << Target.getName()
843 << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
844 << " << \" instruction but the \";\n"
845 << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
846 << " if (MissingFeatures.test(i))\n"
847 << " Msg << SubtargetFeatureNames[i] << \" \";\n"
848 << " Msg << \"predicate(s) are not met\";\n"
849 << " report_fatal_error(Msg.str().c_str());\n"
850 << " }\n"
851 << "#endif // NDEBUG\n";
852 OS << "}\n";
853 OS << "} // end namespace llvm::" << Target.getName() << "_MC\n";
854 OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
857 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
858 StringRef TargetName,
859 bool ExpandDefinition) {
860 ArrayRef<const Record *> TIIPredicates =
861 Records.getAllDerivedDefinitions("TIIPredicate");
862 if (TIIPredicates.empty())
863 return;
865 PredicateExpander PE(TargetName);
866 PE.setExpandForMC(false);
868 for (const Record *Rec : TIIPredicates) {
869 OS << (ExpandDefinition ? "" : "static ") << "bool ";
870 if (ExpandDefinition)
871 OS << TargetName << "InstrInfo::";
872 OS << Rec->getValueAsString("FunctionName");
873 OS << "(const MachineInstr &MI)";
874 if (!ExpandDefinition) {
875 OS << ";\n";
876 continue;
879 OS << " {\n";
880 OS << PE.getIndent();
881 PE.expandStatement(OS, Rec->getValueAsDef("Body"));
882 OS << "\n}\n\n";
886 //===----------------------------------------------------------------------===//
887 // Main Output.
888 //===----------------------------------------------------------------------===//
890 // run - Emit the main instruction description records for the target...
891 void InstrInfoEmitter::run(raw_ostream &OS) {
892 emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);
893 emitEnums(OS);
895 const CodeGenTarget &Target = CDP.getTargetInfo();
896 const std::string &TargetName = std::string(Target.getName());
897 const Record *InstrInfo = Target.getInstructionSet();
899 // Collect all of the operand info records.
900 TGTimer &Timer = Records.getTimer();
901 Timer.startTimer("Collect operand info");
902 OperandInfoListTy OperandInfoList;
903 OperandInfoMapTy OperandInfoMap;
904 unsigned OperandInfoSize =
905 CollectOperandInfo(OperandInfoList, OperandInfoMap);
907 // Collect all of the instruction's implicit uses and defs.
908 Timer.startTimer("Collect uses/defs");
909 std::map<std::vector<const Record *>, unsigned> EmittedLists;
910 std::vector<std::vector<const Record *>> ImplicitLists;
911 unsigned ImplicitListSize = 0;
912 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
913 std::vector<const Record *> ImplicitOps = II->ImplicitUses;
914 llvm::append_range(ImplicitOps, II->ImplicitDefs);
915 if (EmittedLists.insert({ImplicitOps, ImplicitListSize}).second) {
916 ImplicitLists.push_back(ImplicitOps);
917 ImplicitListSize += ImplicitOps.size();
921 ArrayRef<const CodeGenInstruction *> NumberedInstructions =
922 Target.getInstructionsByEnumValue();
923 OS << "#if defined(GET_INSTRINFO_MC_DESC) || "
924 "defined(GET_INSTRINFO_CTOR_DTOR)\n";
925 OS << "namespace llvm {\n\n";
927 OS << "struct " << TargetName << "InstrTable {\n";
928 OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
929 OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
930 "\"Unwanted padding between Insts and OperandInfo\");\n";
931 OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
932 OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), "
933 "\"Unwanted padding between OperandInfo and ImplicitOps\");\n";
934 OS << " MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n";
935 OS << "};\n\n";
937 OS << "} // end namespace llvm\n";
938 OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
939 "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
941 OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
942 OS << "#undef GET_INSTRINFO_MC_DESC\n";
943 OS << "namespace llvm {\n\n";
945 // Emit all of the MCInstrDesc records in reverse ENUM ordering.
946 Timer.startTimer("Emit InstrDesc records");
947 OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
948 OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
949 << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
951 OS << "extern const " << TargetName << "InstrTable " << TargetName
952 << "Descs = {\n {\n";
953 SequenceToOffsetTable<std::string> InstrNames;
954 unsigned Num = NumberedInstructions.size();
955 for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
956 // Keep a list of the instruction names.
957 InstrNames.add(std::string(Inst->TheDef->getName()));
958 // Emit the record into the table.
959 emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
962 OS << " }, {\n";
964 // Emit all of the operand info records.
965 Timer.startTimer("Emit operand info");
966 EmitOperandInfo(OS, OperandInfoList);
968 OS << " }, {\n";
970 // Emit all of the instruction's implicit uses and defs.
971 Timer.startTimer("Emit uses/defs");
972 for (auto &List : ImplicitLists) {
973 OS << " /* " << EmittedLists[List] << " */";
974 for (auto &Reg : List)
975 OS << ' ' << getQualifiedName(Reg) << ',';
976 OS << '\n';
979 OS << " }\n};\n\n";
981 // Emit the array of instruction names.
982 Timer.startTimer("Emit instruction names");
983 InstrNames.layout();
984 InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
985 "InstrNameData[]");
987 OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
988 Num = 0;
989 for (const CodeGenInstruction *Inst : NumberedInstructions) {
990 // Newline every eight entries.
991 if (Num % 8 == 0)
992 OS << "\n ";
993 OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, ";
994 ++Num;
996 OS << "\n};\n\n";
998 bool HasDeprecationFeatures =
999 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
1000 return !Inst->HasComplexDeprecationPredicate &&
1001 !Inst->DeprecatedReason.empty();
1003 if (HasDeprecationFeatures) {
1004 OS << "extern const uint8_t " << TargetName
1005 << "InstrDeprecationFeatures[] = {";
1006 Num = 0;
1007 for (const CodeGenInstruction *Inst : NumberedInstructions) {
1008 if (Num % 8 == 0)
1009 OS << "\n ";
1010 if (!Inst->HasComplexDeprecationPredicate &&
1011 !Inst->DeprecatedReason.empty())
1012 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
1013 << ", ";
1014 else
1015 OS << "uint8_t(-1), ";
1016 ++Num;
1018 OS << "\n};\n\n";
1021 bool HasComplexDeprecationInfos =
1022 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
1023 return Inst->HasComplexDeprecationPredicate;
1025 if (HasComplexDeprecationInfos) {
1026 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
1027 << "InstrComplexDeprecationInfos[] = {";
1028 Num = 0;
1029 for (const CodeGenInstruction *Inst : NumberedInstructions) {
1030 if (Num % 8 == 0)
1031 OS << "\n ";
1032 if (Inst->HasComplexDeprecationPredicate)
1033 // Emit a function pointer to the complex predicate method.
1034 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
1035 else
1036 OS << "nullptr, ";
1037 ++Num;
1039 OS << "\n};\n\n";
1042 // MCInstrInfo initialization routine.
1043 Timer.startTimer("Emit initialization routine");
1044 OS << "static inline void Init" << TargetName
1045 << "MCInstrInfo(MCInstrInfo *II) {\n";
1046 OS << " II->InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
1047 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
1048 if (HasDeprecationFeatures)
1049 OS << TargetName << "InstrDeprecationFeatures, ";
1050 else
1051 OS << "nullptr, ";
1052 if (HasComplexDeprecationInfos)
1053 OS << TargetName << "InstrComplexDeprecationInfos, ";
1054 else
1055 OS << "nullptr, ";
1056 OS << NumberedInstructions.size() << ");\n}\n\n";
1058 OS << "} // end namespace llvm\n";
1060 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
1062 // Create a TargetInstrInfo subclass to hide the MC layer initialization.
1063 OS << "#ifdef GET_INSTRINFO_HEADER\n";
1064 OS << "#undef GET_INSTRINFO_HEADER\n";
1066 std::string ClassName = TargetName + "GenInstrInfo";
1067 OS << "namespace llvm {\n";
1068 OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
1069 << " explicit " << ClassName
1070 << "(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, "
1071 "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
1072 << " ~" << ClassName << "() override = default;\n";
1074 OS << "\n};\n} // end namespace llvm\n";
1076 OS << "#endif // GET_INSTRINFO_HEADER\n\n";
1078 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
1079 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
1080 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
1081 OS << "\n";
1082 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
1084 OS << "#ifdef GET_INSTRINFO_HELPERS\n";
1085 OS << "#undef GET_INSTRINFO_HELPERS\n\n";
1086 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
1087 OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
1089 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
1090 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
1092 OS << "namespace llvm {\n";
1093 OS << "extern const " << TargetName << "InstrTable " << TargetName
1094 << "Descs;\n";
1095 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
1096 OS << "extern const char " << TargetName << "InstrNameData[];\n";
1097 if (HasDeprecationFeatures)
1098 OS << "extern const uint8_t " << TargetName
1099 << "InstrDeprecationFeatures[];\n";
1100 if (HasComplexDeprecationInfos)
1101 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
1102 << "InstrComplexDeprecationInfos[];\n";
1103 OS << ClassName << "::" << ClassName
1104 << "(unsigned CFSetupOpcode, unsigned CFDestroyOpcode, unsigned "
1105 "CatchRetOpcode, unsigned ReturnOpcode)\n"
1106 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
1107 "ReturnOpcode) {\n"
1108 << " InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
1109 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
1110 if (HasDeprecationFeatures)
1111 OS << TargetName << "InstrDeprecationFeatures, ";
1112 else
1113 OS << "nullptr, ";
1114 if (HasComplexDeprecationInfos)
1115 OS << TargetName << "InstrComplexDeprecationInfos, ";
1116 else
1117 OS << "nullptr, ";
1118 OS << NumberedInstructions.size() << ");\n}\n";
1119 OS << "} // end namespace llvm\n";
1121 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
1123 Timer.startTimer("Emit operand name mappings");
1124 emitOperandNameMappings(OS, Target, NumberedInstructions);
1126 Timer.startTimer("Emit operand type mappings");
1127 emitOperandTypeMappings(OS, Target, NumberedInstructions);
1129 Timer.startTimer("Emit logical operand size mappings");
1130 emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions);
1132 Timer.startTimer("Emit logical operand type mappings");
1133 emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions);
1135 Timer.startTimer("Emit helper methods");
1136 emitMCIIHelperMethods(OS, TargetName);
1138 Timer.startTimer("Emit verifier methods");
1139 emitFeatureVerifier(OS, Target);
1142 void InstrInfoEmitter::emitRecord(
1143 const CodeGenInstruction &Inst, unsigned Num, const Record *InstrInfo,
1144 std::map<std::vector<const Record *>, unsigned> &EmittedLists,
1145 const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) {
1146 int MinOperands = 0;
1147 if (!Inst.Operands.empty())
1148 // Each logical operand can be multiple MI operands.
1149 MinOperands =
1150 Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands;
1151 // Even the logical output operand may be multiple MI operands.
1152 int DefOperands = 0;
1153 if (Inst.Operands.NumDefs) {
1154 auto &Opnd = Inst.Operands[Inst.Operands.NumDefs - 1];
1155 DefOperands = Opnd.MIOperandNo + Opnd.MINumOperands;
1158 OS << " { ";
1159 OS << Num << ",\t" << MinOperands << ",\t" << DefOperands << ",\t"
1160 << Inst.TheDef->getValueAsInt("Size") << ",\t"
1161 << SchedModels.getSchedClassIdx(Inst) << ",\t";
1163 const CodeGenTarget &Target = CDP.getTargetInfo();
1165 // Emit the implicit use/def list...
1166 OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
1167 std::vector<const Record *> ImplicitOps = Inst.ImplicitUses;
1168 llvm::append_range(ImplicitOps, Inst.ImplicitDefs);
1169 OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps]
1170 << ",\t";
1172 // Emit the operand info offset.
1173 OperandInfoTy OperandInfo = GetOperandInfo(Inst);
1174 OS << OperandInfoMap.find(OperandInfo)->second << ",\t0";
1176 // Emit all of the target independent flags...
1177 if (Inst.isPreISelOpcode)
1178 OS << "|(1ULL<<MCID::PreISelOpcode)";
1179 if (Inst.isPseudo)
1180 OS << "|(1ULL<<MCID::Pseudo)";
1181 if (Inst.isMeta)
1182 OS << "|(1ULL<<MCID::Meta)";
1183 if (Inst.isReturn)
1184 OS << "|(1ULL<<MCID::Return)";
1185 if (Inst.isEHScopeReturn)
1186 OS << "|(1ULL<<MCID::EHScopeReturn)";
1187 if (Inst.isBranch)
1188 OS << "|(1ULL<<MCID::Branch)";
1189 if (Inst.isIndirectBranch)
1190 OS << "|(1ULL<<MCID::IndirectBranch)";
1191 if (Inst.isCompare)
1192 OS << "|(1ULL<<MCID::Compare)";
1193 if (Inst.isMoveImm)
1194 OS << "|(1ULL<<MCID::MoveImm)";
1195 if (Inst.isMoveReg)
1196 OS << "|(1ULL<<MCID::MoveReg)";
1197 if (Inst.isBitcast)
1198 OS << "|(1ULL<<MCID::Bitcast)";
1199 if (Inst.isAdd)
1200 OS << "|(1ULL<<MCID::Add)";
1201 if (Inst.isTrap)
1202 OS << "|(1ULL<<MCID::Trap)";
1203 if (Inst.isSelect)
1204 OS << "|(1ULL<<MCID::Select)";
1205 if (Inst.isBarrier)
1206 OS << "|(1ULL<<MCID::Barrier)";
1207 if (Inst.hasDelaySlot)
1208 OS << "|(1ULL<<MCID::DelaySlot)";
1209 if (Inst.isCall)
1210 OS << "|(1ULL<<MCID::Call)";
1211 if (Inst.canFoldAsLoad)
1212 OS << "|(1ULL<<MCID::FoldableAsLoad)";
1213 if (Inst.mayLoad)
1214 OS << "|(1ULL<<MCID::MayLoad)";
1215 if (Inst.mayStore)
1216 OS << "|(1ULL<<MCID::MayStore)";
1217 if (Inst.mayRaiseFPException)
1218 OS << "|(1ULL<<MCID::MayRaiseFPException)";
1219 if (Inst.isPredicable)
1220 OS << "|(1ULL<<MCID::Predicable)";
1221 if (Inst.isConvertibleToThreeAddress)
1222 OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
1223 if (Inst.isCommutable)
1224 OS << "|(1ULL<<MCID::Commutable)";
1225 if (Inst.isTerminator)
1226 OS << "|(1ULL<<MCID::Terminator)";
1227 if (Inst.isReMaterializable)
1228 OS << "|(1ULL<<MCID::Rematerializable)";
1229 if (Inst.isNotDuplicable)
1230 OS << "|(1ULL<<MCID::NotDuplicable)";
1231 if (Inst.Operands.hasOptionalDef)
1232 OS << "|(1ULL<<MCID::HasOptionalDef)";
1233 if (Inst.usesCustomInserter)
1234 OS << "|(1ULL<<MCID::UsesCustomInserter)";
1235 if (Inst.hasPostISelHook)
1236 OS << "|(1ULL<<MCID::HasPostISelHook)";
1237 if (Inst.Operands.isVariadic)
1238 OS << "|(1ULL<<MCID::Variadic)";
1239 if (Inst.hasSideEffects)
1240 OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
1241 if (Inst.isAsCheapAsAMove)
1242 OS << "|(1ULL<<MCID::CheapAsAMove)";
1243 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
1244 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
1245 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
1246 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
1247 if (Inst.isRegSequence)
1248 OS << "|(1ULL<<MCID::RegSequence)";
1249 if (Inst.isExtractSubreg)
1250 OS << "|(1ULL<<MCID::ExtractSubreg)";
1251 if (Inst.isInsertSubreg)
1252 OS << "|(1ULL<<MCID::InsertSubreg)";
1253 if (Inst.isConvergent)
1254 OS << "|(1ULL<<MCID::Convergent)";
1255 if (Inst.variadicOpsAreDefs)
1256 OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
1257 if (Inst.isAuthenticated)
1258 OS << "|(1ULL<<MCID::Authenticated)";
1260 // Emit all of the target-specific flags...
1261 const BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
1262 if (!TSF)
1263 PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?");
1264 uint64_t Value = 0;
1265 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
1266 if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
1267 Value |= uint64_t(Bit->getValue()) << i;
1268 else
1269 PrintFatalError(Inst.TheDef->getLoc(),
1270 "Invalid TSFlags bit in " + Inst.TheDef->getName());
1272 OS << ", 0x";
1273 OS.write_hex(Value);
1274 OS << "ULL";
1276 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
1279 // emitEnums - Print out enum values for all of the instructions.
1280 void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
1281 OS << "#ifdef GET_INSTRINFO_ENUM\n";
1282 OS << "#undef GET_INSTRINFO_ENUM\n";
1284 const CodeGenTarget &Target = CDP.getTargetInfo();
1285 StringRef Namespace = Target.getInstNamespace();
1287 if (Namespace.empty())
1288 PrintFatalError("No instructions defined!");
1290 OS << "namespace llvm::" << Namespace << " {\n";
1292 OS << " enum {\n";
1293 unsigned Num = 0;
1294 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue())
1295 OS << " " << Inst->TheDef->getName()
1296 << "\t= " << (Num = Target.getInstrIntValue(Inst->TheDef)) << ",\n";
1297 OS << " INSTRUCTION_LIST_END = " << Num + 1 << "\n";
1298 OS << " };\n\n";
1299 OS << "} // end namespace llvm::" << Namespace << "\n";
1300 OS << "#endif // GET_INSTRINFO_ENUM\n\n";
1302 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
1303 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
1304 OS << "namespace llvm::" << Namespace << "::Sched {\n\n";
1305 OS << " enum {\n";
1306 Num = 0;
1307 for (const auto &Class : SchedModels.explicit_classes())
1308 OS << " " << Class.Name << "\t= " << Num++ << ",\n";
1309 OS << " SCHED_LIST_END = " << Num << "\n";
1310 OS << " };\n";
1311 OS << "} // end namespace llvm::" << Namespace << "::Sched\n";
1313 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
1316 static void EmitInstrInfo(const RecordKeeper &Records, raw_ostream &OS) {
1317 TGTimer &Timer = Records.getTimer();
1318 Timer.startTimer("Analyze DAG patterns");
1319 InstrInfoEmitter(Records).run(OS);
1320 Timer.startTimer("Emit map table");
1321 EmitMapTable(Records, OS);
1324 static TableGen::Emitter::Opt X("gen-instr-info", EmitInstrInfo,
1325 "Generate instruction descriptions");