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