1//===- RegisterInfoEmitter.cpp - Generate a Register File 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 a target
10// register file for a code generator. It uses instances of the Register,
11// RegisterAliases, and RegisterClass classes to gather this information.
12//
13//===----------------------------------------------------------------------===//
14
15#include "Basic/SequenceToOffsetTable.h"
16#include "Common/CodeGenHwModes.h"
17#include "Common/CodeGenRegisters.h"
18#include "Common/CodeGenTarget.h"
19#include "Common/InfoByHwMode.h"
20#include "Common/Types.h"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/BitVector.h"
23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SetVector.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/SparseBitVector.h"
27#include "llvm/ADT/Twine.h"
28#include "llvm/CodeGenTypes/MachineValueType.h"
29#include "llvm/Support/Casting.h"
30#include "llvm/Support/CommandLine.h"
31#include "llvm/Support/Format.h"
32#include "llvm/Support/FormatVariadic.h"
33#include "llvm/Support/Printable.h"
34#include "llvm/Support/raw_ostream.h"
35#include "llvm/TableGen/CodeGenHelpers.h"
36#include "llvm/TableGen/Error.h"
37#include "llvm/TableGen/Record.h"
38#include "llvm/TableGen/SetTheory.h"
39#include "llvm/TableGen/TGTimer.h"
40#include "llvm/TableGen/TableGenBackend.h"
41#include <algorithm>
42#include <cassert>
43#include <cstddef>
44#include <cstdint>
45#include <deque>
46#include <iterator>
47#include <set>
48#include <string>
49#include <vector>
50
51using namespace llvm;
52
53static cl::OptionCategory RegisterInfoCat("Options for -gen-register-info");
54
55static cl::opt<bool>
56 RegisterInfoDebug("register-info-debug", cl::init(Val: false),
57 cl::desc("Dump register information to help debugging"),
58 cl::cat(RegisterInfoCat));
59
60namespace {
61
62class RegisterInfoEmitter {
63 const RecordKeeper &Records;
64 const CodeGenTarget Target;
65 CodeGenRegBank &RegBank;
66
67 std::string MCRegisterClassStorageType;
68
69public:
70 RegisterInfoEmitter(const RecordKeeper &R)
71 : Records(R), Target(R), RegBank(Target.getRegBank()) {
72 RegBank.computeDerivedInfo();
73 }
74
75 // runEnums - Print out enum values for all of the registers.
76 void runEnums(raw_ostream &OS, raw_ostream &MainOS, StringRef FilenamePrefix);
77
78 // runMCDesc - Print out MC register descriptions.
79 void runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
80 StringRef FilenamePrefix);
81
82 // runTargetHeader - Emit a header fragment for the register info emitter.
83 void runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
84 StringRef FilenamePrefix);
85
86 // runTargetDesc - Output the target register and register file descriptions.
87 void runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
88 StringRef FilenamePrefix);
89
90 // run - Output the register file description.
91 TableGenOutputFiles run(StringRef FilenamePrefix);
92
93 template <typename InfoTy, typename FnTy>
94 Printable printByHwMode(const InfoByHwMode<InfoTy> &Info, FnTy Func);
95
96 void debugDump(raw_ostream &OS);
97
98private:
99 void EmitRegMapping(raw_ostream &OS, const std::deque<CodeGenRegister> &Regs,
100 bool isCtor);
101 void EmitRegMappingTables(raw_ostream &OS,
102 const std::deque<CodeGenRegister> &Regs,
103 bool isCtor);
104 void EmitRegUnitPressure(raw_ostream &OS, StringRef ClassName);
105 void emitComposeSubRegIndices(raw_ostream &OS, StringRef ClassName);
106 void emitComposeSubRegIndexLaneMask(raw_ostream &OS, StringRef ClassName);
107};
108
109} // end anonymous namespace
110
111static void emitInclude(StringRef FilenamePrefix, StringRef IncludeFile,
112 StringRef GuardMacro, raw_ostream &OS) {
113 IfDefEmitter IfDed(OS, GuardMacro);
114 OS << "#include \"" << FilenamePrefix << IncludeFile << "\"\n";
115}
116
117// runEnums - Print out enum values for all of the registers.
118void RegisterInfoEmitter::runEnums(raw_ostream &OS, raw_ostream &MainOS,
119 StringRef FilenamePrefix) {
120 emitInclude(FilenamePrefix, IncludeFile: "Enums.inc", GuardMacro: "GET_REGINFO_ENUM", OS&: MainOS);
121
122 const auto &Registers = RegBank.getRegisters();
123
124 // Register enums are stored as uint16_t in the tables. Make sure we'll fit.
125 assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
126
127 StringRef Namespace = Registers.front().TheDef->getValueAsString(FieldName: "Namespace");
128
129 emitSourceFileHeader(Desc: "Target Register Enum Values", OS);
130
131 NamespaceEmitter LlvmNS(OS, "llvm");
132
133 OS << "class MCRegisterClass;\n";
134 OS << "const MCRegisterClass &get" << Target.getName()
135 << "MCRegisterClass(unsigned RC);\n";
136
137 {
138 NamespaceEmitter RegNS(OS, Namespace);
139 OS << "enum : unsigned {\n NoRegister,\n";
140
141 for (const auto &Reg : Registers)
142 OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
143 assert(Registers.size() == Registers.back().EnumValue &&
144 "Register enum value mismatch!");
145 OS << " NUM_TARGET_REGS // " << Registers.size() + 1 << "\n";
146 OS << "};\n";
147 }
148
149 const auto &RegisterClasses = RegBank.getRegClasses();
150 if (!RegisterClasses.empty()) {
151 // RegisterClass enums are stored as uint16_t in the tables.
152 assert(RegisterClasses.size() <= UINT16_MAX &&
153 "Too many register classes to fit in tables");
154
155 OS << "\n// Register classes\n\n";
156 NamespaceEmitter RegNS(OS, Namespace);
157 OS << "enum {\n";
158 for (const auto &RC : RegisterClasses)
159 OS << " " << RC.getIdName() << " = " << RC.EnumValue << ",\n";
160 OS << "\n};\n";
161 }
162
163 ArrayRef<const Record *> RegAltNameIndices = Target.getRegAltNameIndices();
164 // If the only definition is the default NoRegAltName, we don't need to
165 // emit anything.
166 if (RegAltNameIndices.size() > 1) {
167 OS << "\n// Register alternate name indices\n\n";
168 NamespaceEmitter RegNS(OS, Namespace);
169 OS << "enum {\n";
170 for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
171 OS << " " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";
172 OS << " NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";
173 OS << "};\n";
174 }
175
176 auto &SubRegIndices = RegBank.getSubRegIndices();
177 if (!SubRegIndices.empty()) {
178 OS << "\n// Subregister indices\n\n";
179 NamespaceEmitter SubRegNS(OS, SubRegIndices.front().getNamespace());
180 OS << "enum : uint16_t {\n NoSubRegister,\n";
181 unsigned i = 0;
182 for (const auto &Idx : SubRegIndices)
183 OS << " " << Idx.getName() << ",\t// " << ++i << "\n";
184 OS << " NUM_TARGET_SUBREGS\n};\n";
185 }
186
187 {
188 OS << "// Register pressure sets enum.\n";
189 NamespaceEmitter RegNS(OS, Namespace);
190 OS << "enum RegisterPressureSets {\n";
191 unsigned NumSets = RegBank.getNumRegPressureSets();
192 for (unsigned i = 0; i < NumSets; ++i) {
193 const RegUnitSet &RegUnits = RegBank.getRegSetAt(Order: i);
194 OS << " " << RegUnits.Name << " = " << i << ",\n";
195 }
196 OS << "};\n";
197 }
198
199 // Note: While these functions are not enums, we need to define them in the
200 // same place as <TARGET>::<REG>, so that the assembly parser can use them
201 // without having to include <TARGETT>RegisterInfo.h, which may not be
202 // possible due to build system structure.
203 ArrayRef<const Record *> RegisterByHwModeRecords =
204 Records.getAllDerivedDefinitions(ClassName: "RegisterByHwMode");
205 if (!RegisterByHwModeRecords.empty()) {
206 OS << "// Registers by HwMode\n";
207 OS << "class MCRegister;\n";
208 NamespaceEmitter RegClassNS(OS, Namespace + "::RegisterByHwMode");
209 // Define the getters for the RegisterByHwMode in one globally accessible
210 // location so they can be reused by all callers.
211 for (const Record *Rec : RegisterByHwModeRecords) {
212 OS << "LLVM_READONLY MCRegister get" << Rec->getName()
213 << "(unsigned HwMode);\n";
214 }
215 }
216}
217
218static void printInt(raw_ostream &OS, int Val) { OS << Val; }
219
220void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS,
221 StringRef ClassName) {
222 unsigned NumRCs = RegBank.getRegClasses().size();
223 unsigned NumSets = RegBank.getNumRegPressureSets();
224
225 OS << "/// Get the weight in units of pressure for this register class.\n"
226 << "const RegClassWeight &" << ClassName << "::\n"
227 << "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
228 << " static const RegClassWeight RCWeightTable[] = {\n";
229 for (const auto &RC : RegBank.getRegClasses()) {
230 const CodeGenRegister::Vec &Regs = RC.getMembers();
231 OS << " {" << RC.getWeight(RegBank) << ", ";
232 if (Regs.empty() || RC.Artificial)
233 OS << '0';
234 else {
235 std::vector<unsigned> RegUnits;
236 RC.buildRegUnitSet(RegBank, RegUnits);
237 OS << RegBank.getRegUnitSetWeight(Units: RegUnits);
238 }
239 OS << "}, \t// " << RC.getName() << "\n";
240 }
241 OS << " };\n"
242 << " return RCWeightTable[RC->getID()];\n"
243 << "}\n\n";
244
245 // Reasonable targets (not ARMv7) have unit weight for all units, so don't
246 // bother generating a table.
247 bool RegUnitsHaveUnitWeight = true;
248 for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
249 UnitIdx < UnitEnd; ++UnitIdx) {
250 if (RegBank.getRegUnit(RUID: UnitIdx).Weight > 1)
251 RegUnitsHaveUnitWeight = false;
252 }
253 OS << "/// Get the weight in units of pressure for this register unit.\n"
254 << "unsigned " << ClassName << "::\n"
255 << "getRegUnitWeight(MCRegUnit RegUnit) const {\n"
256 << " assert(static_cast<unsigned>(RegUnit) < "
257 << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n";
258 if (!RegUnitsHaveUnitWeight) {
259 OS << " static const uint8_t RUWeightTable[] = {\n ";
260 for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
261 UnitIdx < UnitEnd; ++UnitIdx) {
262 const RegUnit &RU = RegBank.getRegUnit(RUID: UnitIdx);
263 assert(RU.Weight < 256 && "RegUnit too heavy");
264 OS << RU.Weight << ", ";
265 }
266 OS << "};\n"
267 << " return RUWeightTable[static_cast<unsigned>(RegUnit)];\n";
268 } else {
269 OS << " // All register units have unit weight.\n"
270 << " return 1;\n";
271 }
272 OS << "}\n\n";
273
274 OS << "\n"
275 << "// Get the number of dimensions of register pressure.\n"
276 << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
277 << " return " << NumSets << ";\n}\n\n";
278
279 OS << "// Get the name of this register unit pressure set.\n"
280 << "const char *" << ClassName << "::\n"
281 << "getRegPressureSetName(unsigned Idx) const {\n"
282 << " static const char *PressureNameTable[] = {\n";
283 unsigned MaxRegUnitWeight = 0;
284 for (unsigned i = 0; i < NumSets; ++i) {
285 const RegUnitSet &RegUnits = RegBank.getRegSetAt(Order: i);
286 MaxRegUnitWeight = std::max(a: MaxRegUnitWeight, b: RegUnits.Weight);
287 OS << " \"" << RegUnits.Name << "\",\n";
288 }
289 OS << " };\n"
290 << " return PressureNameTable[Idx];\n"
291 << "}\n\n";
292
293 OS << "// Get the register unit pressure limit for this dimension.\n"
294 << "// This limit must be adjusted dynamically for reserved registers.\n"
295 << "unsigned " << ClassName << "::\n"
296 << "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const "
297 "{\n"
298 << " static const " << getMinimalTypeForRange(Range: MaxRegUnitWeight, MaxSize: 32)
299 << " PressureLimitTable[] = {\n";
300 for (unsigned i = 0; i < NumSets; ++i) {
301 const RegUnitSet &RegUnits = RegBank.getRegSetAt(Order: i);
302 OS << " " << RegUnits.Weight << ", \t// " << i << ": " << RegUnits.Name
303 << "\n";
304 }
305 OS << " };\n"
306 << " return PressureLimitTable[Idx];\n"
307 << "}\n\n";
308
309 SequenceToOffsetTable<std::vector<int>> PSetsSeqs(/*Terminator=*/-1);
310
311 // This table may be larger than NumRCs if some register units needed a list
312 // of unit sets that did not correspond to a register class.
313 unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
314 std::vector<std::vector<int>> PSets(NumRCUnitSets);
315
316 for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
317 ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(RCIdx: i);
318 PSets[i].reserve(n: PSetIDs.size());
319 for (unsigned PSetID : PSetIDs) {
320 PSets[i].push_back(x: RegBank.getRegPressureSet(Idx: PSetID).Order);
321 }
322 llvm::sort(C&: PSets[i]);
323 PSetsSeqs.add(Seq: PSets[i]);
324 }
325
326 PSetsSeqs.layout();
327
328 OS << "/// Table of pressure sets per register class or unit.\n"
329 << "static const int RCSetsTable[] = {\n";
330 PSetsSeqs.emit(OS, Print: printInt);
331 OS << "};\n\n";
332
333 OS << "/// Get the dimensions of register pressure impacted by this "
334 << "register class.\n"
335 << "/// Returns a -1 terminated array of pressure set IDs\n"
336 << "const int *" << ClassName << "::\n"
337 << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
338 OS << " static const " << getMinimalTypeForRange(Range: PSetsSeqs.size() - 1, MaxSize: 32)
339 << " RCSetStartTable[] = {\n ";
340 for (unsigned i = 0, e = NumRCs; i != e; ++i) {
341 OS << PSetsSeqs.get(Seq: PSets[i]) << ",";
342 }
343 OS << "};\n"
344 << " return &RCSetsTable[RCSetStartTable[RC->getID()]];\n"
345 << "}\n\n";
346
347 OS << "/// Get the dimensions of register pressure impacted by this "
348 << "register unit.\n"
349 << "/// Returns a -1 terminated array of pressure set IDs\n"
350 << "const int *" << ClassName << "::\n"
351 << "getRegUnitPressureSets(MCRegUnit RegUnit) const {\n"
352 << " assert(static_cast<unsigned>(RegUnit) < "
353 << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n";
354 OS << " static const " << getMinimalTypeForRange(Range: PSetsSeqs.size() - 1, MaxSize: 32)
355 << " RUSetStartTable[] = {\n ";
356 for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
357 UnitIdx < UnitEnd; ++UnitIdx) {
358 OS << PSetsSeqs.get(Seq: PSets[RegBank.getRegUnit(RUID: UnitIdx).RegClassUnitSetsIdx])
359 << ",";
360 }
361 OS << "};\n"
362 << " return "
363 "&RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];\n"
364 << "}\n\n";
365}
366
367using DwarfRegNumsMapPair = std::pair<const Record *, std::vector<int64_t>>;
368using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>;
369
370static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
371 // Sort and unique to get a map-like vector. We want the last assignment to
372 // match previous behaviour.
373 llvm::stable_sort(Range&: DwarfRegNums, C: on_first<LessRecordRegister>());
374 // Warn about duplicate assignments.
375 const Record *LastSeenReg = nullptr;
376 for (const auto &X : DwarfRegNums) {
377 const auto &Reg = X.first;
378 // The only way LessRecordRegister can return equal is if they're the same
379 // string. Use simple equality instead.
380 if (LastSeenReg && Reg->getName() == LastSeenReg->getName())
381 PrintWarning(WarningLoc: Reg->getLoc(), Msg: Twine("DWARF numbers for register ") +
382 getQualifiedName(R: Reg) +
383 "specified multiple times");
384 LastSeenReg = Reg;
385 }
386 auto Last = llvm::unique(R&: DwarfRegNums, P: [](const DwarfRegNumsMapPair &A,
387 const DwarfRegNumsMapPair &B) {
388 return A.first->getName() == B.first->getName();
389 });
390 DwarfRegNums.erase(first: Last, last: DwarfRegNums.end());
391}
392
393void RegisterInfoEmitter::EmitRegMappingTables(
394 raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
395 // Collect all information about dwarf register numbers
396 DwarfRegNumsVecTy DwarfRegNums;
397
398 // First, just pull all provided information to the map
399 unsigned maxLength = 0;
400 for (auto &RE : Regs) {
401 const Record *Reg = RE.TheDef;
402 std::vector<int64_t> RegNums = Reg->getValueAsListOfInts(FieldName: "DwarfNumbers");
403 maxLength = std::max(a: (size_t)maxLength, b: RegNums.size());
404 DwarfRegNums.emplace_back(args&: Reg, args: std::move(RegNums));
405 }
406 finalizeDwarfRegNumsKeys(DwarfRegNums);
407
408 if (!maxLength)
409 return;
410
411 // Now we know maximal length of number list. Append -1's, where needed
412 for (auto &DwarfRegNum : DwarfRegNums)
413 for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)
414 DwarfRegNum.second.push_back(x: -1);
415
416 StringRef Namespace = Regs.front().TheDef->getValueAsString(FieldName: "Namespace");
417
418 OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
419
420 // Emit reverse information about the dwarf register numbers.
421 for (unsigned j = 0; j < 2; ++j) {
422 for (unsigned I = 0, E = maxLength; I != E; ++I) {
423 OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
424 OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
425 OS << I << "Dwarf2L[]";
426
427 if (!isCtor) {
428 OS << " = {\n";
429
430 // Store the mapping sorted by the LLVM reg num so lookup can be done
431 // with a binary search.
432 std::map<uint64_t, const Record *> Dwarf2LMap;
433 for (auto &DwarfRegNum : DwarfRegNums) {
434 int DwarfRegNo = DwarfRegNum.second[I];
435 if (DwarfRegNo < 0)
436 continue;
437 Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;
438 }
439
440 for (auto &I : Dwarf2LMap)
441 OS << " { " << I.first << "U, " << getQualifiedName(R: I.second)
442 << " },\n";
443
444 OS << "};\n";
445 } else {
446 OS << ";\n";
447 }
448
449 // We have to store the size in a const global, it's used in multiple
450 // places.
451 OS << "extern const unsigned " << Namespace
452 << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";
453 if (!isCtor)
454 OS << " = std::size(" << Namespace
455 << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";
456 else
457 OS << ";\n\n";
458 }
459 }
460
461 for (auto &RE : Regs) {
462 const Record *Reg = RE.TheDef;
463 const RecordVal *V = Reg->getValue(Name: "DwarfAlias");
464 if (!V || !V->getValue())
465 continue;
466
467 const DefInit *DI = cast<DefInit>(Val: V->getValue());
468 const Record *Alias = DI->getDef();
469 const auto &AliasIter = llvm::lower_bound(
470 Range&: DwarfRegNums, Value&: Alias, C: [](const DwarfRegNumsMapPair &A, const Record *B) {
471 return LessRecordRegister()(A.first, B);
472 });
473 assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&
474 "Expected Alias to be present in map");
475 const auto &RegIter = llvm::lower_bound(
476 Range&: DwarfRegNums, Value&: Reg, C: [](const DwarfRegNumsMapPair &A, const Record *B) {
477 return LessRecordRegister()(A.first, B);
478 });
479 assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&
480 "Expected Reg to be present in map");
481 RegIter->second = AliasIter->second;
482 }
483
484 // Emit information about the dwarf register numbers.
485 for (unsigned j = 0; j < 2; ++j) {
486 for (unsigned i = 0, e = maxLength; i != e; ++i) {
487 OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
488 OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
489 OS << i << "L2Dwarf[]";
490 if (!isCtor) {
491 OS << " = {\n";
492 // Store the mapping sorted by the Dwarf reg num so lookup can be done
493 // with a binary search.
494 for (auto &DwarfRegNum : DwarfRegNums) {
495 int RegNo = DwarfRegNum.second[i];
496 if (RegNo == -1) // -1 is the default value, don't emit a mapping.
497 continue;
498
499 OS << " { " << getQualifiedName(R: DwarfRegNum.first) << ", " << RegNo
500 << "U },\n";
501 }
502 OS << "};\n";
503 } else {
504 OS << ";\n";
505 }
506
507 // We have to store the size in a const global, it's used in multiple
508 // places.
509 OS << "extern const unsigned " << Namespace
510 << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";
511 if (!isCtor)
512 OS << " = std::size(" << Namespace
513 << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2Dwarf);\n\n";
514 else
515 OS << ";\n\n";
516 }
517 }
518}
519
520void RegisterInfoEmitter::EmitRegMapping(
521 raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
522 // Emit the initializer so the tables from EmitRegMappingTables get wired up
523 // to the MCRegisterInfo object.
524 unsigned maxLength = 0;
525 for (auto &RE : Regs) {
526 const Record *Reg = RE.TheDef;
527 maxLength = std::max(a: (size_t)maxLength,
528 b: Reg->getValueAsListOfInts(FieldName: "DwarfNumbers").size());
529 }
530
531 if (!maxLength)
532 return;
533
534 StringRef Namespace = Regs.front().TheDef->getValueAsString(FieldName: "Namespace");
535
536 // Emit reverse information about the dwarf register numbers.
537 for (unsigned j = 0; j < 2; ++j) {
538 OS << " switch (";
539 if (j == 0)
540 OS << "DwarfFlavour";
541 else
542 OS << "EHFlavour";
543 OS << ") {\n"
544 << " default:\n"
545 << " llvm_unreachable(\"Unknown DWARF flavour\");\n";
546
547 for (unsigned i = 0, e = maxLength; i != e; ++i) {
548 OS << " case " << i << ":\n";
549 OS << " ";
550 if (!isCtor)
551 OS << "RI->";
552 std::string Tmp;
553 raw_string_ostream(Tmp)
554 << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
555 << "Dwarf2L";
556 OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";
557 if (j == 0)
558 OS << "false";
559 else
560 OS << "true";
561 OS << ");\n";
562 OS << " break;\n";
563 }
564 OS << " }\n";
565 }
566
567 // Emit information about the dwarf register numbers.
568 for (unsigned j = 0; j < 2; ++j) {
569 OS << " switch (";
570 if (j == 0)
571 OS << "DwarfFlavour";
572 else
573 OS << "EHFlavour";
574 OS << ") {\n"
575 << " default:\n"
576 << " llvm_unreachable(\"Unknown DWARF flavour\");\n";
577
578 for (unsigned i = 0, e = maxLength; i != e; ++i) {
579 OS << " case " << i << ":\n";
580 OS << " ";
581 if (!isCtor)
582 OS << "RI->";
583 std::string Tmp;
584 raw_string_ostream(Tmp)
585 << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
586 << "L2Dwarf";
587 OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";
588 if (j == 0)
589 OS << "false";
590 else
591 OS << "true";
592 OS << ");\n";
593 OS << " break;\n";
594 }
595 OS << " }\n";
596 }
597}
598
599// Print a BitVector as a sequence of hex numbers using a little-endian mapping.
600// Width is the number of bits per hex number.
601static void printBitVectorAsHex(raw_ostream &OS, const BitVector &Bits,
602 unsigned Width) {
603 assert(Width <= 32 && "Width too large");
604 unsigned Digits = (Width + 3) / 4;
605 for (unsigned i = 0, e = Bits.size(); i < e; i += Width) {
606 unsigned Value = 0;
607 for (unsigned j = 0; j != Width && i + j != e; ++j)
608 Value |= Bits.test(Idx: i + j) << j;
609 OS << format(Fmt: "0x%0*x, ", Vals: Digits, Vals: Value);
610 }
611}
612
613// Helper to emit a set of bits into a constant byte array.
614class BitVectorEmitter {
615 BitVector Values;
616
617public:
618 void add(unsigned v) {
619 if (v >= Values.size())
620 Values.resize(N: ((v / 8) + 1) * 8); // Round up to the next byte.
621 Values[v] = true;
622 }
623
624 unsigned byteSize() const { return (Values.size() + 7) / 8; }
625
626 void print(raw_ostream &OS) { printBitVectorAsHex(OS, Bits: Values, Width: 8); }
627};
628
629static void printSimpleValueType(raw_ostream &OS, MVT VT) {
630 OS << getEnumName(T: VT);
631}
632
633static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
634 OS << (Idx ? Idx->EnumValue : 0);
635}
636
637// Differentially encoded register and regunit lists allow for better
638// compression on regular register banks. The sequence is computed from the
639// differential list as:
640//
641// out[0] = InitVal;
642// out[n+1] = out[n] + diff[n]; // n = 0, 1, ...
643//
644// The initial value depends on the specific list. The list is terminated by a
645// 0 differential which means we can't encode repeated elements.
646
647using DiffVec = SmallVector<int16_t, 4>;
648using MaskVec = SmallVector<LaneBitmask, 4>;
649
650// Fills V with differentials between every two consecutive elements of List.
651static DiffVec &diffEncode(DiffVec &V, SparseBitVector<> List) {
652 assert(V.empty() && "Clear DiffVec before diffEncode.");
653 SparseBitVector<>::iterator I = List.begin(), E = List.end();
654 unsigned Val = *I;
655 while (++I != E) {
656 unsigned Cur = *I;
657 V.push_back(Elt: Cur - Val);
658 Val = Cur;
659 }
660 return V;
661}
662
663template <typename Iter>
664static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
665 assert(V.empty() && "Clear DiffVec before diffEncode.");
666 unsigned Val = InitVal;
667 for (Iter I = Begin; I != End; ++I) {
668 unsigned Cur = (*I)->EnumValue;
669 V.push_back(Elt: Cur - Val);
670 Val = Cur;
671 }
672 return V;
673}
674
675static void printDiff16(raw_ostream &OS, int16_t Val) { OS << Val; }
676
677static void printMask(raw_ostream &OS, LaneBitmask Val) {
678 OS << "LaneBitmask(0x" << PrintLaneMask(LaneMask: Val) << ')';
679}
680
681// Try to combine Idx's compose map into Vec if it is compatible.
682// Return false if it's not possible.
683static bool combine(const CodeGenSubRegIndex *Idx,
684 SmallVectorImpl<const CodeGenSubRegIndex *> &Vec) {
685 const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
686 for (const auto &I : Map) {
687 const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
688 if (Entry && Entry != I.second)
689 return false;
690 }
691
692 // All entries are compatible. Make it so.
693 for (const auto &I : Map) {
694 const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
695 assert((!Entry || Entry == I.second) && "Expected EnumValue to be unique");
696 Entry = I.second;
697 }
698 return true;
699}
700
701void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
702 StringRef ClassName) {
703 const auto &SubRegIndices = RegBank.getSubRegIndices();
704
705 // Many sub-register indexes are composition-compatible, meaning that
706 //
707 // compose(IdxA, IdxB) == compose(IdxA', IdxB)
708 //
709 // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
710 // The illegal entries can be use as wildcards to compress the table further.
711
712 // Map each Sub-register index to a compatible table row.
713 SmallVector<unsigned, 4> RowMap;
714 SmallVector<SmallVector<const CodeGenSubRegIndex *, 4>, 4> Rows;
715
716 size_t SubRegIndicesSize = llvm::size(Range: SubRegIndices);
717 for (const auto &Idx : SubRegIndices) {
718 unsigned Found = ~0u;
719 for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
720 if (combine(Idx: &Idx, Vec&: Rows[r])) {
721 Found = r;
722 break;
723 }
724 }
725 if (Found == ~0u) {
726 Found = Rows.size();
727 Rows.resize(N: Found + 1);
728 Rows.back().resize(N: SubRegIndicesSize);
729 combine(Idx: &Idx, Vec&: Rows.back());
730 }
731 RowMap.push_back(Elt: Found);
732 }
733
734 OS << "unsigned " << ClassName
735 << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
736
737 // Output the row map if there are multiple rows.
738 if (Rows.size() > 1) {
739 OS << " static const " << getMinimalTypeForRange(Range: Rows.size(), MaxSize: 32)
740 << " RowMap[" << SubRegIndicesSize << "] = {\n ";
741 for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
742 OS << RowMap[i] << ", ";
743 OS << "\n };\n";
744 }
745
746 // Output the rows.
747 OS << " static const " << getMinimalTypeForRange(Range: SubRegIndicesSize + 1, MaxSize: 32)
748 << " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";
749 for (const auto &Row : Rows) {
750 OS << " { ";
751 for (const llvm::CodeGenSubRegIndex *Elem :
752 ArrayRef(&Row[0], SubRegIndicesSize))
753 if (Elem)
754 OS << Elem->getQualifiedName() << ", ";
755 else
756 OS << "0, ";
757 OS << "},\n";
758 }
759 OS << " };\n\n";
760
761 OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << "); (void) IdxA;\n"
762 << " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
763 if (Rows.size() > 1)
764 OS << " return Rows[RowMap[IdxA]][IdxB];\n";
765 else
766 OS << " return Rows[0][IdxB];\n";
767 OS << "}\n\n";
768
769 // Generate the reverse case.
770 //
771 // FIXME: This is the brute force approach. Compress the table similar to the
772 // forward case.
773 OS << "unsigned " << ClassName
774 << "::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const "
775 "{\n";
776 OS << " static const " << getMinimalTypeForRange(Range: SubRegIndicesSize + 1, MaxSize: 32)
777 << " Table[" << SubRegIndicesSize << "][" << SubRegIndicesSize
778 << "] = {\n";
779
780 // Find values where composeSubReg(A, X) == B;
781 for (const auto &IdxA : SubRegIndices) {
782 OS << " { ";
783
784 SmallVectorImpl<const CodeGenSubRegIndex *> &Row =
785 Rows[RowMap[IdxA.EnumValue - 1]];
786 for (const auto &IdxB : SubRegIndices) {
787 const CodeGenSubRegIndex *FoundReverse = nullptr;
788
789 for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i) {
790 const CodeGenSubRegIndex *This = &SubRegIndices[i];
791 const CodeGenSubRegIndex *Composed = Row[i];
792 if (Composed == &IdxB) {
793 if (FoundReverse && FoundReverse != This) // Not unique
794 break;
795 FoundReverse = This;
796 }
797 }
798
799 if (FoundReverse) {
800 OS << FoundReverse->getQualifiedName() << ", ";
801 } else {
802 OS << "0, ";
803 }
804 }
805 OS << "},\n";
806 }
807
808 OS << " };\n\n";
809 OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << ");\n"
810 << " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
811 OS << " return Table[IdxA][IdxB];\n";
812 OS << " }\n\n";
813}
814
815void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
816 StringRef ClassName) {
817 // See the comments in computeSubRegLaneMasks() for our goal here.
818 const auto &SubRegIndices = RegBank.getSubRegIndices();
819
820 // Create a list of Mask+Rotate operations, with equivalent entries merged.
821 SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
822 SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
823 for (const auto &Idx : SubRegIndices) {
824 const SmallVector<MaskRolPair, 1> &IdxSequence =
825 Idx.CompositionLaneMaskTransform;
826
827 unsigned Found = ~0u;
828 unsigned SIdx = 0;
829 unsigned NextSIdx;
830 for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
831 SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
832 NextSIdx = SIdx + Sequence.size() + 1;
833 if (Sequence == IdxSequence) {
834 Found = SIdx;
835 break;
836 }
837 }
838 if (Found == ~0u) {
839 Sequences.push_back(Elt: IdxSequence);
840 Found = SIdx;
841 }
842 SubReg2SequenceIndexMap.push_back(Elt: Found);
843 }
844
845 OS << " struct MaskRolOp {\n"
846 " LaneBitmask Mask;\n"
847 " uint8_t RotateLeft;\n"
848 " };\n"
849 " static const MaskRolOp LaneMaskComposeSequences[] = {\n";
850 unsigned Idx = 0;
851 for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
852 OS << " ";
853 const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
854 for (const MaskRolPair &P : Sequence) {
855 printMask(OS&: OS << "{ ", Val: P.Mask);
856 OS << format(Fmt: ", %2u }, ", Vals: P.RotateLeft);
857 }
858 OS << "{ LaneBitmask::getNone(), 0 }";
859 if (s + 1 != se)
860 OS << ", ";
861 OS << " // Sequence " << Idx << "\n";
862 Idx += Sequence.size() + 1;
863 }
864 auto *IntType =
865 getMinimalTypeForRange(Range: *llvm::max_element(Range&: SubReg2SequenceIndexMap));
866 OS << " };\n"
867 " static const "
868 << IntType << " CompositeSequences[] = {\n";
869 for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
870 OS << " ";
871 OS << SubReg2SequenceIndexMap[i];
872 if (i + 1 != e)
873 OS << ",";
874 OS << " // to " << SubRegIndices[i].getName() << "\n";
875 }
876 OS << " };\n\n";
877
878 OS << "LaneBitmask " << ClassName
879 << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"
880 " const {\n"
881 " --IdxA; assert(IdxA < "
882 << SubRegIndices.size()
883 << " && \"Subregister index out of bounds\");\n"
884 " LaneBitmask Result;\n"
885 " for (const MaskRolOp *Ops =\n"
886 " &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
887 " Ops->Mask.any(); ++Ops) {\n"
888 " LaneBitmask::Type M = LaneMask.getAsInteger() & "
889 "Ops->Mask.getAsInteger();\n"
890 " if (unsigned S = Ops->RotateLeft)\n"
891 " Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - "
892 "S)));\n"
893 " else\n"
894 " Result |= LaneBitmask(M);\n"
895 " }\n"
896 " return Result;\n"
897 "}\n\n";
898
899 OS << "LaneBitmask " << ClassName
900 << "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "
901 " LaneBitmask LaneMask) const {\n"
902 " LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
903 " --IdxA; assert(IdxA < "
904 << SubRegIndices.size()
905 << " && \"Subregister index out of bounds\");\n"
906 " LaneBitmask Result;\n"
907 " for (const MaskRolOp *Ops =\n"
908 " &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
909 " Ops->Mask.any(); ++Ops) {\n"
910 " LaneBitmask::Type M = LaneMask.getAsInteger();\n"
911 " if (unsigned S = Ops->RotateLeft)\n"
912 " Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - "
913 "S)));\n"
914 " else\n"
915 " Result |= LaneBitmask(M);\n"
916 " }\n"
917 " return Result;\n"
918 "}\n\n";
919}
920
921//
922// runMCDesc - Print out MC register descriptions.
923//
924void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
925 StringRef FilenamePrefix) {
926 emitInclude(FilenamePrefix, IncludeFile: "MCDesc.inc", GuardMacro: "GET_REGINFO_MC_DESC", OS&: MainOS);
927
928 emitSourceFileHeader(Desc: "MC Register Information", OS);
929
930 const auto &Regs = RegBank.getRegisters();
931
932 auto &SubRegIndices = RegBank.getSubRegIndices();
933 // The lists of sub-registers and super-registers go in the same array. That
934 // allows us to share suffixes.
935 using RegVec = std::vector<const CodeGenRegister *>;
936
937 // Differentially encoded lists.
938 SequenceToOffsetTable<DiffVec> DiffSeqs;
939 SmallVector<DiffVec, 4> SubRegLists(Regs.size());
940 SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
941 SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
942
943 // List of lane masks accompanying register unit sequences.
944 SequenceToOffsetTable<MaskVec> LaneMaskSeqs(/*Terminator=*/std::nullopt);
945 SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
946
947 // Keep track of sub-register names as well. These are not differentially
948 // encoded.
949 using SubRegIdxVec = SmallVector<const CodeGenSubRegIndex *, 4>;
950 SequenceToOffsetTable<SubRegIdxVec, deref<std::less<>>> SubRegIdxSeqs(
951 /*Terminator=*/std::nullopt);
952 SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
953
954 SequenceToOffsetTable<std::string> RegStrings;
955
956 // Precompute register lists for the SequenceToOffsetTable.
957 unsigned i = 0;
958 for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
959 const auto &Reg = *I;
960 RegStrings.add(Seq: Reg.getName().str());
961
962 // Compute the ordered sub-register list.
963 SetVector<const CodeGenRegister *> SR;
964 Reg.addSubRegsPreOrder(OSet&: SR, RegBank);
965 diffEncode(V&: SubRegLists[i], InitVal: Reg.EnumValue, Begin: SR.begin(), End: SR.end());
966 DiffSeqs.add(Seq: SubRegLists[i]);
967
968 // Compute the corresponding sub-register indexes.
969 SubRegIdxVec &SRIs = SubRegIdxLists[i];
970 for (const CodeGenRegister *S : SR)
971 SRIs.push_back(Elt: Reg.getSubRegIndex(Reg: S));
972 SubRegIdxSeqs.add(Seq: SRIs);
973
974 // Super-registers are already computed.
975 const RegVec &SuperRegList = Reg.getSuperRegs();
976 diffEncode(V&: SuperRegLists[i], InitVal: Reg.EnumValue, Begin: SuperRegList.begin(),
977 End: SuperRegList.end());
978 DiffSeqs.add(Seq: SuperRegLists[i]);
979
980 const SparseBitVector<> &RUs = Reg.getNativeRegUnits();
981 DiffSeqs.add(Seq: diffEncode(V&: RegUnitLists[i], List: RUs));
982
983 const auto &RUMasks = Reg.getRegUnitLaneMasks();
984 MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
985 assert(LaneMaskVec.empty());
986 llvm::append_range(C&: LaneMaskVec, R: RUMasks);
987 LaneMaskSeqs.add(Seq: LaneMaskVec);
988 }
989
990 // Compute the final layout of the sequence table.
991 DiffSeqs.layout();
992 LaneMaskSeqs.layout();
993 SubRegIdxSeqs.layout();
994
995 NamespaceEmitter LlvmNS(OS, "llvm");
996
997 StringRef TargetName = Target.getName();
998
999 // Emit the shared table of differential lists.
1000 OS << "extern const int16_t " << TargetName << "RegDiffLists[] = {\n";
1001 DiffSeqs.emit(OS, Print: printDiff16);
1002 OS << "};\n\n";
1003
1004 // Emit the shared table of regunit lane mask sequences.
1005 OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
1006 LaneMaskSeqs.emit(OS, Print: printMask);
1007 OS << "};\n\n";
1008
1009 // Emit the table of sub-register indexes.
1010 OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
1011 SubRegIdxSeqs.emit(OS, Print: printSubRegIndex);
1012 OS << "};\n\n";
1013
1014 // Emit the string table.
1015 RegStrings.layout();
1016 RegStrings.emitStringLiteralDef(OS, Decl: Twine("extern const char ") + TargetName +
1017 "RegStrings[]");
1018
1019 OS << "extern const MCRegisterDesc " << TargetName
1020 << "RegDesc[] = { // Descriptors\n";
1021 OS << " { " << RegStrings.get(Seq: "") << ", 0, 0, 0, 0, 0, 0, 0 },\n";
1022
1023 // Emit the register descriptors now.
1024 i = 0;
1025 for (const auto &Reg : Regs) {
1026 unsigned FirstRU = Reg.getNativeRegUnits().find_first();
1027 unsigned Offset = DiffSeqs.get(Seq: RegUnitLists[i]);
1028 // The value must be kept in sync with MCRegisterInfo.h.
1029 constexpr unsigned RegUnitBits = 12;
1030 assert(isUInt<RegUnitBits>(FirstRU) && "Too many regunits");
1031 assert(isUInt<32 - RegUnitBits>(Offset) && "Offset is too big");
1032 OS << " { " << RegStrings.get(Seq: Reg.getName().str()) << ", "
1033 << DiffSeqs.get(Seq: SubRegLists[i]) << ", " << DiffSeqs.get(Seq: SuperRegLists[i])
1034 << ", " << SubRegIdxSeqs.get(Seq: SubRegIdxLists[i]) << ", "
1035 << (Offset << RegUnitBits | FirstRU) << ", "
1036 << LaneMaskSeqs.get(Seq: RegUnitLaneMasks[i]) << ", " << Reg.Constant << ", "
1037 << Reg.Artificial << " },\n";
1038 ++i;
1039 }
1040 OS << "};\n\n"; // End of register descriptors...
1041
1042 // Emit the table of register unit roots. Each regunit has one or two root
1043 // registers.
1044 OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
1045 for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {
1046 ArrayRef<const CodeGenRegister *> Roots = RegBank.getRegUnit(RUID: i).getRoots();
1047 assert(!Roots.empty() && "All regunits must have a root register.");
1048 assert(Roots.size() <= 2 && "More than two roots not supported yet.");
1049 OS << " { ";
1050 ListSeparator LS;
1051 for (const CodeGenRegister *R : Roots)
1052 OS << LS << getQualifiedName(R: R->TheDef);
1053 OS << " },\n";
1054 }
1055 OS << "};\n\n";
1056
1057 // Emit the table of register unit intervals.
1058 if (Target.getRegistersAreIntervals()) {
1059 OS << "extern const unsigned " << TargetName
1060 << "RegUnitIntervals[][2] = {\n";
1061 // Add entry for NoRegister
1062 OS << " { 0, 0 },\n";
1063 for (const CodeGenRegister &Reg : Regs) {
1064 const auto &Units = Reg.getNativeRegUnits();
1065 if (Units.empty()) {
1066 OS << " { 0, 0 },\n";
1067 } else {
1068 unsigned First = Units.find_first();
1069 unsigned Last = Units.find_last();
1070 OS << " { " << First << ", " << Last + 1 << " },\n";
1071 }
1072 }
1073 OS << "};\n\n";
1074 }
1075
1076 // Emit register class bit mask tables. The first bit mask emitted for a
1077 // register class, RC, is the set of sub-classes, including RC itself.
1078 //
1079 // If RC has super-registers, also create a list of subreg indices and bit
1080 // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
1081 // SuperRC, that satisfies:
1082 //
1083 // For all SuperReg in SuperRC: SuperReg:Idx in RC
1084 //
1085 // The 0-terminated list of subreg indices starts at:
1086 //
1087 // RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
1088 //
1089 // The corresponding bitmasks follow the sub-class mask in memory. Each
1090 // mask has RCMaskWords uint32_t entries.
1091 //
1092 // Every bit mask present in the list has at least one bit set.
1093
1094 const auto &RegisterClasses = RegBank.getRegClasses();
1095
1096 OS << "// Register classes...\n";
1097
1098 SequenceToOffsetTable<std::string> RegClassStrings;
1099 // Start indices for per-reg-class info in the respective arrays.
1100 struct StartIndex {
1101 unsigned RegIdx;
1102 unsigned BitSetIdx;
1103 unsigned SubClassMaskIdx;
1104 unsigned SuperClassIdx;
1105 };
1106 SmallVector<StartIndex> StartIndices;
1107 StartIndices.reserve(N: RegisterClasses.size() + 1);
1108 StartIndices.push_back(Elt: StartIndex{.RegIdx: 0, .BitSetIdx: 0, .SubClassMaskIdx: 0, .SuperClassIdx: 0});
1109
1110 // For compressing the sub-reg index lists.
1111 using IdxList = std::vector<const CodeGenSubRegIndex *>;
1112 SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
1113 SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
1114 BitVector MaskBV(RegisterClasses.size());
1115 for (const auto &RC : RegisterClasses) {
1116 ArrayRef<const Record *> Order = RC.getOrder();
1117 RegClassStrings.add(Seq: RC.getName());
1118
1119 unsigned MaxRegVal = 0;
1120 for (const Record *Reg : Order)
1121 MaxRegVal = std::max(a: MaxRegVal, b: RegBank.getReg(Reg)->EnumValue);
1122
1123 unsigned SubClassMaskSize = (RC.getSubClasses().size() + 31) / 32;
1124 IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
1125 for (auto &Idx : SubRegIndices) {
1126 MaskBV.reset();
1127 RC.getSuperRegClasses(SubIdx: &Idx, Out&: MaskBV);
1128 if (MaskBV.none())
1129 continue;
1130 SRIList.push_back(x: &Idx);
1131 SubClassMaskSize += (MaskBV.size() + 31) / 32;
1132 }
1133 SuperRegIdxSeqs.add(Seq: SRIList);
1134
1135 const auto &Last = StartIndices.back();
1136 StartIndices.push_back(Elt: StartIndex{
1137 .RegIdx: Last.RegIdx + unsigned(Order.size()),
1138 // Round to next byte size.
1139 .BitSetIdx: Last.BitSetIdx + (Order.empty() ? 0 : (MaxRegVal / 8) + 1),
1140 .SubClassMaskIdx: Last.SubClassMaskIdx + SubClassMaskSize,
1141 .SuperClassIdx: Last.SuperClassIdx + unsigned(RC.getSuperClasses().size()),
1142 });
1143 }
1144
1145 RegClassStrings.layout();
1146 RegClassStrings.emitStringLiteralDef(
1147 OS, Decl: Twine("extern const char ") + TargetName + "RegClassStrings[]");
1148
1149 SuperRegIdxSeqs.layout();
1150
1151 const auto &Totals = StartIndices.back();
1152 raw_string_ostream(MCRegisterClassStorageType)
1153 << "MCRegisterClassStorage<" << RegisterClasses.size() << ", "
1154 << Totals.RegIdx << ", " << Totals.BitSetIdx << ", "
1155 << Totals.SubClassMaskIdx << ", " << SuperRegIdxSeqs.size() << ", "
1156 << Totals.SuperClassIdx << ">";
1157 OS << "using " << TargetName
1158 << "RegisterClassStorage = " << MCRegisterClassStorageType << ";\n";
1159 OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
1160 << "MCRegisterClassStorage = {\n"
1161 << " {\n";
1162
1163 for (const auto &It : enumerate(First: RegisterClasses)) {
1164 const auto &RC = It.value();
1165 const auto &RCIndices = StartIndices[It.index()];
1166 uint32_t RegSize = 0;
1167 if (RC.RSI.isSimple())
1168 RegSize = RC.RSI.getSimple().RegSize;
1169
1170 // Helper to generate offsetof macro for relative offset in storage.
1171 auto GetOff = [&](std::string_view Member,
1172 unsigned DataIdx) -> std::string {
1173 return ("offsetof(" + Twine(TargetName) + "RegisterClassStorage, " +
1174 Member + "[" + Twine(DataIdx) + "]) - " + Twine(It.index()) +
1175 " * sizeof(MCRegisterClass)")
1176 .str();
1177 };
1178
1179 unsigned BitSetSize =
1180 StartIndices[It.index() + 1].BitSetIdx - RCIndices.BitSetIdx;
1181 OS << " {\n " << GetOff("Regs", RCIndices.RegIdx) << ",\n "
1182 << GetOff("BitSets", RCIndices.BitSetIdx) << ",\n "
1183 << RegClassStrings.get(Seq: RC.getName()) << ",\n " << RegSize
1184 << ",\n " << RC.getOrder().size() << ",\n " << BitSetSize
1185 << ",\n " << RC.getQualifiedIdName() << ",\n "
1186 << static_cast<unsigned>(RC.CopyCost) << ", /* CopyCost */\n "
1187 << (RC.Allocatable ? "true" : "false") << ", /* Allocatable */\n "
1188 << (RC.getBaseClassOrder() ? "true" : "false") << ",\n "
1189 << GetOff("SubClassMasks", RCIndices.SubClassMaskIdx) << ",\n "
1190 << GetOff("SuperRegIdxSeqs",
1191 SuperRegIdxSeqs.get(Seq: SuperRegIdxLists[RC.EnumValue]))
1192 << ",\n ";
1193 printMask(OS, Val: RC.LaneMask);
1194 OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
1195 << (RC.GlobalPriority ? "true" : "false") << ",\n "
1196 << format(Fmt: "0x%02x", Vals: RC.TSFlags) << ", /* TSFlags */\n "
1197 << (unsigned)RC.SpillStackID << ", /* SpillStackID */\n "
1198 << (RC.HasDisjunctSubRegs ? "true" : "false")
1199 << ", /* HasDisjunctSubRegs */\n "
1200 << (RC.CoveredBySubRegs ? "true" : "false")
1201 << ", /* CoveredBySubRegs */\n "
1202 << GetOff("SuperClasses", RCIndices.SuperClassIdx) << ",\n "
1203 << RC.getSuperClasses().size() << "\n },\n";
1204 }
1205
1206 OS << " },\n {\n";
1207
1208 // Emit registers.
1209 // TODO: these sequences often have overlaps which could be deduplicated.
1210 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1211 ArrayRef<const Record *> Order = RC.getOrder();
1212 if (Order.empty())
1213 continue;
1214 OS << " /* " << StartIndices[Idx].RegIdx << " */ ";
1215 for (const Record *Reg : Order)
1216 OS << getQualifiedName(R: Reg) << ", ";
1217 OS << "\n";
1218 }
1219
1220 OS << " },\n {\n";
1221
1222 // Emit register bit sets.
1223 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1224 ArrayRef<const Record *> Order = RC.getOrder();
1225 if (!Order.empty()) {
1226 OS << " /* " << StartIndices[Idx].BitSetIdx << " */ ";
1227 BitVectorEmitter BVE;
1228 for (const Record *Reg : Order)
1229 BVE.add(v: RegBank.getReg(Reg)->EnumValue);
1230 BVE.print(OS);
1231 OS << "\n";
1232 }
1233 }
1234 OS << " },\n {\n";
1235
1236 // Emit subclass masks.
1237 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1238 OS << " // " << StartIndices[Idx].SubClassMaskIdx << " " << RC.getName()
1239 << "\n ";
1240 printBitVectorAsHex(OS, Bits: RC.getSubClasses(), Width: 32);
1241
1242 // Emit super-reg class masks for any relevant SubRegIndices that can
1243 // project into RC.
1244 for (auto &Idx : SubRegIndices) {
1245 MaskBV.reset();
1246 RC.getSuperRegClasses(SubIdx: &Idx, Out&: MaskBV);
1247 if (MaskBV.none())
1248 continue;
1249 OS << "\n ";
1250 printBitVectorAsHex(OS, Bits: MaskBV, Width: 32);
1251 OS << "// " << Idx.getName();
1252 }
1253 OS << "\n";
1254 }
1255 OS << " },\n {\n";
1256
1257 // Emit SubRegIdxSeqs.
1258 SuperRegIdxSeqs.emit(OS, Print: printSubRegIndex);
1259 OS << " },\n {\n";
1260
1261 // Emit super-class lists.
1262 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1263 ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
1264 OS << " /* " << StartIndices[Idx].SuperClassIdx << " " << RC.getName()
1265 << " */ ";
1266 for (const auto *Super : Supers)
1267 OS << Super->getQualifiedIdName() << ", ";
1268 OS << "\n";
1269 }
1270
1271 OS << " }\n};\n\n";
1272 OS << "const MCRegisterClass &get" << Target.getName()
1273 << "MCRegisterClass(unsigned RC) {\n"
1274 << " return " << Target.getName()
1275 << "MCRegisterClassStorage.Classes[RC];\n"
1276 << "}\n\n";
1277
1278 EmitRegMappingTables(OS, Regs, isCtor: false);
1279
1280 // Emit Reg encoding table
1281 OS << "extern const uint16_t " << TargetName;
1282 OS << "RegEncodingTable[] = {\n";
1283 // Add entry for NoRegister
1284 OS << " 0,\n";
1285 for (const auto &RE : Regs) {
1286 const Record *Reg = RE.TheDef;
1287 const BitsInit *BI = Reg->getValueAsBitsInit(FieldName: "HWEncoding");
1288 uint64_t Value = BI->convertKnownBitsToInt();
1289 OS << " " << Value << ",\n";
1290 }
1291 OS << "};\n"; // End of HW encoding table
1292
1293 // MCRegisterInfo initialization routine.
1294 OS << "static inline void Init" << TargetName
1295 << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
1296 << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "
1297 "{\n"
1298 << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
1299 << Regs.size() + 1 << ", RA, PC, " << TargetName
1300 << "MCRegisterClassStorage.Classes, " << RegisterClasses.size() << ", "
1301 << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", "
1302 << TargetName << "RegDiffLists, " << TargetName << "LaneMaskLists, "
1303 << TargetName << "RegStrings, " << TargetName << "RegClassStrings, "
1304 << TargetName << "SubRegIdxLists, " << (llvm::size(Range: SubRegIndices) + 1)
1305 << ",\n"
1306 << TargetName << "RegEncodingTable, "
1307 << (Target.getRegistersAreIntervals() ? TargetName + "RegUnitIntervals"
1308 : "nullptr")
1309 << ");\n\n";
1310
1311 EmitRegMapping(OS, Regs, isCtor: false);
1312
1313 OS << "}\n\n";
1314
1315 // Emit the register by HwMode (if present).
1316 ArrayRef<const Record *> RegisterByHwModeRecords =
1317 Records.getAllDerivedDefinitions(ClassName: "RegisterByHwMode");
1318 if (!RegisterByHwModeRecords.empty()) {
1319 OS << "// Registers by HwMode\n";
1320 NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace +
1321 "::RegisterByHwMode");
1322
1323 unsigned NumModes = Target.getHwModes().getNumModeIds();
1324 for (const Record *Rec : RegisterByHwModeRecords) {
1325 RegisterByHwMode RegByMode(Rec, RegBank);
1326 OS << "LLVM_READONLY MCRegister get" << Rec->getName()
1327 << "(unsigned HwMode) {\n";
1328 OS << indent(2) << "switch (HwMode) {\n";
1329 for (unsigned M = 0; M < NumModes; ++M) {
1330 if (RegByMode.hasMode(M)) {
1331 const CodeGenRegister *R = RegByMode.get(Mode: M);
1332 OS << indent(2) << "case " << M << ": return "
1333 << getQualifiedName(R: R->TheDef) << "; // "
1334 << Target.getHwModes().getModeName(Id: M, IncludeDefault: true) << "\n";
1335 }
1336 }
1337 OS << indent(2)
1338 << "default: llvm_unreachable(\"Unhandled HwMode for Register "
1339 << Rec->getName() << "\");\n"
1340 << indent(2) << "}\n"
1341 << "}\n";
1342 }
1343 }
1344}
1345
1346void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
1347 StringRef FilenamePrefix) {
1348 emitInclude(FilenamePrefix, IncludeFile: "Header.inc", GuardMacro: "GET_REGINFO_HEADER", OS&: MainOS);
1349
1350 emitSourceFileHeader(Desc: "Register Information Header Fragment", OS);
1351
1352 const std::string &TargetName = Target.getName().str();
1353 std::string ClassName = TargetName + "GenRegisterInfo";
1354
1355 OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";
1356
1357 NamespaceEmitter LlvmNS(OS, "llvm");
1358
1359 OS << "class " << TargetName << "FrameLowering;\n\n";
1360
1361 OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
1362 << "MCRegisterClassStorage;\n\n";
1363
1364 OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
1365 << " explicit " << ClassName
1366 << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
1367 << " unsigned PC = 0, unsigned HwMode = 0);\n";
1368 if (!RegBank.getSubRegIndices().empty()) {
1369 OS << " unsigned composeSubRegIndicesImpl"
1370 << "(unsigned, unsigned) const override;\n"
1371 << " unsigned reverseComposeSubRegIndicesImpl"
1372 << "(unsigned, unsigned) const override;\n"
1373 << " LaneBitmask composeSubRegIndexLaneMaskImpl"
1374 << "(unsigned, LaneBitmask) const override;\n"
1375 << " LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
1376 << "(unsigned, LaneBitmask) const override;\n"
1377 << " const TargetRegisterClass *getSubClassWithSubReg"
1378 << "(const TargetRegisterClass *, unsigned) const override;\n"
1379 << " const TargetRegisterClass *getSubRegisterClass"
1380 << "(const TargetRegisterClass *, unsigned) const override;\n";
1381 }
1382 OS << " const RegClassWeight &getRegClassWeight("
1383 << "const TargetRegisterClass *RC) const override;\n"
1384 << " unsigned getRegUnitWeight(MCRegUnit RegUnit) const override;\n"
1385 << " unsigned getNumRegPressureSets() const override;\n"
1386 << " const char *getRegPressureSetName(unsigned Idx) const override;\n"
1387 << " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
1388 "Idx) const override;\n"
1389 << " const int *getRegClassPressureSets("
1390 << "const TargetRegisterClass *RC) const override;\n"
1391 << " const int *getRegUnitPressureSets("
1392 << "MCRegUnit RegUnit) const override;\n"
1393 << " ArrayRef<const char *> getRegMaskNames() const override;\n"
1394 << " ArrayRef<const uint32_t *> getRegMasks() const override;\n"
1395 << " bool isGeneralPurposeRegister(const MachineFunction &, "
1396 << "MCRegister) const override;\n"
1397 << " bool isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
1398 << " const override;\n"
1399 << " bool isFixedRegister(const MachineFunction &, "
1400 << "MCRegister) const override;\n"
1401 << " bool isArgumentRegister(const MachineFunction &, "
1402 << "MCRegister) const override;\n"
1403 << " bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"
1404 << " /// Devirtualized TargetFrameLowering.\n"
1405 << " static const " << TargetName << "FrameLowering *getFrameLowering(\n"
1406 << " const MachineFunction &MF);\n";
1407
1408 const auto &RegisterClasses = RegBank.getRegClasses();
1409 if (llvm::any_of(Range: RegisterClasses,
1410 P: [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
1411 OS << " ArrayRef<MCPhysReg> getRawAllocationOrder("
1412 "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
1413 "const override;\n";
1414 }
1415 if (llvm::any_of(Range: RegisterClasses,
1416 P: [](const auto &RC) { return RC.getBaseClassOrder(); })) {
1417 OS << " const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "
1418 "const override;\n";
1419 }
1420 if (!RegisterClasses.empty()) {
1421 OS << " const TargetRegisterClass *getMinimalPhysRegClass("
1422 "MCRegister Reg) const override;\n";
1423 }
1424
1425 OS << "};\n\n";
1426
1427 if (!RegisterClasses.empty()) {
1428 NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace);
1429 OS << "// Register classes\n";
1430
1431 for (const auto &RC : RegisterClasses) {
1432 // Output the extern for the instance.
1433 OS << "static constexpr const TargetRegisterClass &" << RC.getName()
1434 << "RegClass = " << TargetName << "MCRegisterClassStorage.Classes["
1435 << RC.EnumValue << "];\n";
1436 }
1437 }
1438}
1439
1440//
1441// runTargetDesc - Output the target register and register file descriptions.
1442//
1443void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
1444 StringRef FilenamePrefix) {
1445 emitInclude(FilenamePrefix, IncludeFile: "TargetDesc.inc", GuardMacro: "GET_REGINFO_TARGET_DESC",
1446 OS&: MainOS);
1447
1448 emitSourceFileHeader(Desc: "Target Register and Register Classes Information", OS);
1449
1450 NamespaceEmitter LlvmNS(OS, "llvm");
1451
1452 // Get access to MCRegisterClass data.
1453 OS << "extern const " << MCRegisterClassStorageType << " " << Target.getName()
1454 << "MCRegisterClassStorage;\n";
1455
1456 // Start out by emitting each of the register classes.
1457 const auto &RegisterClasses = RegBank.getRegClasses();
1458 const auto &SubRegIndices = RegBank.getSubRegIndices();
1459
1460 // Collect all registers belonging to any allocatable class.
1461 std::set<const Record *> AllocatableRegs;
1462
1463 // Collect allocatable registers.
1464 for (const auto &RC : RegisterClasses) {
1465 ArrayRef<const Record *> Order = RC.getOrder();
1466
1467 if (RC.Allocatable)
1468 AllocatableRegs.insert(first: Order.begin(), last: Order.end());
1469 }
1470
1471 const CodeGenHwModes &CGH = Target.getHwModes();
1472 unsigned NumModes = CGH.getNumModeIds();
1473 StringRef TargetName = Target.getName();
1474
1475 // Build a shared array of value types.
1476 SequenceToOffsetTable<std::vector<MVT>> VTSeqs(
1477 /*Terminator=*/MVT::Other);
1478 for (unsigned M = 0; M < NumModes; ++M) {
1479 for (const auto &RC : RegisterClasses) {
1480 std::vector<MVT> S;
1481 for (const ValueTypeByHwMode &VVT : RC.VTs)
1482 if (VVT.hasDefault() || VVT.hasMode(M))
1483 S.push_back(x: VVT.get(Mode: M));
1484 VTSeqs.add(Seq: S);
1485 }
1486 }
1487 VTSeqs.layout();
1488 OS << "\nstatic const MVT::SimpleValueType " << TargetName
1489 << "VTLists[] = {\n";
1490 VTSeqs.emit(OS, Print: printSimpleValueType);
1491 OS << "};\n";
1492
1493 // Emit SubRegIndex names, skipping 0.
1494 SequenceToOffsetTable<std::string> SubRegIndexStrings;
1495 for (const auto &Idx : SubRegIndices)
1496 SubRegIndexStrings.add(Seq: Idx.getName());
1497 SubRegIndexStrings.layout();
1498
1499 SubRegIndexStrings.emitStringLiteralDef(OS, Decl: Twine("static constexpr char ") +
1500 TargetName +
1501 "SubRegIndexStrings[]");
1502
1503 OS << "\nstatic constexpr uint32_t " << TargetName
1504 << "SubRegIndexNameOffsets[] = {\n";
1505 for (const auto &Idx : SubRegIndices)
1506 OS << " " << SubRegIndexStrings.get(Seq: Idx.getName()) << ", \n";
1507 if (SubRegIndices.empty())
1508 OS << " /* dummy */ 0\n";
1509 OS << "};\n\n";
1510
1511 // Emit the table of sub-register index sizes.
1512 OS << "static const TargetRegisterInfo::SubRegCoveredBits " << TargetName
1513 << "SubRegIdxRangeTable[] = {\n";
1514 for (unsigned M = 0; M < NumModes; ++M) {
1515 OS << " { " << (uint32_t)-1 << ", " << (uint32_t)-1 << " },\n";
1516 for (const auto &Idx : SubRegIndices) {
1517 const SubRegRange &Range = Idx.Range.get(Mode: M);
1518 OS << " { " << Range.Offset << ", " << Range.Size << " },\t// "
1519 << Idx.getName() << "\n";
1520 }
1521 }
1522 OS << "};\n\n";
1523
1524 // Emit SubRegIndex lane masks, including 0.
1525 OS << "\nstatic const LaneBitmask " << TargetName
1526 << "SubRegIndexLaneMaskTable[] = {\n "
1527 "LaneBitmask::getAll(),\n";
1528 for (const auto &Idx : SubRegIndices) {
1529 printMask(OS&: OS << " ", Val: Idx.LaneMask);
1530 OS << ", // " << Idx.getName() << '\n';
1531 }
1532 OS << " };\n\n";
1533
1534 OS << "\n";
1535
1536 // Now that all of the structs have been emitted, emit the instances.
1537 if (!RegisterClasses.empty()) {
1538 OS << "\nstatic const TargetRegisterInfo::RegClassInfo " << TargetName
1539 << "RegClassInfos[]" << " = {\n";
1540 for (unsigned M = 0; M < NumModes; ++M) {
1541 unsigned EV = 0;
1542 OS << " // Mode = " << M << " ("
1543 << CGH.getModeName(Id: M, /*IncludeDefault=*/true) << ")\n";
1544 for (const auto &RC : RegisterClasses) {
1545 assert(RC.EnumValue == EV && "Unexpected order of register classes");
1546 ++EV;
1547 (void)EV;
1548 const RegSizeInfo &RI = RC.RSI.get(Mode: M);
1549 OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", "
1550 << RI.SpillAlignment;
1551 std::vector<MVT> VTs;
1552 for (const ValueTypeByHwMode &VVT : RC.VTs)
1553 if (VVT.hasDefault() || VVT.hasMode(M))
1554 VTs.push_back(x: VVT.get(Mode: M));
1555 OS << ", /*" << TargetName << "VTLists+*/" << VTSeqs.get(Seq: VTs)
1556 << " }, // " << RC.getName() << '\n';
1557 }
1558 }
1559 OS << "};\n";
1560
1561 // Emit methods.
1562 for (const auto &RC : RegisterClasses) {
1563 if (!RC.AltOrderSelect.empty()) {
1564 OS << "\nstatic inline unsigned " << RC.getName()
1565 << "AltOrderSelect(const MachineFunction &MF, bool Rev) {"
1566 << RC.AltOrderSelect << "}\n\n"
1567 << "static ArrayRef<MCPhysReg> " << RC.getName()
1568 << "GetRawAllocationOrder(const TargetRegisterClass &RC, "
1569 << "const MachineFunction &MF, bool Rev) {\n";
1570 for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {
1571 ArrayRef<const Record *> Elems = RC.getOrder(No: oi);
1572 if (!Elems.empty()) {
1573 OS << " static const MCPhysReg AltOrder" << oi << "[] = {";
1574 for (unsigned elem = 0; elem != Elems.size(); ++elem)
1575 OS << (elem ? ", " : " ") << getQualifiedName(R: Elems[elem]);
1576 OS << " };\n";
1577 }
1578 }
1579 OS << " const ArrayRef<MCPhysReg> Order[] = {\n"
1580 << " RC.getRegisters(";
1581 for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
1582 if (RC.getOrder(No: oi).empty())
1583 OS << "),\n ArrayRef<MCPhysReg>(";
1584 else
1585 OS << "),\n ArrayRef(AltOrder" << oi;
1586 OS << ")\n };\n const unsigned Select = " << RC.getName()
1587 << "AltOrderSelect(MF, Rev);\n assert(Select < "
1588 << RC.getNumOrders() << ");\n return Order[Select];\n}\n";
1589 }
1590 }
1591 }
1592
1593 // Emit extra information about registers.
1594 const auto &Regs = RegBank.getRegisters();
1595 unsigned NumRegCosts = 1;
1596 for (const auto &Reg : Regs)
1597 NumRegCosts = std::max(a: (size_t)NumRegCosts, b: Reg.CostPerUse.size());
1598
1599 std::vector<unsigned> AllRegCostPerUse;
1600 llvm::BitVector InAllocClass(Regs.size() + 1, false);
1601 AllRegCostPerUse.insert(position: AllRegCostPerUse.end(), n: NumRegCosts, x: 0);
1602
1603 // Populate the vector RegCosts with the CostPerUse list of the registers
1604 // in the order they are read. Have at most NumRegCosts entries for
1605 // each register. Fill with zero for values which are not explicitly given.
1606 for (const auto &Reg : Regs) {
1607 auto Costs = Reg.CostPerUse;
1608 llvm::append_range(C&: AllRegCostPerUse, R&: Costs);
1609 if (NumRegCosts > Costs.size())
1610 AllRegCostPerUse.insert(position: AllRegCostPerUse.end(),
1611 n: NumRegCosts - Costs.size(), x: 0);
1612
1613 if (AllocatableRegs.count(x: Reg.TheDef))
1614 InAllocClass.set(Reg.EnumValue);
1615 }
1616
1617 // Emit the cost values as a 1D-array after grouping them by their indices,
1618 // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
1619 // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
1620 OS << "\nstatic const uint8_t " << TargetName << "CostPerUseTable[] = { \n";
1621 for (unsigned int I = 0; I < NumRegCosts; ++I) {
1622 for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
1623 OS << AllRegCostPerUse[J] << ", ";
1624 }
1625 OS << "};\n\n";
1626
1627 OS << "\nstatic const bool " << TargetName
1628 << "InAllocatableClassTable[] = { \n";
1629 for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
1630 OS << (InAllocClass[I] ? "true" : "false") << ", ";
1631 }
1632 OS << "};\n\n";
1633
1634 OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
1635 << "RegInfoDesc = { // Extra Descriptors\n";
1636 OS << TargetName << "CostPerUseTable, " << NumRegCosts << ", " << TargetName
1637 << "InAllocatableClassTable";
1638 OS << "};\n\n"; // End of register descriptors.
1639
1640 std::string ClassName = Target.getName().str() + "GenRegisterInfo";
1641
1642 size_t SubRegIndicesSize = llvm::size(Range: SubRegIndices);
1643
1644 if (!SubRegIndices.empty()) {
1645 emitComposeSubRegIndices(OS, ClassName);
1646 emitComposeSubRegIndexLaneMask(OS, ClassName);
1647 }
1648
1649 if (!SubRegIndices.empty()) {
1650 // Emit getSubClassWithSubReg.
1651 OS << "const TargetRegisterClass *" << ClassName
1652 << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
1653 << " const {\n";
1654 // Use the smallest type that can hold a regclass ID with room for a
1655 // sentinel.
1656 const size_t NumRegClasses = RegisterClasses.size();
1657 const char *RegClassTy = getMinimalTypeForRange(Range: NumRegClasses + 1);
1658 auto EmitTableLookup = [&]() {
1659 OS << formatv(Fmt: R"(
1660 };
1661 assert(RC && "Missing regclass");
1662 if (!Idx) return RC;
1663 --Idx;
1664 assert(Idx < {} && "Bad subreg");
1665 unsigned TV = Table[RC->getID()][Idx];
1666 return TV ? getRegClass(TV - 1) : nullptr;
1667})",
1668 Vals&: SubRegIndicesSize);
1669 };
1670
1671 OS << formatv(Fmt: " static constexpr {} Table[{}][{}] = {{\n", Vals&: RegClassTy,
1672 Vals: NumRegClasses, Vals&: SubRegIndicesSize);
1673 for (const auto &RC : RegisterClasses) {
1674 OS << " {\t// " << RC.getName() << "\n";
1675 for (auto &Idx : SubRegIndices) {
1676 if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(SubIdx: &Idx))
1677 OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
1678 << " -> " << SRC->getName() << "\n";
1679 else
1680 OS << " 0,\t// " << Idx.getName() << "\n";
1681 }
1682 OS << " },\n";
1683 }
1684 EmitTableLookup();
1685
1686 // Emit getSubRegisterClass.
1687 OS << "const TargetRegisterClass *" << ClassName
1688 << "::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx)"
1689 << " const {\n";
1690
1691 OS << formatv(Fmt: " static constexpr {} Table[{}][{}] = {{\n", Vals&: RegClassTy,
1692 Vals: NumRegClasses, Vals&: SubRegIndicesSize);
1693 for (const auto &RC : RegisterClasses) {
1694 OS << " {\t// " << RC.getName() << '\n';
1695 for (auto &Idx : SubRegIndices) {
1696 std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
1697 MatchingSubClass = RC.getMatchingSubClassWithSubRegs(RegBank, SubIdx: &Idx);
1698
1699 unsigned EnumValue = 0;
1700 if (MatchingSubClass) {
1701 CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1702 EnumValue = SubRegClass->EnumValue + 1;
1703 }
1704
1705 OS << " " << EnumValue << ",\t// " << RC.getName() << ':'
1706 << Idx.getName();
1707
1708 if (MatchingSubClass) {
1709 CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1710 OS << " -> " << SubRegClass->getName();
1711 }
1712
1713 OS << '\n';
1714 }
1715
1716 OS << " },\n";
1717 }
1718 EmitTableLookup();
1719 }
1720
1721 EmitRegUnitPressure(OS, ClassName);
1722
1723 if (llvm::any_of(Range: RegisterClasses,
1724 P: [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
1725 OS << "ArrayRef<MCPhysReg> " << ClassName
1726 << "::getRawAllocationOrder("
1727 "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
1728 "const {\n";
1729 OS << " switch (RC.getID()) {\n";
1730 for (const auto &RC : RegisterClasses) {
1731 if (RC.AltOrderSelect.empty())
1732 continue;
1733 OS << " case " << RC.getQualifiedIdName() << ":\n"
1734 << " return " << RC.getName()
1735 << "GetRawAllocationOrder(RC, MF, Rev);\n";
1736 ;
1737 }
1738 OS << " }\n";
1739 OS << " return RC.getRegisters();\n";
1740 OS << "}\n\n";
1741 }
1742
1743 // Emit register base class mapper
1744 if (!RegisterClasses.empty()) {
1745 // Collect base classes
1746 SmallVector<const CodeGenRegisterClass *> BaseClasses;
1747 for (const auto &RC : RegisterClasses) {
1748 if (RC.getBaseClassOrder())
1749 BaseClasses.push_back(Elt: &RC);
1750 }
1751 if (!BaseClasses.empty()) {
1752 assert(BaseClasses.size() < UINT16_MAX &&
1753 "Too many base register classes");
1754
1755 // Apply order
1756 struct BaseClassOrdering {
1757 bool operator()(const CodeGenRegisterClass *LHS,
1758 const CodeGenRegisterClass *RHS) const {
1759 return std::pair(*LHS->getBaseClassOrder(), LHS->EnumValue) <
1760 std::pair(*RHS->getBaseClassOrder(), RHS->EnumValue);
1761 }
1762 };
1763 llvm::stable_sort(Range&: BaseClasses, C: BaseClassOrdering());
1764
1765 OS << "\n// Register to base register class mapping\n\n";
1766 OS << "\n";
1767 OS << "const TargetRegisterClass *" << ClassName
1768 << "::getPhysRegBaseClass(MCRegister Reg)"
1769 << " const {\n";
1770 OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
1771 OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
1772 OS << " InvalidRegClassID, // NoRegister\n";
1773 for (const CodeGenRegister &Reg : Regs) {
1774 const CodeGenRegisterClass *BaseRC = nullptr;
1775 for (const CodeGenRegisterClass *RC : BaseClasses) {
1776 if (RC->contains(&Reg)) {
1777 BaseRC = RC;
1778 break;
1779 }
1780 }
1781
1782 OS << " "
1783 << (BaseRC ? BaseRC->getQualifiedIdName() : "InvalidRegClassID")
1784 << ", // " << Reg.getName() << "\n";
1785 }
1786 OS << " };\n\n"
1787 " assert(Reg < ArrayRef(Mapping).size());\n"
1788 " unsigned RCID = Mapping[Reg.id()];\n"
1789 " if (RCID == InvalidRegClassID)\n"
1790 " return nullptr;\n"
1791 " return &"
1792 << TargetName
1793 << "MCRegisterClassStorage.Classes[RCID];\n"
1794 "}\n";
1795 }
1796 }
1797
1798 if (!RegisterClasses.empty()) {
1799 assert(RegisterClasses.size() < UINT16_MAX &&
1800 "Too many minimal register classes");
1801
1802 OS << "\n// Register to minimal register class mapping\n\n";
1803 OS << "const TargetRegisterClass *" << ClassName
1804 << "::getMinimalPhysRegClass(MCRegister Reg)" << " const {\n";
1805 OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
1806 OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
1807 OS << " InvalidRegClassID, // NoRegister\n";
1808 for (const CodeGenRegister &Reg : Regs) {
1809 const CodeGenRegisterClass *MinimalRC = nullptr;
1810 for (const auto &RC : RegisterClasses) {
1811 if (RC.contains(&Reg) && (!MinimalRC || MinimalRC->hasSubClass(RC: &RC)))
1812 MinimalRC = &RC;
1813 }
1814
1815 OS << " "
1816 << (MinimalRC ? MinimalRC->getQualifiedIdName() : "InvalidRegClassID")
1817 << ", // " << Reg.getName() << "\n";
1818 }
1819 OS << " };\n\n"
1820 " assert(Reg < ArrayRef(Mapping).size());\n"
1821 " unsigned RCID = Mapping[Reg.id()];\n"
1822 " if (RCID == InvalidRegClassID)\n"
1823 " return nullptr;\n"
1824 " return &"
1825 << TargetName
1826 << "MCRegisterClassStorage.Classes[RCID];\n"
1827 "}\n";
1828 }
1829
1830 // Emit the constructor of the class...
1831 OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
1832 OS << "extern const int16_t " << TargetName << "RegDiffLists[];\n";
1833 OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";
1834 OS << "extern const char " << TargetName << "RegStrings[];\n";
1835 OS << "extern const char " << TargetName << "RegClassStrings[];\n";
1836 OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
1837 OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
1838 OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
1839 if (Target.getRegistersAreIntervals())
1840 OS << "extern const unsigned " << TargetName << "RegUnitIntervals[][2];\n";
1841
1842 EmitRegMappingTables(OS, Regs, isCtor: true);
1843
1844 OS << formatv(Fmt: R"(
1845{0}::
1846{0}(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
1847 unsigned PC, unsigned HwMode)
1848 : TargetRegisterInfo(&{1}RegInfoDesc,
1849 {1}SubRegIndexStrings, {1}SubRegIndexNameOffsets,
1850 {1}SubRegIdxRangeTable, {1}SubRegIndexLaneMaskTable,
1851
1852 )",
1853 Vals&: ClassName, Vals&: TargetName);
1854 printMask(OS, Val: RegBank.CoveringLanes);
1855 OS << formatv(Fmt: R"(, {0}RegClassInfos, {0}VTLists, HwMode) {{
1856 InitMCRegisterInfo({0}RegDesc, {1}, RA, PC,
1857 &get{0}MCRegisterClass(0), {2}, {0}RegUnitRoots, {3}, {0}RegDiffLists,
1858 {0}LaneMaskLists, {0}RegStrings, {0}RegClassStrings, {0}SubRegIdxLists, {4},
1859 {0}RegEncodingTable, {5});
1860
1861)",
1862 Vals&: TargetName, Vals: Regs.size() + 1, Vals: RegisterClasses.size(),
1863 Vals: RegBank.getNumNativeRegUnits(), Vals: SubRegIndicesSize + 1,
1864 Vals: Target.getRegistersAreIntervals()
1865 ? TargetName + "RegUnitIntervals"
1866 : Twine("nullptr"));
1867 EmitRegMapping(OS, Regs, isCtor: true);
1868
1869 OS << "}\n\n";
1870
1871 // Emit CalleeSavedRegs information.
1872 ArrayRef<const Record *> CSRSets =
1873 Records.getAllDerivedDefinitions(ClassName: "CalleeSavedRegs");
1874 for (const Record *CSRSet : CSRSets) {
1875 const SetTheory::RecVec *Regs = RegBank.getSets().expand(Set: CSRSet);
1876 assert(Regs && "Cannot expand CalleeSavedRegs instance");
1877
1878 // Emit the *_SaveList list of callee-saved registers.
1879 OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { ";
1880 for (const Record *Reg : *Regs)
1881 OS << getQualifiedName(R: Reg) << ", ";
1882 OS << "0 };\n";
1883
1884 // Emit the *_RegMask bit mask of call-preserved registers.
1885 BitVector Covered = RegBank.computeCoveredRegisters(Regs: *Regs);
1886
1887 // Check for an optional OtherPreserved set.
1888 // Add those registers to RegMask, but not to SaveList.
1889 if (const DagInit *OPDag =
1890 dyn_cast<DagInit>(Val: CSRSet->getValueInit(FieldName: "OtherPreserved"))) {
1891 SetTheory::RecSet OPSet;
1892 RegBank.getSets().evaluate(Expr: OPDag, Elts&: OPSet, Loc: CSRSet->getLoc());
1893 Covered |= RegBank.computeCoveredRegisters(Regs: OPSet.getArrayRef());
1894 }
1895
1896 // Add all constant physical registers to the preserved mask:
1897 SetTheory::RecSet ConstantSet;
1898 for (const auto &Reg : RegBank.getRegisters()) {
1899 if (Reg.Constant)
1900 ConstantSet.insert(X: Reg.TheDef);
1901 }
1902 Covered |= RegBank.computeCoveredRegisters(Regs: ConstantSet.getArrayRef());
1903
1904 OS << "static const uint32_t " << CSRSet->getName() << "_RegMask[] = { ";
1905 printBitVectorAsHex(OS, Bits: Covered, Width: 32);
1906 OS << "};\n";
1907 }
1908 OS << "\n\n";
1909
1910 OS << "ArrayRef<const uint32_t *> " << ClassName
1911 << "::getRegMasks() const {\n";
1912 if (!CSRSets.empty()) {
1913 OS << " static const uint32_t *const Masks[] = {\n";
1914 for (const Record *CSRSet : CSRSets)
1915 OS << " " << CSRSet->getName() << "_RegMask,\n";
1916 OS << " };\n";
1917 OS << " return ArrayRef(Masks);\n";
1918 } else {
1919 OS << " return {};\n";
1920 }
1921 OS << "}\n\n";
1922
1923 const std::list<CodeGenRegisterCategory> &RegCategories =
1924 RegBank.getRegCategories();
1925 OS << "bool " << ClassName << "::\n"
1926 << "isGeneralPurposeRegister(const MachineFunction &MF, "
1927 << "MCRegister PhysReg) const {\n"
1928 << " return\n";
1929 for (const CodeGenRegisterCategory &Category : RegCategories)
1930 if (Category.getName() == "GeneralPurposeRegisters") {
1931 for (const CodeGenRegisterClass *RC : Category.getClasses())
1932 OS << " " << RC->getQualifiedName()
1933 << "RegClass.contains(PhysReg) ||\n";
1934 break;
1935 }
1936 OS << " false;\n";
1937 OS << "}\n\n";
1938
1939 OS << "bool " << ClassName << "::\n"
1940 << "isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
1941 << " const {\n"
1942 << " return\n";
1943 for (const CodeGenRegisterCategory &Category : RegCategories)
1944 if (Category.getName() == "GeneralPurposeRegisters") {
1945 for (const CodeGenRegisterClass *RC : Category.getClasses())
1946 OS << " " << RC->getQualifiedName()
1947 << "RegClass.hasSubClassEq(RC) ||\n";
1948 break;
1949 }
1950 OS << " false;\n";
1951 OS << "}\n\n";
1952
1953 OS << "bool " << ClassName << "::\n"
1954 << "isFixedRegister(const MachineFunction &MF, "
1955 << "MCRegister PhysReg) const {\n"
1956 << " return\n";
1957 for (const CodeGenRegisterCategory &Category : RegCategories)
1958 if (Category.getName() == "FixedRegisters") {
1959 for (const CodeGenRegisterClass *RC : Category.getClasses())
1960 OS << " " << RC->getQualifiedName()
1961 << "RegClass.contains(PhysReg) ||\n";
1962 break;
1963 }
1964 OS << " false;\n";
1965 OS << "}\n\n";
1966
1967 OS << "bool " << ClassName << "::\n"
1968 << "isArgumentRegister(const MachineFunction &MF, "
1969 << "MCRegister PhysReg) const {\n"
1970 << " return\n";
1971 for (const CodeGenRegisterCategory &Category : RegCategories)
1972 if (Category.getName() == "ArgumentRegisters") {
1973 for (const CodeGenRegisterClass *RC : Category.getClasses())
1974 OS << " " << RC->getQualifiedName()
1975 << "RegClass.contains(PhysReg) ||\n";
1976 break;
1977 }
1978 OS << " false;\n";
1979 OS << "}\n\n";
1980
1981 OS << "bool " << ClassName << "::\n"
1982 << "isConstantPhysReg(MCRegister PhysReg) const {\n"
1983 << " return\n";
1984 for (const auto &Reg : Regs)
1985 if (Reg.Constant)
1986 OS << " PhysReg == " << getQualifiedName(R: Reg.TheDef) << " ||\n";
1987 OS << " false;\n";
1988 OS << "}\n\n";
1989
1990 OS << "ArrayRef<const char *> " << ClassName
1991 << "::getRegMaskNames() const {\n";
1992 if (!CSRSets.empty()) {
1993 OS << " static const char *Names[] = {\n";
1994 for (const Record *CSRSet : CSRSets)
1995 OS << " " << '"' << CSRSet->getName() << '"' << ",\n";
1996 OS << " };\n";
1997 OS << " return ArrayRef(Names);\n";
1998 } else {
1999 OS << " return {};\n";
2000 }
2001 OS << "}\n\n";
2002
2003 OS << "const " << TargetName << "FrameLowering *\n"
2004 << TargetName
2005 << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
2006 << " return static_cast<const " << TargetName << "FrameLowering *>(\n"
2007 << " MF.getSubtarget().getFrameLowering());\n"
2008 << "}\n\n";
2009}
2010
2011TableGenOutputFiles RegisterInfoEmitter::run(StringRef FilenamePrefix) {
2012 TGTimer &Timer = Records.getTimer();
2013 Timer.startTimer(Name: "Print enums");
2014 std::string Main;
2015 raw_string_ostream MainOS(Main);
2016 std::string Enums;
2017 raw_string_ostream EnumsOS(Enums);
2018 runEnums(OS&: EnumsOS, MainOS, FilenamePrefix);
2019
2020 Timer.startTimer(Name: "Print MC registers");
2021 std::string MCDesc;
2022 raw_string_ostream MCDescOS(MCDesc);
2023 runMCDesc(OS&: MCDescOS, MainOS, FilenamePrefix);
2024
2025 Timer.startTimer(Name: "Print header fragment");
2026 std::string Header;
2027 raw_string_ostream HeaderOS(Header);
2028 runTargetHeader(OS&: HeaderOS, MainOS, FilenamePrefix);
2029
2030 Timer.startTimer(Name: "Print target registers");
2031 std::string TargetDesc;
2032 raw_string_ostream TargetDescOS(TargetDesc);
2033 runTargetDesc(OS&: TargetDescOS, MainOS, FilenamePrefix);
2034
2035 if (RegisterInfoDebug)
2036 debugDump(OS&: errs());
2037
2038 // The suffixes should be in sync with the tablegen function in
2039 // llvm/cmake/modules/TableGen.cmake.
2040 return {.MainFile: std::move(Main),
2041 .AdditionalFiles: {{"Enums.inc", Enums},
2042 {"MCDesc.inc", MCDesc},
2043 {"Header.inc", Header},
2044 {"TargetDesc.inc", TargetDesc}}};
2045}
2046
2047template <typename InfoTy, typename FnTy>
2048Printable RegisterInfoEmitter::printByHwMode(const InfoByHwMode<InfoTy> &Info,
2049 FnTy Func) {
2050 return Printable([&](raw_ostream &OS) {
2051 if (Info.isSimple()) {
2052 OS << Func(Info.getSimple());
2053 return;
2054 }
2055
2056 const CodeGenHwModes &CGH = Target.getHwModes();
2057
2058 OS << "{";
2059 for (unsigned M = 0, E = CGH.getNumModeIds(); M != E; ++M)
2060 OS << ' ' << CGH.getModeName(Id: M, /*IncludeDefault=*/true) << ':'
2061 << Func(Info.get(M));
2062 OS << " }";
2063 });
2064}
2065
2066void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
2067 for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
2068 OS << "RegisterClass " << RC.getName() << ":\n";
2069 OS << "\tSpillSize: " << printByHwMode(Info: RC.RSI, Func: [](const RegSizeInfo &Info) {
2070 return Info.SpillSize;
2071 }) << '\n';
2072 OS << "\tSpillAlignment: "
2073 << printByHwMode(
2074 Info: RC.RSI,
2075 Func: [](const RegSizeInfo &Info) { return Info.SpillAlignment; })
2076 << '\n';
2077 OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
2078 OS << "\tLaneMask: " << PrintLaneMask(LaneMask: RC.LaneMask) << '\n';
2079 OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
2080 OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
2081 OS << "\tAllocatable: " << RC.Allocatable << '\n';
2082 OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';
2083 OS << "\tWeight: " << RC.getWeight(RegBank) << '\n';
2084 OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';
2085 OS << "\tRegs:";
2086 for (const CodeGenRegister *R : RC.getMembers()) {
2087 OS << " " << R->getName();
2088 }
2089 OS << '\n';
2090 OS << "\tSubClasses:";
2091 const BitVector &SubClasses = RC.getSubClasses();
2092 for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {
2093 if (!SubClasses.test(Idx: SRC.EnumValue))
2094 continue;
2095 OS << " " << SRC.getName();
2096 }
2097 OS << '\n';
2098 OS << "\tSuperClasses:";
2099 for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {
2100 OS << " " << SRC->getName();
2101 }
2102 OS << '\n';
2103 if (RC.Artificial)
2104 OS << "\tArtificial: 1\n";
2105 }
2106
2107 for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
2108 OS << "SubRegIndex " << SRI.getName() << ":\n";
2109 OS << "\tLaneMask: " << PrintLaneMask(LaneMask: SRI.LaneMask) << '\n';
2110 OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
2111 OS << "\tOffset: " << printByHwMode(Info: SRI.Range, Func: [](const SubRegRange &Info) {
2112 return Info.Offset;
2113 }) << '\n';
2114 OS << "\tSize: " << printByHwMode(Info: SRI.Range, Func: [](const SubRegRange &Info) {
2115 return Info.Size;
2116 }) << '\n';
2117 if (SRI.Artificial)
2118 OS << "\tArtificial: 1\n";
2119 }
2120
2121 for (const CodeGenRegister &R : RegBank.getRegisters()) {
2122 OS << "Register " << R.getName() << ":\n";
2123 OS << "\tCostPerUse: ";
2124 for (const auto &Cost : R.CostPerUse)
2125 OS << Cost << " ";
2126 OS << '\n';
2127 OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
2128 OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
2129 for (auto &[SubIdx, SubReg] : R.getSubRegs()) {
2130 OS << "\tSubReg " << SubIdx->getName() << " = " << SubReg->getName()
2131 << '\n';
2132 }
2133 for (unsigned U : R.getNativeRegUnits())
2134 OS << "\tRegUnit " << U << '\n';
2135 if (R.Artificial)
2136 OS << "\tArtificial: 1\n";
2137 }
2138}
2139
2140static TableGen::Emitter::MultiFileOptClass<RegisterInfoEmitter>
2141 X("gen-register-info", "Generate registers and register classes info");
2142