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