[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / utils / TableGen / InstrInfoEmitter.cpp
blobaee887a906e54387ca810620696d3ca24a1f53eb
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 "CodeGenDAGPatterns.h"
15 #include "CodeGenInstruction.h"
16 #include "CodeGenSchedule.h"
17 #include "CodeGenTarget.h"
18 #include "PredicateExpander.h"
19 #include "SequenceToOffsetTable.h"
20 #include "TableGenBackends.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/TableGen/Error.h"
27 #include "llvm/TableGen/Record.h"
28 #include "llvm/TableGen/TableGenBackend.h"
29 #include <cassert>
30 #include <cstdint>
31 #include <iterator>
32 #include <map>
33 #include <string>
34 #include <utility>
35 #include <vector>
37 using namespace llvm;
39 namespace {
41 class InstrInfoEmitter {
42 RecordKeeper &Records;
43 CodeGenDAGPatterns CDP;
44 const CodeGenSchedModels &SchedModels;
46 public:
47 InstrInfoEmitter(RecordKeeper &R):
48 Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
50 // run - Output the instruction set description.
51 void run(raw_ostream &OS);
53 private:
54 void emitEnums(raw_ostream &OS);
56 typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
58 /// The keys of this map are maps which have OpName enum values as their keys
59 /// and instruction operand indices as their values. The values of this map
60 /// are lists of instruction names.
61 typedef std::map<std::map<unsigned, unsigned>,
62 std::vector<std::string>> OpNameMapTy;
63 typedef std::map<std::string, unsigned>::iterator StrUintMapIter;
65 /// Generate member functions in the target-specific GenInstrInfo class.
66 ///
67 /// This method is used to custom expand TIIPredicate definitions.
68 /// See file llvm/Target/TargetInstPredicates.td for a description of what is
69 /// a TIIPredicate and how to use it.
70 void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
71 bool ExpandDefinition = true);
73 /// Expand TIIPredicate definitions to functions that accept a const MCInst
74 /// reference.
75 void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
76 void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
77 Record *InstrInfo,
78 std::map<std::vector<Record*>, unsigned> &EL,
79 const OperandInfoMapTy &OpInfo,
80 raw_ostream &OS);
81 void emitOperandTypeMappings(
82 raw_ostream &OS, const CodeGenTarget &Target,
83 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
84 void initOperandMapData(
85 ArrayRef<const CodeGenInstruction *> NumberedInstructions,
86 StringRef Namespace,
87 std::map<std::string, unsigned> &Operands,
88 OpNameMapTy &OperandMap);
89 void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
90 ArrayRef<const CodeGenInstruction*> NumberedInstructions);
92 void emitLogicalOperandSizeMappings(
93 raw_ostream &OS, StringRef Namespace,
94 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
95 void emitLogicalOperandTypeMappings(
96 raw_ostream &OS, StringRef Namespace,
97 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
99 // Operand information.
100 void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
101 std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
104 } // end anonymous namespace
106 static void PrintDefList(const std::vector<Record*> &Uses,
107 unsigned Num, raw_ostream &OS) {
108 OS << "static const MCPhysReg ImplicitList" << Num << "[] = { ";
109 for (Record *U : Uses)
110 OS << getQualifiedName(U) << ", ";
111 OS << "0 };\n";
114 //===----------------------------------------------------------------------===//
115 // Operand Info Emission.
116 //===----------------------------------------------------------------------===//
118 std::vector<std::string>
119 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
120 std::vector<std::string> Result;
122 for (auto &Op : Inst.Operands) {
123 // Handle aggregate operands and normal operands the same way by expanding
124 // either case into a list of operands for this op.
125 std::vector<CGIOperandList::OperandInfo> OperandList;
127 // This might be a multiple operand thing. Targets like X86 have
128 // registers in their multi-operand operands. It may also be an anonymous
129 // operand, which has a single operand, but no declared class for the
130 // operand.
131 DagInit *MIOI = Op.MIOperandInfo;
133 if (!MIOI || MIOI->getNumArgs() == 0) {
134 // Single, anonymous, operand.
135 OperandList.push_back(Op);
136 } else {
137 for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
138 OperandList.push_back(Op);
140 auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
141 OperandList.back().Rec = OpR;
145 for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
146 Record *OpR = OperandList[j].Rec;
147 std::string Res;
149 if (OpR->isSubClassOf("RegisterOperand"))
150 OpR = OpR->getValueAsDef("RegClass");
151 if (OpR->isSubClassOf("RegisterClass"))
152 Res += getQualifiedName(OpR) + "RegClassID, ";
153 else if (OpR->isSubClassOf("PointerLikeRegClass"))
154 Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
155 else
156 // -1 means the operand does not have a fixed register class.
157 Res += "-1, ";
159 // Fill in applicable flags.
160 Res += "0";
162 // Ptr value whose register class is resolved via callback.
163 if (OpR->isSubClassOf("PointerLikeRegClass"))
164 Res += "|(1<<MCOI::LookupPtrRegClass)";
166 // Predicate operands. Check to see if the original unexpanded operand
167 // was of type PredicateOp.
168 if (Op.Rec->isSubClassOf("PredicateOp"))
169 Res += "|(1<<MCOI::Predicate)";
171 // Optional def operands. Check to see if the original unexpanded operand
172 // was of type OptionalDefOperand.
173 if (Op.Rec->isSubClassOf("OptionalDefOperand"))
174 Res += "|(1<<MCOI::OptionalDef)";
176 // Branch target operands. Check to see if the original unexpanded
177 // operand was of type BranchTargetOperand.
178 if (Op.Rec->isSubClassOf("BranchTargetOperand"))
179 Res += "|(1<<MCOI::BranchTarget)";
181 // Fill in operand type.
182 Res += ", ";
183 assert(!Op.OperandType.empty() && "Invalid operand type.");
184 Res += Op.OperandType;
186 // Fill in constraint info.
187 Res += ", ";
189 const CGIOperandList::ConstraintInfo &Constraint =
190 Op.Constraints[j];
191 if (Constraint.isNone())
192 Res += "0";
193 else if (Constraint.isEarlyClobber())
194 Res += "MCOI_EARLY_CLOBBER";
195 else {
196 assert(Constraint.isTied());
197 Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
200 Result.push_back(Res);
204 return Result;
207 void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
208 OperandInfoMapTy &OperandInfoIDs) {
209 // ID #0 is for no operand info.
210 unsigned OperandListNum = 0;
211 OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
213 OS << "\n";
214 const CodeGenTarget &Target = CDP.getTargetInfo();
215 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
216 std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
217 unsigned &N = OperandInfoIDs[OperandInfo];
218 if (N != 0) continue;
220 N = ++OperandListNum;
221 OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
222 for (const std::string &Info : OperandInfo)
223 OS << "{ " << Info << " }, ";
224 OS << "};\n";
228 /// Initialize data structures for generating operand name mappings.
230 /// \param Operands [out] A map used to generate the OpName enum with operand
231 /// names as its keys and operand enum values as its values.
232 /// \param OperandMap [out] A map for representing the operand name mappings for
233 /// each instructions. This is used to generate the OperandMap table as
234 /// well as the getNamedOperandIdx() function.
235 void InstrInfoEmitter::initOperandMapData(
236 ArrayRef<const CodeGenInstruction *> NumberedInstructions,
237 StringRef Namespace,
238 std::map<std::string, unsigned> &Operands,
239 OpNameMapTy &OperandMap) {
240 unsigned NumOperands = 0;
241 for (const CodeGenInstruction *Inst : NumberedInstructions) {
242 if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
243 continue;
244 std::map<unsigned, unsigned> OpList;
245 for (const auto &Info : Inst->Operands) {
246 StrUintMapIter I = Operands.find(Info.Name);
248 if (I == Operands.end()) {
249 I = Operands.insert(Operands.begin(),
250 std::pair<std::string, unsigned>(Info.Name, NumOperands++));
252 OpList[I->second] = Info.MIOperandNo;
254 OperandMap[OpList].push_back(Namespace.str() + "::" +
255 Inst->TheDef->getName().str());
259 /// Generate a table and function for looking up the indices of operands by
260 /// name.
262 /// This code generates:
263 /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
264 /// for each operand name.
265 /// - A 2-dimensional table called OperandMap for mapping OpName enum values to
266 /// operand indices.
267 /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
268 /// for looking up the operand index for an instruction, given a value from
269 /// OpName enum
270 void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
271 const CodeGenTarget &Target,
272 ArrayRef<const CodeGenInstruction*> NumberedInstructions) {
273 StringRef Namespace = Target.getInstNamespace();
274 std::string OpNameNS = "OpName";
275 // Map of operand names to their enumeration value. This will be used to
276 // generate the OpName enum.
277 std::map<std::string, unsigned> Operands;
278 OpNameMapTy OperandMap;
280 initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap);
282 OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
283 OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
284 OS << "namespace llvm {\n";
285 OS << "namespace " << Namespace << " {\n";
286 OS << "namespace " << OpNameNS << " {\n";
287 OS << "enum {\n";
288 for (const auto &Op : Operands)
289 OS << " " << Op.first << " = " << Op.second << ",\n";
291 OS << " OPERAND_LAST";
292 OS << "\n};\n";
293 OS << "} // end namespace OpName\n";
294 OS << "} // end namespace " << Namespace << "\n";
295 OS << "} // end namespace llvm\n";
296 OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
298 OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
299 OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
300 OS << "namespace llvm {\n";
301 OS << "namespace " << Namespace << " {\n";
302 OS << "LLVM_READONLY\n";
303 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
304 if (!Operands.empty()) {
305 OS << " static const int16_t OperandMap [][" << Operands.size()
306 << "] = {\n";
307 for (const auto &Entry : OperandMap) {
308 const std::map<unsigned, unsigned> &OpList = Entry.first;
309 OS << "{";
311 // Emit a row of the OperandMap table
312 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
313 OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", ";
315 OS << "},\n";
317 OS << "};\n";
319 OS << " switch(Opcode) {\n";
320 unsigned TableIndex = 0;
321 for (const auto &Entry : OperandMap) {
322 for (const std::string &Name : Entry.second)
323 OS << " case " << Name << ":\n";
325 OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
327 OS << " default: return -1;\n";
328 OS << " }\n";
329 } else {
330 // There are no operands, so no need to emit anything
331 OS << " return -1;\n";
333 OS << "}\n";
334 OS << "} // end namespace " << Namespace << "\n";
335 OS << "} // end namespace llvm\n";
336 OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
339 /// Generate an enum for all the operand types for this target, under the
340 /// llvm::TargetNamespace::OpTypes namespace.
341 /// Operand types are all definitions derived of the Operand Target.td class.
342 void InstrInfoEmitter::emitOperandTypeMappings(
343 raw_ostream &OS, const CodeGenTarget &Target,
344 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
346 StringRef Namespace = Target.getInstNamespace();
347 std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
348 std::vector<Record *> RegisterOperands =
349 Records.getAllDerivedDefinitions("RegisterOperand");
350 std::vector<Record *> RegisterClasses =
351 Records.getAllDerivedDefinitions("RegisterClass");
353 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
354 OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
355 OS << "namespace llvm {\n";
356 OS << "namespace " << Namespace << " {\n";
357 OS << "namespace OpTypes {\n";
358 OS << "enum OperandType {\n";
360 unsigned EnumVal = 0;
361 for (const std::vector<Record *> *RecordsToAdd :
362 {&Operands, &RegisterOperands, &RegisterClasses}) {
363 for (const Record *Op : *RecordsToAdd) {
364 if (!Op->isAnonymous())
365 OS << " " << Op->getName() << " = " << EnumVal << ",\n";
366 ++EnumVal;
370 OS << " OPERAND_TYPE_LIST_END" << "\n};\n";
371 OS << "} // end namespace OpTypes\n";
372 OS << "} // end namespace " << Namespace << "\n";
373 OS << "} // end namespace llvm\n";
374 OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
376 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
377 OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
378 OS << "namespace llvm {\n";
379 OS << "namespace " << Namespace << " {\n";
380 OS << "LLVM_READONLY\n";
381 OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
382 // TODO: Factor out duplicate operand lists to compress the tables.
383 if (!NumberedInstructions.empty()) {
384 std::vector<int> OperandOffsets;
385 std::vector<Record *> OperandRecords;
386 int CurrentOffset = 0;
387 for (const CodeGenInstruction *Inst : NumberedInstructions) {
388 OperandOffsets.push_back(CurrentOffset);
389 for (const auto &Op : Inst->Operands) {
390 const DagInit *MIOI = Op.MIOperandInfo;
391 if (!MIOI || MIOI->getNumArgs() == 0) {
392 // Single, anonymous, operand.
393 OperandRecords.push_back(Op.Rec);
394 ++CurrentOffset;
395 } else {
396 for (Init *Arg : MIOI->getArgs()) {
397 OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
398 ++CurrentOffset;
404 // Emit the table of offsets (indexes) into the operand type table.
405 // Size the unsigned integer offset to save space.
406 assert(OperandRecords.size() <= UINT32_MAX &&
407 "Too many operands for offset table");
408 OS << ((OperandRecords.size() <= UINT16_MAX) ? " const uint16_t"
409 : " const uint32_t");
410 OS << " Offsets[] = {\n";
411 for (int I = 0, E = OperandOffsets.size(); I != E; ++I)
412 OS << " " << OperandOffsets[I] << ",\n";
413 OS << " };\n";
415 // Add an entry for the end so that we don't need to special case it below.
416 OperandOffsets.push_back(OperandRecords.size());
418 // Emit the actual operand types in a flat table.
419 // Size the signed integer operand type to save space.
420 assert(EnumVal <= INT16_MAX &&
421 "Too many operand types for operand types table");
422 OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t");
423 OS << " OpcodeOperandTypes[] = {\n ";
424 for (int I = 0, E = OperandRecords.size(), CurOffset = 1; I != E; ++I) {
425 // We print each Opcode's operands in its own row.
426 if (I == OperandOffsets[CurOffset]) {
427 OS << "\n ";
428 // If there are empty rows, mark them with an empty comment.
429 while (OperandOffsets[++CurOffset] == I)
430 OS << "/**/\n ";
432 Record *OpR = OperandRecords[I];
433 if ((OpR->isSubClassOf("Operand") ||
434 OpR->isSubClassOf("RegisterOperand") ||
435 OpR->isSubClassOf("RegisterClass")) &&
436 !OpR->isAnonymous())
437 OS << "OpTypes::" << OpR->getName();
438 else
439 OS << -1;
440 OS << ", ";
442 OS << "\n };\n";
444 OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
445 } else {
446 OS << " llvm_unreachable(\"No instructions defined\");\n";
448 OS << "}\n";
449 OS << "} // end namespace " << Namespace << "\n";
450 OS << "} // end namespace llvm\n";
451 OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
454 void InstrInfoEmitter::emitLogicalOperandSizeMappings(
455 raw_ostream &OS, StringRef Namespace,
456 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
457 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
459 std::map<unsigned, std::vector<std::string>> InstMap;
461 size_t LogicalOpListSize = 0U;
462 std::vector<unsigned> LogicalOpList;
463 for (const auto *Inst : NumberedInstructions) {
464 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
465 continue;
467 LogicalOpList.clear();
468 llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList),
469 [](const CGIOperandList::OperandInfo &Op) -> unsigned {
470 auto *MIOI = Op.MIOperandInfo;
471 if (!MIOI || MIOI->getNumArgs() == 0)
472 return 1;
473 return MIOI->getNumArgs();
475 LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize);
477 auto I =
478 LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first;
479 InstMap[I->second].push_back(
480 (Namespace + "::" + Inst->TheDef->getName()).str());
483 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
484 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
485 OS << "namespace llvm {\n";
486 OS << "namespace " << Namespace << " {\n";
487 OS << "LLVM_READONLY static unsigned\n";
488 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
489 if (!InstMap.empty()) {
490 std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
491 LogicalOpSizeMap.size());
492 for (auto &P : LogicalOpSizeMap) {
493 LogicalOpSizeList[P.second] = &P.first;
495 OS << " static const unsigned SizeMap[][" << LogicalOpListSize
496 << "] = {\n";
497 for (auto &R : LogicalOpSizeList) {
498 const auto &Row = *R;
499 OS << " {";
500 int i;
501 for (i = 0; i < static_cast<int>(Row.size()); ++i) {
502 OS << Row[i] << ", ";
504 for (; i < static_cast<int>(LogicalOpListSize); ++i) {
505 OS << "0, ";
507 OS << "}, ";
508 OS << "\n";
510 OS << " };\n";
512 OS << " switch (Opcode) {\n";
513 OS << " default: return LogicalOpIdx;\n";
514 for (auto &P : InstMap) {
515 auto OpMapIdx = P.first;
516 const auto &Insts = P.second;
517 for (const auto &Inst : Insts) {
518 OS << " case " << Inst << ":\n";
520 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
522 OS << " }\n";
523 } else {
524 OS << " return LogicalOpIdx;\n";
526 OS << "}\n";
528 OS << "LLVM_READONLY static inline unsigned\n";
529 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
530 OS << " auto S = 0U;\n";
531 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
532 OS << " S += getLogicalOperandSize(Opcode, i);\n";
533 OS << " return S;\n";
534 OS << "}\n";
536 OS << "} // end namespace " << Namespace << "\n";
537 OS << "} // end namespace llvm\n";
538 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
541 void InstrInfoEmitter::emitLogicalOperandTypeMappings(
542 raw_ostream &OS, StringRef Namespace,
543 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
544 std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap;
546 std::map<unsigned, std::vector<std::string>> InstMap;
548 size_t OpTypeListSize = 0U;
549 std::vector<std::string> LogicalOpTypeList;
550 for (const auto *Inst : NumberedInstructions) {
551 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
552 continue;
554 LogicalOpTypeList.clear();
555 for (const auto &Op : Inst->Operands) {
556 auto *OpR = Op.Rec;
557 if ((OpR->isSubClassOf("Operand") ||
558 OpR->isSubClassOf("RegisterOperand") ||
559 OpR->isSubClassOf("RegisterClass")) &&
560 !OpR->isAnonymous()) {
561 LogicalOpTypeList.push_back(
562 (Namespace + "::OpTypes::" + Op.Rec->getName()).str());
563 } else {
564 LogicalOpTypeList.push_back("-1");
567 OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize);
569 auto I =
570 LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()})
571 .first;
572 InstMap[I->second].push_back(
573 (Namespace + "::" + Inst->TheDef->getName()).str());
576 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
577 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
578 OS << "namespace llvm {\n";
579 OS << "namespace " << Namespace << " {\n";
580 OS << "LLVM_READONLY static int\n";
581 OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
582 if (!InstMap.empty()) {
583 std::vector<const std::vector<std::string> *> LogicalOpTypeList(
584 LogicalOpTypeMap.size());
585 for (auto &P : LogicalOpTypeMap) {
586 LogicalOpTypeList[P.second] = &P.first;
588 OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n";
589 for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) {
590 const auto &Row = *LogicalOpTypeList[r];
591 OS << " {";
592 int i, s = Row.size();
593 for (i = 0; i < s; ++i) {
594 if (i > 0)
595 OS << ", ";
596 OS << Row[i];
598 for (; i < static_cast<int>(OpTypeListSize); ++i) {
599 if (i > 0)
600 OS << ", ";
601 OS << "-1";
603 OS << "}";
604 if (r != rs - 1)
605 OS << ",";
606 OS << "\n";
608 OS << " };\n";
610 OS << " switch (Opcode) {\n";
611 OS << " default: return -1;\n";
612 for (auto &P : InstMap) {
613 auto OpMapIdx = P.first;
614 const auto &Insts = P.second;
615 for (const auto &Inst : Insts) {
616 OS << " case " << Inst << ":\n";
618 OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
620 OS << " }\n";
621 } else {
622 OS << " return -1;\n";
624 OS << "}\n";
625 OS << "} // end namespace " << Namespace << "\n";
626 OS << "} // end namespace llvm\n";
627 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n";
630 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
631 StringRef TargetName) {
632 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
633 if (TIIPredicates.empty())
634 return;
636 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
637 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
639 OS << "namespace llvm {\n";
640 OS << "class MCInst;\n\n";
642 OS << "namespace " << TargetName << "_MC {\n\n";
644 for (const Record *Rec : TIIPredicates) {
645 OS << "bool " << Rec->getValueAsString("FunctionName")
646 << "(const MCInst &MI);\n";
649 OS << "\n} // end namespace " << TargetName << "_MC\n";
650 OS << "} // end namespace llvm\n\n";
652 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
654 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
655 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
657 OS << "namespace llvm {\n";
658 OS << "namespace " << TargetName << "_MC {\n\n";
660 PredicateExpander PE(TargetName);
661 PE.setExpandForMC(true);
663 for (const Record *Rec : TIIPredicates) {
664 OS << "bool " << Rec->getValueAsString("FunctionName");
665 OS << "(const MCInst &MI) {\n";
667 OS.indent(PE.getIndentLevel() * 2);
668 PE.expandStatement(OS, Rec->getValueAsDef("Body"));
669 OS << "\n}\n\n";
672 OS << "} // end namespace " << TargetName << "_MC\n";
673 OS << "} // end namespace llvm\n\n";
675 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n";
678 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
679 StringRef TargetName,
680 bool ExpandDefinition) {
681 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
682 if (TIIPredicates.empty())
683 return;
685 PredicateExpander PE(TargetName);
686 PE.setExpandForMC(false);
688 for (const Record *Rec : TIIPredicates) {
689 OS << (ExpandDefinition ? "" : "static ") << "bool ";
690 if (ExpandDefinition)
691 OS << TargetName << "InstrInfo::";
692 OS << Rec->getValueAsString("FunctionName");
693 OS << "(const MachineInstr &MI)";
694 if (!ExpandDefinition) {
695 OS << ";\n";
696 continue;
699 OS << " {\n";
700 OS.indent(PE.getIndentLevel() * 2);
701 PE.expandStatement(OS, Rec->getValueAsDef("Body"));
702 OS << "\n}\n\n";
706 //===----------------------------------------------------------------------===//
707 // Main Output.
708 //===----------------------------------------------------------------------===//
710 // run - Emit the main instruction description records for the target...
711 void InstrInfoEmitter::run(raw_ostream &OS) {
712 emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);
713 emitEnums(OS);
715 OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
716 OS << "#undef GET_INSTRINFO_MC_DESC\n";
718 OS << "namespace llvm {\n\n";
720 CodeGenTarget &Target = CDP.getTargetInfo();
721 const std::string &TargetName = std::string(Target.getName());
722 Record *InstrInfo = Target.getInstructionSet();
724 // Keep track of all of the def lists we have emitted already.
725 std::map<std::vector<Record*>, unsigned> EmittedLists;
726 unsigned ListNumber = 0;
728 // Emit all of the instruction's implicit uses and defs.
729 Records.startTimer("Emit uses/defs");
730 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
731 Record *Inst = II->TheDef;
732 std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
733 if (!Uses.empty()) {
734 unsigned &IL = EmittedLists[Uses];
735 if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
737 std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
738 if (!Defs.empty()) {
739 unsigned &IL = EmittedLists[Defs];
740 if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
744 OperandInfoMapTy OperandInfoIDs;
746 // Emit all of the operand info records.
747 Records.startTimer("Emit operand info");
748 EmitOperandInfo(OS, OperandInfoIDs);
750 // Emit all of the MCInstrDesc records in their ENUM ordering.
752 Records.startTimer("Emit InstrDesc records");
753 OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
754 ArrayRef<const CodeGenInstruction*> NumberedInstructions =
755 Target.getInstructionsByEnumValue();
757 SequenceToOffsetTable<std::string> InstrNames;
758 unsigned Num = 0;
759 for (const CodeGenInstruction *Inst : NumberedInstructions) {
760 // Keep a list of the instruction names.
761 InstrNames.add(std::string(Inst->TheDef->getName()));
762 // Emit the record into the table.
763 emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS);
765 OS << "};\n\n";
767 // Emit the array of instruction names.
768 Records.startTimer("Emit instruction names");
769 InstrNames.layout();
770 InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
771 "InstrNameData[]");
773 OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
774 Num = 0;
775 for (const CodeGenInstruction *Inst : NumberedInstructions) {
776 // Newline every eight entries.
777 if (Num % 8 == 0)
778 OS << "\n ";
779 OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, ";
780 ++Num;
782 OS << "\n};\n\n";
784 bool HasDeprecationFeatures =
785 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
786 return !Inst->HasComplexDeprecationPredicate &&
787 !Inst->DeprecatedReason.empty();
789 if (HasDeprecationFeatures) {
790 OS << "extern const uint8_t " << TargetName
791 << "InstrDeprecationFeatures[] = {";
792 Num = 0;
793 for (const CodeGenInstruction *Inst : NumberedInstructions) {
794 if (Num % 8 == 0)
795 OS << "\n ";
796 if (!Inst->HasComplexDeprecationPredicate &&
797 !Inst->DeprecatedReason.empty())
798 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
799 << ", ";
800 else
801 OS << "uint8_t(-1), ";
802 ++Num;
804 OS << "\n};\n\n";
807 bool HasComplexDeprecationInfos =
808 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
809 return Inst->HasComplexDeprecationPredicate;
811 if (HasComplexDeprecationInfos) {
812 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
813 << "InstrComplexDeprecationInfos[] = {";
814 Num = 0;
815 for (const CodeGenInstruction *Inst : NumberedInstructions) {
816 if (Num % 8 == 0)
817 OS << "\n ";
818 if (Inst->HasComplexDeprecationPredicate)
819 // Emit a function pointer to the complex predicate method.
820 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
821 else
822 OS << "nullptr, ";
823 ++Num;
825 OS << "\n};\n\n";
828 // MCInstrInfo initialization routine.
829 Records.startTimer("Emit initialization routine");
830 OS << "static inline void Init" << TargetName
831 << "MCInstrInfo(MCInstrInfo *II) {\n";
832 OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
833 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
834 if (HasDeprecationFeatures)
835 OS << TargetName << "InstrDeprecationFeatures, ";
836 else
837 OS << "nullptr, ";
838 if (HasComplexDeprecationInfos)
839 OS << TargetName << "InstrComplexDeprecationInfos, ";
840 else
841 OS << "nullptr, ";
842 OS << NumberedInstructions.size() << ");\n}\n\n";
844 OS << "} // end namespace llvm\n";
846 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
848 // Create a TargetInstrInfo subclass to hide the MC layer initialization.
849 OS << "#ifdef GET_INSTRINFO_HEADER\n";
850 OS << "#undef GET_INSTRINFO_HEADER\n";
852 std::string ClassName = TargetName + "GenInstrInfo";
853 OS << "namespace llvm {\n";
854 OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
855 << " explicit " << ClassName
856 << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n"
857 << " ~" << ClassName << "() override = default;\n";
860 OS << "\n};\n} // end namespace llvm\n";
862 OS << "#endif // GET_INSTRINFO_HEADER\n\n";
864 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
865 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
866 emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */false);
867 OS << "\n";
868 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
870 OS << "#ifdef GET_INSTRINFO_HELPERS\n";
871 OS << "#undef GET_INSTRINFO_HELPERS\n\n";
872 emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */true);
873 OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
875 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
876 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
878 OS << "namespace llvm {\n";
879 OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
880 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
881 OS << "extern const char " << TargetName << "InstrNameData[];\n";
882 if (HasDeprecationFeatures)
883 OS << "extern const uint8_t " << TargetName
884 << "InstrDeprecationFeatures[];\n";
885 if (HasComplexDeprecationInfos)
886 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
887 << "InstrComplexDeprecationInfos[];\n";
888 OS << ClassName << "::" << ClassName
889 << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int "
890 "ReturnOpcode)\n"
891 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
892 "ReturnOpcode) {\n"
893 << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
894 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
895 if (HasDeprecationFeatures)
896 OS << TargetName << "InstrDeprecationFeatures, ";
897 else
898 OS << "nullptr, ";
899 if (HasComplexDeprecationInfos)
900 OS << TargetName << "InstrComplexDeprecationInfos, ";
901 else
902 OS << "nullptr, ";
903 OS << NumberedInstructions.size() << ");\n}\n";
904 OS << "} // end namespace llvm\n";
906 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
908 Records.startTimer("Emit operand name mappings");
909 emitOperandNameMappings(OS, Target, NumberedInstructions);
911 Records.startTimer("Emit operand type mappings");
912 emitOperandTypeMappings(OS, Target, NumberedInstructions);
914 Records.startTimer("Emit logical operand size mappings");
915 emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions);
917 Records.startTimer("Emit logical operand type mappings");
918 emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions);
920 Records.startTimer("Emit helper methods");
921 emitMCIIHelperMethods(OS, TargetName);
924 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
925 Record *InstrInfo,
926 std::map<std::vector<Record*>, unsigned> &EmittedLists,
927 const OperandInfoMapTy &OpInfo,
928 raw_ostream &OS) {
929 int MinOperands = 0;
930 if (!Inst.Operands.empty())
931 // Each logical operand can be multiple MI operands.
932 MinOperands = Inst.Operands.back().MIOperandNo +
933 Inst.Operands.back().MINumOperands;
935 OS << " { ";
936 OS << Num << ",\t" << MinOperands << ",\t"
937 << Inst.Operands.NumDefs << ",\t"
938 << Inst.TheDef->getValueAsInt("Size") << ",\t"
939 << SchedModels.getSchedClassIdx(Inst) << ",\t0";
941 CodeGenTarget &Target = CDP.getTargetInfo();
943 // Emit all of the target independent flags...
944 if (Inst.isPreISelOpcode) OS << "|(1ULL<<MCID::PreISelOpcode)";
945 if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)";
946 if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)";
947 if (Inst.isEHScopeReturn) OS << "|(1ULL<<MCID::EHScopeReturn)";
948 if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)";
949 if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)";
950 if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)";
951 if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)";
952 if (Inst.isMoveReg) OS << "|(1ULL<<MCID::MoveReg)";
953 if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)";
954 if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)";
955 if (Inst.isTrap) OS << "|(1ULL<<MCID::Trap)";
956 if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)";
957 if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)";
958 if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)";
959 if (Inst.isCall) OS << "|(1ULL<<MCID::Call)";
960 if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)";
961 if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)";
962 if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)";
963 if (Inst.mayRaiseFPException) OS << "|(1ULL<<MCID::MayRaiseFPException)";
964 if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)";
965 if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
966 if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)";
967 if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)";
968 if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)";
969 if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)";
970 if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)";
971 if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)";
972 if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)";
973 if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)";
974 if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
975 if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)";
976 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
977 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
978 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
979 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
980 if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)";
981 if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)";
982 if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)";
983 if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)";
984 if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
985 if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)";
987 // Emit all of the target-specific flags...
988 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
989 if (!TSF)
990 PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?");
991 uint64_t Value = 0;
992 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
993 if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
994 Value |= uint64_t(Bit->getValue()) << i;
995 else
996 PrintFatalError(Inst.TheDef->getLoc(),
997 "Invalid TSFlags bit in " + Inst.TheDef->getName());
999 OS << ", 0x";
1000 OS.write_hex(Value);
1001 OS << "ULL, ";
1003 // Emit the implicit uses and defs lists...
1004 std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
1005 if (UseList.empty())
1006 OS << "nullptr, ";
1007 else
1008 OS << "ImplicitList" << EmittedLists[UseList] << ", ";
1010 std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
1011 if (DefList.empty())
1012 OS << "nullptr, ";
1013 else
1014 OS << "ImplicitList" << EmittedLists[DefList] << ", ";
1016 // Emit the operand info.
1017 std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
1018 if (OperandInfo.empty())
1019 OS << "nullptr";
1020 else
1021 OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
1023 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
1026 // emitEnums - Print out enum values for all of the instructions.
1027 void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
1028 OS << "#ifdef GET_INSTRINFO_ENUM\n";
1029 OS << "#undef GET_INSTRINFO_ENUM\n";
1031 OS << "namespace llvm {\n\n";
1033 const CodeGenTarget &Target = CDP.getTargetInfo();
1035 // We must emit the PHI opcode first...
1036 StringRef Namespace = Target.getInstNamespace();
1038 if (Namespace.empty())
1039 PrintFatalError("No instructions defined!");
1041 OS << "namespace " << Namespace << " {\n";
1042 OS << " enum {\n";
1043 unsigned Num = 0;
1044 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue())
1045 OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
1046 OS << " INSTRUCTION_LIST_END = " << Num << "\n";
1047 OS << " };\n\n";
1048 OS << "} // end namespace " << Namespace << "\n";
1049 OS << "} // end namespace llvm\n";
1050 OS << "#endif // GET_INSTRINFO_ENUM\n\n";
1052 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
1053 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
1054 OS << "namespace llvm {\n\n";
1055 OS << "namespace " << Namespace << " {\n";
1056 OS << "namespace Sched {\n";
1057 OS << " enum {\n";
1058 Num = 0;
1059 for (const auto &Class : SchedModels.explicit_classes())
1060 OS << " " << Class.Name << "\t= " << Num++ << ",\n";
1061 OS << " SCHED_LIST_END = " << Num << "\n";
1062 OS << " };\n";
1063 OS << "} // end namespace Sched\n";
1064 OS << "} // end namespace " << Namespace << "\n";
1065 OS << "} // end namespace llvm\n";
1067 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
1070 namespace llvm {
1072 void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
1073 RK.startTimer("Analyze DAG patterns");
1074 InstrInfoEmitter(RK).run(OS);
1075 RK.startTimer("Emit map table");
1076 EmitMapTable(RK, OS);
1079 } // end namespace llvm