1 //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
41 class InstrInfoEmitter
{
42 RecordKeeper
&Records
;
43 CodeGenDAGPatterns CDP
;
44 const CodeGenSchedModels
&SchedModels
;
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
);
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.
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
75 void emitMCIIHelperMethods(raw_ostream
&OS
, StringRef TargetName
);
76 void emitRecord(const CodeGenInstruction
&Inst
, unsigned Num
,
78 std::map
<std::vector
<Record
*>, unsigned> &EL
,
79 const OperandInfoMapTy
&OpInfo
,
81 void emitOperandTypeMappings(
82 raw_ostream
&OS
, const CodeGenTarget
&Target
,
83 ArrayRef
<const CodeGenInstruction
*> NumberedInstructions
);
84 void initOperandMapData(
85 ArrayRef
<const CodeGenInstruction
*> NumberedInstructions
,
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
) << ", ";
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
131 DagInit
*MIOI
= Op
.MIOperandInfo
;
133 if (!MIOI
|| MIOI
->getNumArgs() == 0) {
134 // Single, anonymous, operand.
135 OperandList
.push_back(Op
);
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
;
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")) + ", ";
156 // -1 means the operand does not have a fixed register class.
159 // Fill in applicable flags.
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.
183 assert(!Op
.OperandType
.empty() && "Invalid operand type.");
184 Res
+= Op
.OperandType
;
186 // Fill in constraint info.
189 const CGIOperandList::ConstraintInfo
&Constraint
=
191 if (Constraint
.isNone())
193 else if (Constraint
.isEarlyClobber())
194 Res
+= "MCOI_EARLY_CLOBBER";
196 assert(Constraint
.isTied());
197 Res
+= "MCOI_TIED_TO(" + utostr(Constraint
.getTiedOperand()) + ")";
200 Result
.push_back(Res
);
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
;
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
<< " }, ";
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
,
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"))
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
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
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
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";
288 for (const auto &Op
: Operands
)
289 OS
<< " " << Op
.first
<< " = " << Op
.second
<< ",\n";
291 OS
<< " OPERAND_LAST";
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()
307 for (const auto &Entry
: OperandMap
) {
308 const std::map
<unsigned, unsigned> &OpList
= Entry
.first
;
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
) << ", ";
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";
330 // There are no operands, so no need to emit anything
331 OS
<< " return -1;\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";
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
);
396 for (Init
*Arg
: MIOI
->getArgs()) {
397 OperandRecords
.push_back(cast
<DefInit
>(Arg
)->getDef());
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";
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
]) {
428 // If there are empty rows, mark them with an empty comment.
429 while (OperandOffsets
[++CurOffset
] == I
)
432 Record
*OpR
= OperandRecords
[I
];
433 if ((OpR
->isSubClassOf("Operand") ||
434 OpR
->isSubClassOf("RegisterOperand") ||
435 OpR
->isSubClassOf("RegisterClass")) &&
437 OS
<< "OpTypes::" << OpR
->getName();
444 OS
<< " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
446 OS
<< " llvm_unreachable(\"No instructions defined\");\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"))
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)
473 return MIOI
->getNumArgs();
475 LogicalOpListSize
= std::max(LogicalOpList
.size(), LogicalOpListSize
);
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
497 for (auto &R
: LogicalOpSizeList
) {
498 const auto &Row
= *R
;
501 for (i
= 0; i
< static_cast<int>(Row
.size()); ++i
) {
502 OS
<< Row
[i
] << ", ";
504 for (; i
< static_cast<int>(LogicalOpListSize
); ++i
) {
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";
524 OS
<< " return LogicalOpIdx;\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";
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"))
554 LogicalOpTypeList
.clear();
555 for (const auto &Op
: Inst
->Operands
) {
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());
564 LogicalOpTypeList
.push_back("-1");
567 OpTypeListSize
= std::max(LogicalOpTypeList
.size(), OpTypeListSize
);
570 LogicalOpTypeMap
.insert({LogicalOpTypeList
, LogicalOpTypeMap
.size()})
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
];
592 int i
, s
= Row
.size();
593 for (i
= 0; i
< s
; ++i
) {
598 for (; i
< static_cast<int>(OpTypeListSize
); ++i
) {
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";
622 OS
<< " return -1;\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())
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"));
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())
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
) {
700 OS
.indent(PE
.getIndentLevel() * 2);
701 PE
.expandStatement(OS
, Rec
->getValueAsDef("Body"));
706 //===----------------------------------------------------------------------===//
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
);
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");
734 unsigned &IL
= EmittedLists
[Uses
];
735 if (!IL
) PrintDefList(Uses
, IL
= ++ListNumber
, OS
);
737 std::vector
<Record
*> Defs
= Inst
->getValueAsListOfDefs("Defs");
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
;
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
);
767 // Emit the array of instruction names.
768 Records
.startTimer("Emit instruction names");
770 InstrNames
.emitStringLiteralDef(OS
, Twine("extern const char ") + TargetName
+
773 OS
<< "extern const unsigned " << TargetName
<<"InstrNameIndices[] = {";
775 for (const CodeGenInstruction
*Inst
: NumberedInstructions
) {
776 // Newline every eight entries.
779 OS
<< InstrNames
.get(std::string(Inst
->TheDef
->getName())) << "U, ";
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[] = {";
793 for (const CodeGenInstruction
*Inst
: NumberedInstructions
) {
796 if (!Inst
->HasComplexDeprecationPredicate
&&
797 !Inst
->DeprecatedReason
.empty())
798 OS
<< Target
.getInstNamespace() << "::" << Inst
->DeprecatedReason
801 OS
<< "uint8_t(-1), ";
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[] = {";
815 for (const CodeGenInstruction
*Inst
: NumberedInstructions
) {
818 if (Inst
->HasComplexDeprecationPredicate
)
819 // Emit a function pointer to the complex predicate method.
820 OS
<< "&get" << Inst
->DeprecatedReason
<< "DeprecationInfo, ";
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, ";
838 if (HasComplexDeprecationInfos
)
839 OS
<< TargetName
<< "InstrComplexDeprecationInfos, ";
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);
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 "
891 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
893 << " InitMCInstrInfo(" << TargetName
<< "Insts, " << TargetName
894 << "InstrNameIndices, " << TargetName
<< "InstrNameData, ";
895 if (HasDeprecationFeatures
)
896 OS
<< TargetName
<< "InstrDeprecationFeatures, ";
899 if (HasComplexDeprecationInfos
)
900 OS
<< TargetName
<< "InstrComplexDeprecationInfos, ";
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
,
926 std::map
<std::vector
<Record
*>, unsigned> &EmittedLists
,
927 const OperandInfoMapTy
&OpInfo
,
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
;
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");
990 PrintFatalError(Inst
.TheDef
->getLoc(), "no TSFlags?");
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
;
996 PrintFatalError(Inst
.TheDef
->getLoc(),
997 "Invalid TSFlags bit in " + Inst
.TheDef
->getName());
1000 OS
.write_hex(Value
);
1003 // Emit the implicit uses and defs lists...
1004 std::vector
<Record
*> UseList
= Inst
.TheDef
->getValueAsListOfDefs("Uses");
1005 if (UseList
.empty())
1008 OS
<< "ImplicitList" << EmittedLists
[UseList
] << ", ";
1010 std::vector
<Record
*> DefList
= Inst
.TheDef
->getValueAsListOfDefs("Defs");
1011 if (DefList
.empty())
1014 OS
<< "ImplicitList" << EmittedLists
[DefList
] << ", ";
1016 // Emit the operand info.
1017 std::vector
<std::string
> OperandInfo
= GetOperandInfo(Inst
);
1018 if (OperandInfo
.empty())
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";
1044 for (const CodeGenInstruction
*Inst
: Target
.getInstructionsByEnumValue())
1045 OS
<< " " << Inst
->TheDef
->getName() << "\t= " << Num
++ << ",\n";
1046 OS
<< " INSTRUCTION_LIST_END = " << Num
<< "\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";
1059 for (const auto &Class
: SchedModels
.explicit_classes())
1060 OS
<< " " << Class
.Name
<< "\t= " << Num
++ << ",\n";
1061 OS
<< " SCHED_LIST_END = " << Num
<< "\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";
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