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 V.reserve(N: List.count());
697 SparseBitVector<>::iterator I = List.begin(), E = List.end();
698 unsigned Val = *I;
699 while (++I != E) {
700 unsigned Cur = *I;
701 V.push_back(Elt: Cur - Val);
702 Val = Cur;
703 }
704 return V;
705}
706
707template <typename Iter>
708static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
709 assert(V.empty() && "Clear DiffVec before diffEncode.");
710 V.reserve(N: std::distance(Begin, End));
711 unsigned Val = InitVal;
712 for (Iter I = Begin; I != End; ++I) {
713 unsigned Cur = (*I)->EnumValue;
714 V.push_back(Elt: Cur - Val);
715 Val = Cur;
716 }
717 return V;
718}
719
720static void printDiff16(raw_ostream &OS, int16_t Val) { OS << Val; }
721
722static void printMask(raw_ostream &OS, LaneBitmask Val) {
723 OS << "LaneBitmask(0x" << PrintLaneMask(LaneMask: Val) << ')';
724}
725
726// Try to combine Idx's compose map into Vec if it is compatible.
727// Return false if it's not possible.
728static bool combine(const CodeGenSubRegIndex *Idx,
729 SmallVectorImpl<const CodeGenSubRegIndex *> &Vec) {
730 const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
731 for (const auto &I : Map) {
732 const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
733 if (Entry && Entry != I.second)
734 return false;
735 }
736
737 // All entries are compatible. Make it so.
738 for (const auto &I : Map) {
739 const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
740 assert((!Entry || Entry == I.second) && "Expected EnumValue to be unique");
741 Entry = I.second;
742 }
743 return true;
744}
745
746void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
747 StringRef ClassName) {
748 const auto &SubRegIndices = RegBank.getSubRegIndices();
749
750 // Many sub-register indexes are composition-compatible, meaning that
751 //
752 // compose(IdxA, IdxB) == compose(IdxA', IdxB)
753 //
754 // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
755 // The illegal entries can be use as wildcards to compress the table further.
756
757 // Map each Sub-register index to a compatible table row.
758 SmallVector<unsigned, 4> RowMap;
759 SmallVector<SmallVector<const CodeGenSubRegIndex *, 4>, 4> Rows;
760
761 size_t SubRegIndicesSize = llvm::size(Range: SubRegIndices);
762 for (const auto &Idx : SubRegIndices) {
763 unsigned Found = ~0u;
764 for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
765 if (combine(Idx: &Idx, Vec&: Rows[r])) {
766 Found = r;
767 break;
768 }
769 }
770 if (Found == ~0u) {
771 Found = Rows.size();
772 Rows.resize(N: Found + 1);
773 Rows.back().resize(N: SubRegIndicesSize);
774 combine(Idx: &Idx, Vec&: Rows.back());
775 }
776 RowMap.push_back(Elt: Found);
777 }
778
779 OS << "unsigned " << ClassName
780 << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
781
782 // Output the row map if there are multiple rows.
783 if (Rows.size() > 1) {
784 OS << " static const " << getMinimalTypeForRange(Range: Rows.size(), MaxSize: 32)
785 << " RowMap[" << SubRegIndicesSize << "] = {\n ";
786 for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
787 OS << RowMap[i] << ", ";
788 OS << "\n };\n";
789 }
790
791 // Output the rows.
792 OS << " static const " << getMinimalTypeForRange(Range: SubRegIndicesSize + 1, MaxSize: 32)
793 << " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";
794 for (const auto &Row : Rows) {
795 OS << " { ";
796 for (const llvm::CodeGenSubRegIndex *Elem :
797 ArrayRef(&Row[0], SubRegIndicesSize))
798 if (Elem)
799 OS << Elem->getQualifiedName() << ", ";
800 else
801 OS << "0, ";
802 OS << "},\n";
803 }
804 OS << " };\n\n";
805
806 OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << "); (void) IdxA;\n"
807 << " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
808 if (Rows.size() > 1)
809 OS << " return Rows[RowMap[IdxA]][IdxB];\n";
810 else
811 OS << " return Rows[0][IdxB];\n";
812 OS << "}\n\n";
813
814 // Generate the reverse case.
815 //
816 // FIXME: This is the brute force approach. Compress the table similar to the
817 // forward case.
818 OS << "unsigned " << ClassName
819 << "::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const "
820 "{\n";
821 OS << " static const " << getMinimalTypeForRange(Range: SubRegIndicesSize + 1, MaxSize: 32)
822 << " Table[" << SubRegIndicesSize << "][" << SubRegIndicesSize
823 << "] = {\n";
824
825 // Find values where composeSubReg(A, X) == B;
826 for (const auto &IdxA : SubRegIndices) {
827 OS << " { ";
828
829 SmallVectorImpl<const CodeGenSubRegIndex *> &Row =
830 Rows[RowMap[IdxA.EnumValue - 1]];
831 for (const auto &IdxB : SubRegIndices) {
832 const CodeGenSubRegIndex *FoundReverse = nullptr;
833
834 for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i) {
835 const CodeGenSubRegIndex *This = &SubRegIndices[i];
836 const CodeGenSubRegIndex *Composed = Row[i];
837 if (Composed == &IdxB) {
838 if (FoundReverse && FoundReverse != This) // Not unique
839 break;
840 FoundReverse = This;
841 }
842 }
843
844 if (FoundReverse) {
845 OS << FoundReverse->getQualifiedName() << ", ";
846 } else {
847 OS << "0, ";
848 }
849 }
850 OS << "},\n";
851 }
852
853 OS << " };\n\n";
854 OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << ");\n"
855 << " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
856 OS << " return Table[IdxA][IdxB];\n";
857 OS << " }\n\n";
858}
859
860void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
861 StringRef ClassName) {
862 // See the comments in computeSubRegLaneMasks() for our goal here.
863 const auto &SubRegIndices = RegBank.getSubRegIndices();
864
865 // Create a list of Mask+Rotate operations, with equivalent entries merged.
866 SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
867 SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
868 for (const auto &Idx : SubRegIndices) {
869 const SmallVector<MaskRolPair, 1> &IdxSequence =
870 Idx.CompositionLaneMaskTransform;
871
872 unsigned Found = ~0u;
873 unsigned SIdx = 0;
874 unsigned NextSIdx;
875 for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
876 SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
877 NextSIdx = SIdx + Sequence.size() + 1;
878 if (Sequence == IdxSequence) {
879 Found = SIdx;
880 break;
881 }
882 }
883 if (Found == ~0u) {
884 Sequences.push_back(Elt: IdxSequence);
885 Found = SIdx;
886 }
887 SubReg2SequenceIndexMap.push_back(Elt: Found);
888 }
889
890 OS << " struct MaskRolOp {\n"
891 " LaneBitmask Mask;\n"
892 " uint8_t RotateLeft;\n"
893 " };\n"
894 " static const MaskRolOp LaneMaskComposeSequences[] = {\n";
895 unsigned Idx = 0;
896 for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
897 OS << " ";
898 const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
899 for (const MaskRolPair &P : Sequence) {
900 printMask(OS&: OS << "{ ", Val: P.Mask);
901 OS << format(Fmt: ", %2u }, ", Vals: P.RotateLeft);
902 }
903 OS << "{ LaneBitmask::getNone(), 0 }";
904 if (s + 1 != se)
905 OS << ", ";
906 OS << " // Sequence " << Idx << "\n";
907 Idx += Sequence.size() + 1;
908 }
909 auto *IntType =
910 getMinimalTypeForRange(Range: *llvm::max_element(Range&: SubReg2SequenceIndexMap));
911 OS << " };\n"
912 " static const "
913 << IntType << " CompositeSequences[] = {\n";
914 for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
915 OS << " ";
916 OS << SubReg2SequenceIndexMap[i];
917 if (i + 1 != e)
918 OS << ",";
919 OS << " // to " << SubRegIndices[i].getName() << "\n";
920 }
921 OS << " };\n\n";
922
923 OS << "LaneBitmask " << ClassName
924 << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"
925 " const {\n"
926 " --IdxA; assert(IdxA < "
927 << SubRegIndices.size()
928 << " && \"Subregister index out of bounds\");\n"
929 " LaneBitmask Result;\n"
930 " for (const MaskRolOp *Ops =\n"
931 " &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
932 " Ops->Mask.any(); ++Ops) {\n"
933 " LaneBitmask::Type M = LaneMask.getAsInteger() & "
934 "Ops->Mask.getAsInteger();\n"
935 " if (unsigned S = Ops->RotateLeft)\n"
936 " Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - "
937 "S)));\n"
938 " else\n"
939 " Result |= LaneBitmask(M);\n"
940 " }\n"
941 " return Result;\n"
942 "}\n\n";
943
944 OS << "LaneBitmask " << ClassName
945 << "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "
946 " LaneBitmask LaneMask) const {\n"
947 " LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
948 " --IdxA; assert(IdxA < "
949 << SubRegIndices.size()
950 << " && \"Subregister index out of bounds\");\n"
951 " LaneBitmask Result;\n"
952 " for (const MaskRolOp *Ops =\n"
953 " &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
954 " Ops->Mask.any(); ++Ops) {\n"
955 " LaneBitmask::Type M = LaneMask.getAsInteger();\n"
956 " if (unsigned S = Ops->RotateLeft)\n"
957 " Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - "
958 "S)));\n"
959 " else\n"
960 " Result |= LaneBitmask(M);\n"
961 " }\n"
962 " return Result;\n"
963 "}\n\n";
964}
965
966//
967// runMCDesc - Print out MC register descriptions.
968//
969void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
970 StringRef FilenamePrefix) {
971 emitInclude(FilenamePrefix, IncludeFile: "MCDesc.inc", GuardMacro: "GET_REGINFO_MC_DESC", OS&: MainOS);
972
973 emitSourceFileHeader(Desc: "MC Register Information", OS);
974
975 const auto &Regs = RegBank.getRegisters();
976
977 auto &SubRegIndices = RegBank.getSubRegIndices();
978 // The lists of sub-registers and super-registers go in the same array. That
979 // allows us to share suffixes.
980 using RegVec = std::vector<const CodeGenRegister *>;
981
982 // Differentially encoded lists.
983 SequenceToOffsetTable<DiffVec> DiffSeqs;
984 SmallVector<DiffVec, 4> SubRegLists(Regs.size());
985 SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
986 SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
987
988 // List of lane masks accompanying register unit sequences.
989 SequenceToOffsetTable<MaskVec> LaneMaskSeqs(/*Terminator=*/std::nullopt);
990 SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
991
992 // Keep track of sub-register names as well. These are not differentially
993 // encoded.
994 using SubRegIdxVec = SmallVector<const CodeGenSubRegIndex *, 4>;
995 SequenceToOffsetTable<SubRegIdxVec, deref<std::less<>>> SubRegIdxSeqs(
996 /*Terminator=*/std::nullopt);
997 SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
998
999 SequenceToOffsetTable<std::string> RegStrings;
1000
1001 // Precompute register lists for the SequenceToOffsetTable.
1002 unsigned i = 0;
1003 for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
1004 const auto &Reg = *I;
1005 RegStrings.add(Seq: Reg.getName().str());
1006
1007 // Compute the ordered sub-register list.
1008 SetVector<const CodeGenRegister *> SR;
1009 SR.reserve(Size: Reg.getSubRegs().size());
1010 Reg.addSubRegsPreOrder(OSet&: SR, RegBank);
1011 diffEncode(V&: SubRegLists[i], InitVal: Reg.EnumValue, Begin: SR.begin(), End: SR.end());
1012 DiffSeqs.add(Seq: SubRegLists[i]);
1013
1014 // Compute the corresponding sub-register indexes.
1015 SubRegIdxVec &SRIs = SubRegIdxLists[i];
1016 SRIs.reserve(N: SR.size());
1017 for (const CodeGenRegister *S : SR)
1018 SRIs.push_back(Elt: Reg.getSubRegIndex(Reg: S));
1019 SubRegIdxSeqs.add(Seq: SRIs);
1020
1021 // Super-registers are already computed.
1022 const RegVec &SuperRegList = Reg.getSuperRegs();
1023 diffEncode(V&: SuperRegLists[i], InitVal: Reg.EnumValue, Begin: SuperRegList.begin(),
1024 End: SuperRegList.end());
1025 DiffSeqs.add(Seq: SuperRegLists[i]);
1026
1027 const SparseBitVector<> &RUs = Reg.getNativeRegUnits();
1028 DiffSeqs.add(Seq: diffEncode(V&: RegUnitLists[i], List: RUs));
1029
1030 const auto &RUMasks = Reg.getRegUnitLaneMasks();
1031 MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
1032 assert(LaneMaskVec.empty());
1033 llvm::append_range(C&: LaneMaskVec, R: RUMasks);
1034 LaneMaskSeqs.add(Seq: LaneMaskVec);
1035 }
1036
1037 // Compute the final layout of the sequence table.
1038 DiffSeqs.layout();
1039 LaneMaskSeqs.layout();
1040 SubRegIdxSeqs.layout();
1041
1042 NamespaceEmitter LlvmNS(OS, "llvm");
1043
1044 StringRef TargetName = Target.getName();
1045
1046 // Emit the shared table of differential lists.
1047 OS << "extern const int16_t " << TargetName << "RegDiffLists[] = {\n";
1048 DiffSeqs.emit(OS, Print: printDiff16);
1049 OS << "};\n\n";
1050
1051 // Emit the shared table of regunit lane mask sequences.
1052 OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
1053 LaneMaskSeqs.emit(OS, Print: printMask);
1054 OS << "};\n\n";
1055
1056 // Emit the table of sub-register indexes.
1057 OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
1058 SubRegIdxSeqs.emit(OS, Print: printSubRegIndex);
1059 OS << "};\n\n";
1060
1061 // Emit the string table.
1062 RegStrings.layout();
1063 RegStrings.emitStringLiteralDef(OS, Decl: Twine("extern const char ") + TargetName +
1064 "RegStrings[]");
1065
1066 OS << "extern const MCRegisterDesc " << TargetName
1067 << "RegDesc[] = { // Descriptors\n";
1068 OS << " { " << RegStrings.get(Seq: "") << ", 0, 0, 0, 0, 0, 0, 0 },\n";
1069
1070 // Emit the register descriptors now.
1071 i = 0;
1072 for (const auto &Reg : Regs) {
1073 unsigned FirstRU = Reg.getNativeRegUnits().find_first();
1074 unsigned Offset = DiffSeqs.get(Seq: RegUnitLists[i]);
1075 // The value must be kept in sync with MCRegisterInfo.h.
1076 constexpr unsigned RegUnitBits = 12;
1077 assert(isUInt<RegUnitBits>(FirstRU) && "Too many regunits");
1078 assert(isUInt<32 - RegUnitBits>(Offset) && "Offset is too big");
1079 OS << " { " << RegStrings.get(Seq: Reg.getName().str()) << ", "
1080 << DiffSeqs.get(Seq: SubRegLists[i]) << ", " << DiffSeqs.get(Seq: SuperRegLists[i])
1081 << ", " << SubRegIdxSeqs.get(Seq: SubRegIdxLists[i]) << ", "
1082 << (Offset << RegUnitBits | FirstRU) << ", "
1083 << LaneMaskSeqs.get(Seq: RegUnitLaneMasks[i]) << ", " << Reg.Constant << ", "
1084 << Reg.Artificial << " },\n";
1085 ++i;
1086 }
1087 OS << "};\n\n"; // End of register descriptors...
1088
1089 // Emit the table of register unit roots. Each regunit has one or two root
1090 // registers.
1091 OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
1092 for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {
1093 ArrayRef<const CodeGenRegister *> Roots = RegBank.getRegUnit(RUID: i).getRoots();
1094 assert(!Roots.empty() && "All regunits must have a root register.");
1095 assert(Roots.size() <= 2 && "More than two roots not supported yet.");
1096 OS << " { ";
1097 ListSeparator LS;
1098 for (const CodeGenRegister *R : Roots)
1099 OS << LS << getQualifiedName(R: R->TheDef);
1100 OS << " },\n";
1101 }
1102 OS << "};\n\n";
1103
1104 // Emit the table of register unit intervals.
1105 if (Target.getRegistersAreIntervals()) {
1106 OS << "extern const unsigned " << TargetName
1107 << "RegUnitIntervals[][2] = {\n";
1108 // Add entry for NoRegister
1109 OS << " { 0, 0 },\n";
1110 for (const CodeGenRegister &Reg : Regs) {
1111 const auto &Units = Reg.getNativeRegUnits();
1112 if (Units.empty()) {
1113 OS << " { 0, 0 },\n";
1114 } else {
1115 unsigned First = Units.find_first();
1116 unsigned Last = Units.find_last();
1117 OS << " { " << First << ", " << Last + 1 << " },\n";
1118 }
1119 }
1120 OS << "};\n\n";
1121 }
1122
1123 // Emit register class bit mask tables. The first bit mask emitted for a
1124 // register class, RC, is the set of sub-classes, including RC itself.
1125 //
1126 // If RC has super-registers, also create a list of subreg indices and bit
1127 // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
1128 // SuperRC, that satisfies:
1129 //
1130 // For all SuperReg in SuperRC: SuperReg:Idx in RC
1131 //
1132 // The 0-terminated list of subreg indices starts at:
1133 //
1134 // RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
1135 //
1136 // The corresponding bitmasks follow the sub-class mask in memory. Each
1137 // mask has RCMaskWords uint32_t entries.
1138 //
1139 // Every bit mask present in the list has at least one bit set.
1140
1141 const auto &RegisterClasses = RegBank.getRegClasses();
1142
1143 OS << "// Register classes...\n";
1144
1145 SequenceToOffsetTable<std::string> RegClassStrings;
1146 // Start indices for per-reg-class info in the respective arrays.
1147 struct StartIndex {
1148 unsigned RegIdx;
1149 unsigned BitSetIdx;
1150 unsigned SubClassMaskIdx;
1151 unsigned SuperClassIdx;
1152 // Not strictly an index, but to avoid recomputation: cache reg set range.
1153 unsigned MinRegVal;
1154 unsigned RegSetSize;
1155 };
1156 SmallVector<StartIndex> StartIndices;
1157 StartIndices.reserve(N: RegisterClasses.size() + 1);
1158 StartIndices.push_back(Elt: StartIndex{.RegIdx: 0, .BitSetIdx: 0, .SubClassMaskIdx: 0, .SuperClassIdx: 0, .MinRegVal: 0, .RegSetSize: 0});
1159
1160 // For compressing the sub-reg index lists.
1161 using IdxList = std::vector<const CodeGenSubRegIndex *>;
1162 SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
1163 SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
1164 BitVector MaskBV(RegisterClasses.size());
1165 for (const auto &RC : RegisterClasses) {
1166 ArrayRef<const Record *> Order = RC.getOrder();
1167 RegClassStrings.add(Seq: RC.getName());
1168
1169 unsigned MinRegVal = UINT_MAX, MaxRegVal = 0;
1170 for (const Record *Reg : Order) {
1171 MinRegVal = std::min(a: MinRegVal, b: RegBank.getReg(Reg)->EnumValue);
1172 MaxRegVal = std::max(a: MaxRegVal, b: RegBank.getReg(Reg)->EnumValue);
1173 }
1174
1175 unsigned SubClassMaskSize = (RC.getSubClasses().size() + 31) / 32;
1176 IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
1177 for (auto &Idx : SubRegIndices) {
1178 MaskBV.reset();
1179 RC.getSuperRegClasses(SubIdx: &Idx, Out&: MaskBV);
1180 if (MaskBV.none())
1181 continue;
1182 SRIList.push_back(x: &Idx);
1183 SubClassMaskSize += (MaskBV.size() + 31) / 32;
1184 }
1185 SuperRegIdxSeqs.add(Seq: SRIList);
1186
1187 auto &Last = StartIndices.back();
1188 Last.MinRegVal = Order.empty() ? 0 : MinRegVal;
1189 Last.RegSetSize = Order.empty() ? 0 : MaxRegVal - MinRegVal + 1;
1190 StartIndices.push_back(Elt: StartIndex{
1191 .RegIdx: Last.RegIdx + unsigned(Order.size()),
1192 // Round to next byte size.
1193 .BitSetIdx: Last.BitSetIdx +
1194 (Order.empty() ? 0 : ((MaxRegVal - MinRegVal) / 8) + 1),
1195 .SubClassMaskIdx: Last.SubClassMaskIdx + SubClassMaskSize,
1196 .SuperClassIdx: Last.SuperClassIdx + unsigned(RC.getSuperClasses().size()),
1197 .MinRegVal: 0, // MinRegVal for next RegClass.
1198 .RegSetSize: 0, // RegSetSize for next RegClass.
1199 });
1200 }
1201
1202 RegClassStrings.layout();
1203 RegClassStrings.emitStringLiteralDef(
1204 OS, Decl: Twine("extern const char ") + TargetName + "RegClassStrings[]");
1205
1206 SuperRegIdxSeqs.layout();
1207
1208 const auto &Totals = StartIndices.back();
1209 raw_string_ostream(MCRegisterClassStorageType)
1210 << "MCRegisterClassStorage<" << RegisterClasses.size() << ", "
1211 << Totals.RegIdx << ", " << Totals.BitSetIdx << ", "
1212 << Totals.SubClassMaskIdx << ", " << SuperRegIdxSeqs.size() << ", "
1213 << Totals.SuperClassIdx << ">";
1214 OS << "using " << TargetName
1215 << "RegisterClassStorage = " << MCRegisterClassStorageType << ";\n";
1216 OS << "inline constexpr " << MCRegisterClassStorageType << " " << TargetName
1217 << "MCRegisterClassStorage = {\n"
1218 << " {\n";
1219
1220 for (const auto &It : enumerate(First: RegisterClasses)) {
1221 const auto &RC = It.value();
1222 const auto &RCIndices = StartIndices[It.index()];
1223 uint32_t RegSize = 0;
1224 if (RC.RSI.isSimple())
1225 RegSize = RC.RSI.getSimple().RegSize;
1226
1227 // Helper to generate offsetof macro for relative offset in storage.
1228 auto GetOff = [&](std::string_view Member,
1229 unsigned DataIdx) -> std::string {
1230 return ("offsetof(" + Twine(TargetName) + "RegisterClassStorage, " +
1231 Member + "[" + Twine(DataIdx) + "]) - " + Twine(It.index()) +
1232 " * sizeof(MCRegisterClass)")
1233 .str();
1234 };
1235
1236 OS << " {\n " << GetOff("Regs", RCIndices.RegIdx) << ",\n "
1237 << GetOff("BitSets", RCIndices.BitSetIdx) << ",\n "
1238 << RegClassStrings.get(Seq: RC.getName()) << ",\n " << RegSize
1239 << ",\n " << RC.getOrder().size() << ",\n "
1240 << RCIndices.MinRegVal << ", /* MinRegVal */\n "
1241 << RCIndices.RegSetSize << ", /* RegSetSize */\n "
1242 << RC.getQualifiedIdName() << ",\n "
1243 << static_cast<unsigned>(RC.CopyCost) << ", /* CopyCost */\n "
1244 << (RC.Allocatable ? "true" : "false") << ", /* Allocatable */\n "
1245 << (RC.getBaseClassOrder() ? "true" : "false") << ",\n "
1246 << GetOff("SubClassMasks", RCIndices.SubClassMaskIdx) << ",\n "
1247 << GetOff("SuperRegIdxSeqs",
1248 SuperRegIdxSeqs.get(Seq: SuperRegIdxLists[RC.EnumValue]))
1249 << ",\n ";
1250 printMask(OS, Val: RC.LaneMask);
1251 OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
1252 << (RC.GlobalPriority ? "true" : "false") << ",\n "
1253 << format(Fmt: "0x%02x", Vals: RC.TSFlags) << ", /* TSFlags */\n "
1254 << (unsigned)RC.SpillStackID << ", /* SpillStackID */\n "
1255 << (RC.HasDisjunctSubRegs ? "true" : "false")
1256 << ", /* HasDisjunctSubRegs */\n "
1257 << (RC.CoveredBySubRegs ? "true" : "false")
1258 << ", /* CoveredBySubRegs */\n "
1259 << GetOff("SuperClasses", RCIndices.SuperClassIdx) << ",\n "
1260 << RC.getSuperClasses().size() << "\n },\n";
1261 }
1262
1263 OS << " },\n {\n";
1264
1265 // Emit registers.
1266 // TODO: these sequences often have overlaps which could be deduplicated.
1267 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1268 ArrayRef<const Record *> Order = RC.getOrder();
1269 if (Order.empty())
1270 continue;
1271 OS << " /* " << StartIndices[Idx].RegIdx << " */ ";
1272 for (const Record *Reg : Order)
1273 OS << getQualifiedName(R: Reg) << ", ";
1274 OS << "\n";
1275 }
1276
1277 OS << " },\n {\n";
1278
1279 // Emit register bit sets.
1280 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1281 ArrayRef<const Record *> Order = RC.getOrder();
1282 if (!Order.empty()) {
1283 OS << " /* " << StartIndices[Idx].BitSetIdx << " */ ";
1284 BitVectorEmitter BVE;
1285 for (const Record *Reg : Order)
1286 BVE.add(v: RegBank.getReg(Reg)->EnumValue - StartIndices[Idx].MinRegVal);
1287 BVE.print(OS);
1288 OS << "\n";
1289 }
1290 }
1291 OS << " },\n {\n";
1292
1293 // Emit subclass masks.
1294 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1295 OS << " // " << StartIndices[Idx].SubClassMaskIdx << " " << RC.getName()
1296 << "\n ";
1297 printBitVectorAsHex(OS, Bits: RC.getSubClasses(), Width: 32);
1298
1299 // Emit super-reg class masks for any relevant SubRegIndices that can
1300 // project into RC.
1301 for (auto &Idx : SubRegIndices) {
1302 MaskBV.reset();
1303 RC.getSuperRegClasses(SubIdx: &Idx, Out&: MaskBV);
1304 if (MaskBV.none())
1305 continue;
1306 OS << "\n ";
1307 printBitVectorAsHex(OS, Bits: MaskBV, Width: 32);
1308 OS << "// " << Idx.getName();
1309 }
1310 OS << "\n";
1311 }
1312 OS << " },\n {\n";
1313
1314 // Emit SubRegIdxSeqs.
1315 SuperRegIdxSeqs.emit(OS, Print: printSubRegIndex);
1316 OS << " },\n {\n";
1317
1318 // Emit super-class lists.
1319 for (const auto &[Idx, RC] : enumerate(First: RegisterClasses)) {
1320 ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
1321 OS << " /* " << StartIndices[Idx].SuperClassIdx << " " << RC.getName()
1322 << " */ ";
1323 for (const auto *Super : Supers)
1324 OS << Super->getQualifiedIdName() << ", ";
1325 OS << "\n";
1326 }
1327
1328 OS << " }\n};\n\n";
1329 OS << "const MCRegisterClass &get" << Target.getName()
1330 << "MCRegisterClass(unsigned RC) {\n"
1331 << " return " << Target.getName()
1332 << "MCRegisterClassStorage.Classes[RC];\n"
1333 << "}\n\n";
1334
1335 EmitRegMappingTables(OS, Regs, isCtor: false);
1336
1337 // Emit Reg encoding table
1338 OS << "extern const uint16_t " << TargetName;
1339 OS << "RegEncodingTable[] = {\n";
1340 // Add entry for NoRegister
1341 OS << " 0,\n";
1342 for (const auto &RE : Regs) {
1343 const Record *Reg = RE.TheDef;
1344 const BitsInit *BI = Reg->getValueAsBitsInit(FieldName: "HWEncoding");
1345 uint64_t Value = BI->convertKnownBitsToInt();
1346 OS << " " << Value << ",\n";
1347 }
1348 OS << "};\n"; // End of HW encoding table
1349
1350 // MCRegisterInfo initialization routine.
1351 OS << "static inline void Init" << TargetName
1352 << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
1353 << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "
1354 "{\n"
1355 << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
1356 << Regs.size() + 1 << ", RA, PC, " << TargetName
1357 << "MCRegisterClassStorage.Classes, " << RegisterClasses.size() << ", "
1358 << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", "
1359 << TargetName << "RegDiffLists, " << TargetName << "LaneMaskLists, "
1360 << TargetName << "RegStrings, " << TargetName << "RegClassStrings, "
1361 << TargetName << "SubRegIdxLists, " << (llvm::size(Range: SubRegIndices) + 1)
1362 << ",\n"
1363 << TargetName << "RegEncodingTable, "
1364 << (Target.getRegistersAreIntervals() ? TargetName + "RegUnitIntervals"
1365 : "nullptr")
1366 << ");\n\n";
1367
1368 EmitRegMapping(OS, Regs, isCtor: false);
1369
1370 OS << "}\n\n";
1371
1372 // Emit the register by HwMode (if present).
1373 ArrayRef<const Record *> RegisterByHwModeRecords =
1374 Records.getAllDerivedDefinitions(ClassName: "RegisterByHwMode");
1375 if (!RegisterByHwModeRecords.empty()) {
1376 OS << "// Registers by HwMode\n";
1377 NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace +
1378 "::RegisterByHwMode");
1379
1380 unsigned NumModes = Target.getHwModes().getNumModeIds();
1381 for (const Record *Rec : RegisterByHwModeRecords) {
1382 RegisterByHwMode RegByMode(Rec, RegBank);
1383 OS << "LLVM_READONLY MCRegister get" << Rec->getName()
1384 << "(unsigned HwMode) {\n";
1385 OS << indent(2) << "switch (HwMode) {\n";
1386 for (unsigned M = 0; M < NumModes; ++M) {
1387 if (RegByMode.hasMode(M)) {
1388 const CodeGenRegister *R = RegByMode.get(Mode: M);
1389 OS << indent(2) << "case " << M << ": return "
1390 << getQualifiedName(R: R->TheDef) << "; // "
1391 << Target.getHwModes().getModeName(Id: M, IncludeDefault: true) << "\n";
1392 }
1393 }
1394 OS << indent(2)
1395 << "default: llvm_unreachable(\"Unhandled HwMode for Register "
1396 << Rec->getName() << "\");\n"
1397 << indent(2) << "}\n"
1398 << "}\n";
1399 }
1400 }
1401}
1402
1403void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
1404 StringRef FilenamePrefix) {
1405 emitInclude(FilenamePrefix, IncludeFile: "Header.inc", GuardMacro: "GET_REGINFO_HEADER", OS&: MainOS);
1406
1407 emitSourceFileHeader(Desc: "Register Information Header Fragment", OS);
1408
1409 const std::string &TargetName = Target.getName().str();
1410 std::string ClassName = TargetName + "GenRegisterInfo";
1411
1412 OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";
1413
1414 NamespaceEmitter LlvmNS(OS, "llvm");
1415
1416 OS << "class " << TargetName << "FrameLowering;\n\n";
1417
1418 OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
1419 << "MCRegisterClassStorage;\n\n";
1420
1421 OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
1422 << " explicit " << ClassName
1423 << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
1424 << " unsigned PC = 0, unsigned HwMode = 0);\n";
1425 if (!RegBank.getSubRegIndices().empty()) {
1426 OS << " unsigned composeSubRegIndicesImpl"
1427 << "(unsigned, unsigned) const override;\n"
1428 << " unsigned reverseComposeSubRegIndicesImpl"
1429 << "(unsigned, unsigned) const override;\n"
1430 << " LaneBitmask composeSubRegIndexLaneMaskImpl"
1431 << "(unsigned, LaneBitmask) const override;\n"
1432 << " LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
1433 << "(unsigned, LaneBitmask) const override;\n"
1434 << " const TargetRegisterClass *getSubClassWithSubReg"
1435 << "(const TargetRegisterClass *, unsigned) const override;\n"
1436 << " const TargetRegisterClass *getSubRegisterClass"
1437 << "(const TargetRegisterClass *, unsigned) const override;\n";
1438 }
1439 OS << " const RegClassWeight &getRegClassWeight("
1440 << "const TargetRegisterClass *RC) const override;\n"
1441 << " unsigned getRegUnitWeight(MCRegUnit RegUnit) const override;\n"
1442 << " unsigned getNumRegPressureSets() const override;\n"
1443 << " const char *getRegPressureSetName(unsigned Idx) const override;\n"
1444 << " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
1445 "Idx) const override;\n"
1446 << " const TargetRegisterClass *getLargestRegClassForRegPressureSet("
1447 "unsigned Idx) const override;\n"
1448 << " const int *getRegClassPressureSets("
1449 << "const TargetRegisterClass *RC) const override;\n"
1450 << " const int *getRegUnitPressureSets("
1451 << "MCRegUnit RegUnit) const override;\n"
1452 << " ArrayRef<const char *> getRegMaskNames() const override;\n"
1453 << " ArrayRef<const uint32_t *> getRegMasks() const override;\n"
1454 << " bool isGeneralPurposeRegister(const MachineFunction &, "
1455 << "MCRegister) const override;\n"
1456 << " bool isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
1457 << " const override;\n"
1458 << " bool isFixedRegister(const MachineFunction &, "
1459 << "MCRegister) const override;\n"
1460 << " bool isArgumentRegister(const MachineFunction &, "
1461 << "MCRegister) const override;\n"
1462 << " bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"
1463 << " /// Devirtualized TargetFrameLowering.\n"
1464 << " static const " << TargetName << "FrameLowering *getFrameLowering(\n"
1465 << " const MachineFunction &MF);\n";
1466
1467 const auto &RegisterClasses = RegBank.getRegClasses();
1468 if (llvm::any_of(Range: RegisterClasses,
1469 P: [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
1470 OS << " ArrayRef<MCPhysReg> getRawAllocationOrder("
1471 "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
1472 "const override;\n";
1473 }
1474 if (llvm::any_of(Range: RegisterClasses,
1475 P: [](const auto &RC) { return RC.getBaseClassOrder(); })) {
1476 OS << " const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "
1477 "const override;\n";
1478 }
1479 if (!RegisterClasses.empty()) {
1480 OS << " const TargetRegisterClass *getMinimalPhysRegClass("
1481 "MCRegister Reg) const override;\n";
1482 }
1483
1484 OS << "};\n\n";
1485
1486 if (!RegisterClasses.empty()) {
1487 NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace);
1488 OS << "// Register classes\n";
1489
1490 for (const auto &RC : RegisterClasses) {
1491 // Output the extern for the instance.
1492 OS << "static constexpr const TargetRegisterClass &" << RC.getName()
1493 << "RegClass = " << TargetName << "MCRegisterClassStorage.Classes["
1494 << RC.EnumValue << "];\n";
1495 }
1496 }
1497}
1498
1499//
1500// runTargetDesc - Output the target register and register file descriptions.
1501//
1502void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
1503 StringRef FilenamePrefix) {
1504 emitInclude(FilenamePrefix, IncludeFile: "TargetDesc.inc", GuardMacro: "GET_REGINFO_TARGET_DESC",
1505 OS&: MainOS);
1506
1507 emitSourceFileHeader(Desc: "Target Register and Register Classes Information", OS);
1508
1509 NamespaceEmitter LlvmNS(OS, "llvm");
1510
1511 // Get access to MCRegisterClass data.
1512 OS << "extern const " << MCRegisterClassStorageType << " " << Target.getName()
1513 << "MCRegisterClassStorage;\n";
1514
1515 // Start out by emitting each of the register classes.
1516 const auto &RegisterClasses = RegBank.getRegClasses();
1517 const auto &SubRegIndices = RegBank.getSubRegIndices();
1518
1519 // Collect all registers belonging to any allocatable class.
1520 std::set<const Record *> AllocatableRegs;
1521
1522 // Collect allocatable registers.
1523 for (const auto &RC : RegisterClasses) {
1524 ArrayRef<const Record *> Order = RC.getOrder();
1525
1526 if (RC.Allocatable)
1527 AllocatableRegs.insert(first: Order.begin(), last: Order.end());
1528 }
1529
1530 const CodeGenHwModes &CGH = Target.getHwModes();
1531 unsigned NumModes = CGH.getNumModeIds();
1532 StringRef TargetName = Target.getName();
1533
1534 // Build a shared array of value types.
1535 SequenceToOffsetTable<std::vector<MVT>> VTSeqs(
1536 /*Terminator=*/MVT::Other);
1537 for (unsigned M = 0; M < NumModes; ++M) {
1538 for (const auto &RC : RegisterClasses) {
1539 std::vector<MVT> S;
1540 for (const ValueTypeByHwMode &VVT : RC.VTs)
1541 if (VVT.hasDefault() || VVT.hasMode(M))
1542 S.push_back(x: VVT.get(Mode: M));
1543 VTSeqs.add(Seq: S);
1544 }
1545 }
1546 VTSeqs.layout();
1547 OS << "\nstatic const MVT::SimpleValueType " << TargetName
1548 << "VTLists[] = {\n";
1549 VTSeqs.emit(OS, Print: printSimpleValueType);
1550 OS << "};\n";
1551
1552 // Emit SubRegIndex names, skipping 0.
1553 SequenceToOffsetTable<std::string> SubRegIndexStrings;
1554 for (const auto &Idx : SubRegIndices)
1555 SubRegIndexStrings.add(Seq: Idx.getName());
1556 SubRegIndexStrings.layout();
1557
1558 SubRegIndexStrings.emitStringLiteralDef(OS, Decl: Twine("static constexpr char ") +
1559 TargetName +
1560 "SubRegIndexStrings[]");
1561
1562 OS << "\nstatic constexpr uint32_t " << TargetName
1563 << "SubRegIndexNameOffsets[] = {\n";
1564 for (const auto &Idx : SubRegIndices)
1565 OS << " " << SubRegIndexStrings.get(Seq: Idx.getName()) << ", \n";
1566 if (SubRegIndices.empty())
1567 OS << " /* dummy */ 0\n";
1568 OS << "};\n\n";
1569
1570 // Emit the table of sub-register index sizes.
1571 OS << "static const TargetRegisterInfo::SubRegCoveredBits " << TargetName
1572 << "SubRegIdxRangeTable[] = {\n";
1573 for (unsigned M = 0; M < NumModes; ++M) {
1574 OS << " { " << (uint32_t)-1 << ", " << (uint32_t)-1 << " },\n";
1575 for (const auto &Idx : SubRegIndices) {
1576 const SubRegRange &Range = Idx.Range.get(Mode: M);
1577 OS << " { " << Range.Offset << ", " << Range.Size << " },\t// "
1578 << Idx.getName() << "\n";
1579 }
1580 }
1581 OS << "};\n\n";
1582
1583 // Emit SubRegIndex lane masks, including 0.
1584 OS << "\nstatic const LaneBitmask " << TargetName
1585 << "SubRegIndexLaneMaskTable[] = {\n "
1586 "LaneBitmask::getAll(),\n";
1587 for (const auto &Idx : SubRegIndices) {
1588 printMask(OS&: OS << " ", Val: Idx.LaneMask);
1589 OS << ", // " << Idx.getName() << '\n';
1590 }
1591 OS << " };\n\n";
1592
1593 OS << "\n";
1594
1595 // Now that all of the structs have been emitted, emit the instances.
1596 if (!RegisterClasses.empty()) {
1597 OS << "\nstatic const TargetRegisterInfo::RegClassInfo " << TargetName
1598 << "RegClassInfos[]" << " = {\n";
1599 for (unsigned M = 0; M < NumModes; ++M) {
1600 unsigned EV = 0;
1601 OS << " // Mode = " << M << " ("
1602 << CGH.getModeName(Id: M, /*IncludeDefault=*/true) << ")\n";
1603 for (const auto &RC : RegisterClasses) {
1604 assert(RC.EnumValue == EV && "Unexpected order of register classes");
1605 ++EV;
1606 (void)EV;
1607 const RegSizeInfo &RI = RC.RSI.get(Mode: M);
1608 OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", "
1609 << RI.SpillAlignment;
1610 std::vector<MVT> VTs;
1611 for (const ValueTypeByHwMode &VVT : RC.VTs)
1612 if (VVT.hasDefault() || VVT.hasMode(M))
1613 VTs.push_back(x: VVT.get(Mode: M));
1614 OS << ", /*" << TargetName << "VTLists+*/" << VTSeqs.get(Seq: VTs)
1615 << " }, // " << RC.getName() << '\n';
1616 }
1617 }
1618 OS << "};\n";
1619
1620 // Emit methods.
1621 for (const auto &RC : RegisterClasses) {
1622 if (!RC.AltOrderSelect.empty()) {
1623 OS << "\nstatic inline unsigned " << RC.getName()
1624 << "AltOrderSelect(const MachineFunction &MF, bool Rev) {"
1625 << RC.AltOrderSelect << "}\n\n"
1626 << "static ArrayRef<MCPhysReg> " << RC.getName()
1627 << "GetRawAllocationOrder(const TargetRegisterClass &RC, "
1628 << "const MachineFunction &MF, bool Rev) {\n";
1629 for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {
1630 ArrayRef<const Record *> Elems = RC.getOrder(No: oi);
1631 if (!Elems.empty()) {
1632 OS << " static const MCPhysReg AltOrder" << oi << "[] = {";
1633 for (unsigned elem = 0; elem != Elems.size(); ++elem)
1634 OS << (elem ? ", " : " ") << getQualifiedName(R: Elems[elem]);
1635 OS << " };\n";
1636 }
1637 }
1638 OS << " const ArrayRef<MCPhysReg> Order[] = {\n"
1639 << " RC.getRegisters(";
1640 for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
1641 if (RC.getOrder(No: oi).empty())
1642 OS << "),\n ArrayRef<MCPhysReg>(";
1643 else
1644 OS << "),\n ArrayRef(AltOrder" << oi;
1645 OS << ")\n };\n const unsigned Select = " << RC.getName()
1646 << "AltOrderSelect(MF, Rev);\n assert(Select < "
1647 << RC.getNumOrders() << ");\n return Order[Select];\n}\n";
1648 }
1649 }
1650 }
1651
1652 // Emit extra information about registers.
1653 const auto &Regs = RegBank.getRegisters();
1654 unsigned NumRegCosts = 1;
1655 for (const auto &Reg : Regs)
1656 NumRegCosts = std::max(a: (size_t)NumRegCosts, b: Reg.CostPerUse.size());
1657
1658 std::vector<unsigned> AllRegCostPerUse;
1659 llvm::BitVector InAllocClass(Regs.size() + 1, false);
1660 AllRegCostPerUse.insert(position: AllRegCostPerUse.end(), n: NumRegCosts, x: 0);
1661
1662 // Populate the vector RegCosts with the CostPerUse list of the registers
1663 // in the order they are read. Have at most NumRegCosts entries for
1664 // each register. Fill with zero for values which are not explicitly given.
1665 for (const auto &Reg : Regs) {
1666 auto Costs = Reg.CostPerUse;
1667 llvm::append_range(C&: AllRegCostPerUse, R&: Costs);
1668 if (NumRegCosts > Costs.size())
1669 AllRegCostPerUse.insert(position: AllRegCostPerUse.end(),
1670 n: NumRegCosts - Costs.size(), x: 0);
1671
1672 if (AllocatableRegs.count(x: Reg.TheDef))
1673 InAllocClass.set(Reg.EnumValue);
1674 }
1675
1676 // Emit the cost values as a 1D-array after grouping them by their indices,
1677 // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
1678 // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
1679 OS << "\nstatic const uint8_t " << TargetName << "CostPerUseTable[] = { \n";
1680 for (unsigned int I = 0; I < NumRegCosts; ++I) {
1681 for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
1682 OS << AllRegCostPerUse[J] << ", ";
1683 }
1684 OS << "};\n\n";
1685
1686 OS << "\nstatic const bool " << TargetName
1687 << "InAllocatableClassTable[] = { \n";
1688 for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
1689 OS << (InAllocClass[I] ? "true" : "false") << ", ";
1690 }
1691 OS << "};\n\n";
1692
1693 OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
1694 << "RegInfoDesc = { // Extra Descriptors\n";
1695 OS << TargetName << "CostPerUseTable, " << NumRegCosts << ", " << TargetName
1696 << "InAllocatableClassTable";
1697 OS << "};\n\n"; // End of register descriptors.
1698
1699 std::string ClassName = Target.getName().str() + "GenRegisterInfo";
1700
1701 size_t SubRegIndicesSize = llvm::size(Range: SubRegIndices);
1702
1703 if (!SubRegIndices.empty()) {
1704 emitComposeSubRegIndices(OS, ClassName);
1705 emitComposeSubRegIndexLaneMask(OS, ClassName);
1706 }
1707
1708 if (!SubRegIndices.empty()) {
1709 // Emit getSubClassWithSubReg.
1710 OS << "const TargetRegisterClass *" << ClassName
1711 << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
1712 << " const {\n";
1713 // Use the smallest type that can hold a regclass ID with room for a
1714 // sentinel.
1715 const size_t NumRegClasses = RegisterClasses.size();
1716 const char *RegClassTy = getMinimalTypeForRange(Range: NumRegClasses + 1);
1717 auto EmitTableLookup = [&]() {
1718 OS << formatv(Fmt: R"(
1719 };
1720 assert(RC && "Missing regclass");
1721 if (!Idx) return RC;
1722 --Idx;
1723 assert(Idx < {} && "Bad subreg");
1724 unsigned TV = Table[RC->getID()][Idx];
1725 return TV ? getRegClass(TV - 1) : nullptr;
1726})",
1727 Vals&: SubRegIndicesSize);
1728 };
1729
1730 OS << formatv(Fmt: " static constexpr {} Table[{}][{}] = {{\n", Vals&: RegClassTy,
1731 Vals: NumRegClasses, Vals&: SubRegIndicesSize);
1732 for (const auto &RC : RegisterClasses) {
1733 OS << " {\t// " << RC.getName() << "\n";
1734 for (auto &Idx : SubRegIndices) {
1735 if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(SubIdx: &Idx))
1736 OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
1737 << " -> " << SRC->getName() << "\n";
1738 else
1739 OS << " 0,\t// " << Idx.getName() << "\n";
1740 }
1741 OS << " },\n";
1742 }
1743 EmitTableLookup();
1744
1745 // Emit getSubRegisterClass.
1746 OS << "const TargetRegisterClass *" << ClassName
1747 << "::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx)"
1748 << " const {\n";
1749
1750 OS << formatv(Fmt: " static constexpr {} Table[{}][{}] = {{\n", Vals&: RegClassTy,
1751 Vals: NumRegClasses, Vals&: SubRegIndicesSize);
1752 for (const auto &RC : RegisterClasses) {
1753 OS << " {\t// " << RC.getName() << '\n';
1754 for (auto &Idx : SubRegIndices) {
1755 std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
1756 MatchingSubClass = RC.getMatchingSubClassWithSubRegs(RegBank, SubIdx: &Idx);
1757
1758 unsigned EnumValue = 0;
1759 if (MatchingSubClass) {
1760 CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1761 EnumValue = SubRegClass->EnumValue + 1;
1762 }
1763
1764 OS << " " << EnumValue << ",\t// " << RC.getName() << ':'
1765 << Idx.getName();
1766
1767 if (MatchingSubClass) {
1768 CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
1769 OS << " -> " << SubRegClass->getName();
1770 }
1771
1772 OS << '\n';
1773 }
1774
1775 OS << " },\n";
1776 }
1777 EmitTableLookup();
1778 }
1779
1780 EmitRegUnitPressure(OS, ClassName);
1781
1782 if (llvm::any_of(Range: RegisterClasses,
1783 P: [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
1784 OS << "ArrayRef<MCPhysReg> " << ClassName
1785 << "::getRawAllocationOrder("
1786 "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
1787 "const {\n";
1788 OS << " switch (RC.getID()) {\n";
1789 for (const auto &RC : RegisterClasses) {
1790 if (RC.AltOrderSelect.empty())
1791 continue;
1792 OS << " case " << RC.getQualifiedIdName() << ":\n"
1793 << " return " << RC.getName()
1794 << "GetRawAllocationOrder(RC, MF, Rev);\n";
1795 ;
1796 }
1797 OS << " }\n";
1798 OS << " return RC.getRegisters();\n";
1799 OS << "}\n\n";
1800 }
1801
1802 // Emit register base class mapper
1803 if (!RegisterClasses.empty()) {
1804 // Collect base classes
1805 SmallVector<const CodeGenRegisterClass *> BaseClasses;
1806 for (const auto &RC : RegisterClasses) {
1807 if (RC.getBaseClassOrder())
1808 BaseClasses.push_back(Elt: &RC);
1809 }
1810 if (!BaseClasses.empty()) {
1811 assert(BaseClasses.size() < UINT16_MAX &&
1812 "Too many base register classes");
1813
1814 // Apply order
1815 struct BaseClassOrdering {
1816 bool operator()(const CodeGenRegisterClass *LHS,
1817 const CodeGenRegisterClass *RHS) const {
1818 return std::pair(*LHS->getBaseClassOrder(), LHS->EnumValue) <
1819 std::pair(*RHS->getBaseClassOrder(), RHS->EnumValue);
1820 }
1821 };
1822 llvm::stable_sort(Range&: BaseClasses, C: BaseClassOrdering());
1823
1824 OS << "\n// Register to base register class mapping\n\n";
1825 OS << "\n";
1826 OS << "const TargetRegisterClass *" << ClassName
1827 << "::getPhysRegBaseClass(MCRegister Reg)"
1828 << " const {\n";
1829 OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
1830 OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
1831 OS << " InvalidRegClassID, // NoRegister\n";
1832 for (const CodeGenRegister &Reg : Regs) {
1833 const CodeGenRegisterClass *BaseRC = nullptr;
1834 for (const CodeGenRegisterClass *RC : BaseClasses) {
1835 if (RC->contains(&Reg)) {
1836 BaseRC = RC;
1837 break;
1838 }
1839 }
1840
1841 OS << " "
1842 << (BaseRC ? BaseRC->getQualifiedIdName() : "InvalidRegClassID")
1843 << ", // " << Reg.getName() << "\n";
1844 }
1845 OS << " };\n\n"
1846 " assert(Reg < ArrayRef(Mapping).size());\n"
1847 " unsigned RCID = Mapping[Reg.id()];\n"
1848 " if (RCID == InvalidRegClassID)\n"
1849 " return nullptr;\n"
1850 " return &"
1851 << TargetName
1852 << "MCRegisterClassStorage.Classes[RCID];\n"
1853 "}\n";
1854 }
1855 }
1856
1857 if (!RegisterClasses.empty()) {
1858 assert(RegisterClasses.size() < UINT16_MAX &&
1859 "Too many minimal register classes");
1860
1861 OS << "\n// Register to minimal register class mapping\n\n";
1862 OS << "const TargetRegisterClass *" << ClassName
1863 << "::getMinimalPhysRegClass(MCRegister Reg)" << " const {\n";
1864 OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
1865 OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
1866 OS << " InvalidRegClassID, // NoRegister\n";
1867 for (const CodeGenRegister &Reg : Regs) {
1868 const CodeGenRegisterClass *MinimalRC = nullptr;
1869 for (const auto &RC : RegisterClasses) {
1870 if (RC.contains(&Reg) && (!MinimalRC || MinimalRC->hasSubClass(RC: &RC)))
1871 MinimalRC = &RC;
1872 }
1873
1874 OS << " "
1875 << (MinimalRC ? MinimalRC->getQualifiedIdName() : "InvalidRegClassID")
1876 << ", // " << Reg.getName() << "\n";
1877 }
1878 OS << " };\n\n"
1879 " assert(Reg < ArrayRef(Mapping).size());\n"
1880 " unsigned RCID = Mapping[Reg.id()];\n"
1881 " if (RCID == InvalidRegClassID)\n"
1882 " return nullptr;\n"
1883 " return &"
1884 << TargetName
1885 << "MCRegisterClassStorage.Classes[RCID];\n"
1886 "}\n";
1887 }
1888
1889 // Emit the constructor of the class...
1890 OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
1891 OS << "extern const int16_t " << TargetName << "RegDiffLists[];\n";
1892 OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";
1893 OS << "extern const char " << TargetName << "RegStrings[];\n";
1894 OS << "extern const char " << TargetName << "RegClassStrings[];\n";
1895 OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
1896 OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
1897 OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
1898 if (Target.getRegistersAreIntervals())
1899 OS << "extern const unsigned " << TargetName << "RegUnitIntervals[][2];\n";
1900
1901 EmitRegMappingTables(OS, Regs, isCtor: true);
1902
1903 OS << formatv(Fmt: R"(
1904{0}::
1905{0}(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
1906 unsigned PC, unsigned HwMode)
1907 : TargetRegisterInfo(&{1}RegInfoDesc,
1908 {1}SubRegIndexStrings, {1}SubRegIndexNameOffsets,
1909 {1}SubRegIdxRangeTable, {1}SubRegIndexLaneMaskTable,
1910
1911 )",
1912 Vals&: ClassName, Vals&: TargetName);
1913 printMask(OS, Val: RegBank.CoveringLanes);
1914 OS << formatv(Fmt: R"(, {0}RegClassInfos, {0}VTLists, HwMode) {{
1915 InitMCRegisterInfo({0}RegDesc, {1}, RA, PC,
1916 &get{0}MCRegisterClass(0), {2}, {0}RegUnitRoots, {3}, {0}RegDiffLists,
1917 {0}LaneMaskLists, {0}RegStrings, {0}RegClassStrings, {0}SubRegIdxLists, {4},
1918 {0}RegEncodingTable, {5});
1919
1920)",
1921 Vals&: TargetName, Vals: Regs.size() + 1, Vals: RegisterClasses.size(),
1922 Vals: RegBank.getNumNativeRegUnits(), Vals: SubRegIndicesSize + 1,
1923 Vals: Target.getRegistersAreIntervals()
1924 ? TargetName + "RegUnitIntervals"
1925 : Twine("nullptr"));
1926 EmitRegMapping(OS, Regs, isCtor: true);
1927
1928 OS << "}\n\n";
1929
1930 // Emit CalleeSavedRegs information.
1931 ArrayRef<const Record *> CSRSets =
1932 Records.getAllDerivedDefinitions(ClassName: "CalleeSavedRegs");
1933 for (const Record *CSRSet : CSRSets) {
1934 const SetTheory::RecVec *Regs = RegBank.getSets().expand(Set: CSRSet);
1935 assert(Regs && "Cannot expand CalleeSavedRegs instance");
1936
1937 // Emit the *_SaveList list of callee-saved registers.
1938 OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { ";
1939 for (const Record *Reg : *Regs)
1940 OS << getQualifiedName(R: Reg) << ", ";
1941 OS << "0 };\n";
1942
1943 // Emit the *_RegMask bit mask of call-preserved registers.
1944 BitVector Covered = RegBank.computeCoveredRegisters(Regs: *Regs);
1945
1946 // Check for an optional OtherPreserved set.
1947 // Add those registers to RegMask, but not to SaveList.
1948 if (const DagInit *OPDag =
1949 dyn_cast<DagInit>(Val: CSRSet->getValueInit(FieldName: "OtherPreserved"))) {
1950 SetTheory::RecSet OPSet;
1951 RegBank.getSets().evaluate(Expr: OPDag, Elts&: OPSet, Loc: CSRSet->getLoc());
1952 Covered |= RegBank.computeCoveredRegisters(Regs: OPSet.getArrayRef());
1953 }
1954
1955 // Add all constant physical registers to the preserved mask:
1956 SetTheory::RecSet ConstantSet;
1957 for (const auto &Reg : RegBank.getRegisters()) {
1958 if (Reg.Constant)
1959 ConstantSet.insert(X: Reg.TheDef);
1960 }
1961 Covered |= RegBank.computeCoveredRegisters(Regs: ConstantSet.getArrayRef());
1962
1963 OS << "static const uint32_t " << CSRSet->getName() << "_RegMask[] = { ";
1964 printBitVectorAsHex(OS, Bits: Covered, Width: 32);
1965 OS << "};\n";
1966 }
1967 OS << "\n\n";
1968
1969 OS << "ArrayRef<const uint32_t *> " << ClassName
1970 << "::getRegMasks() const {\n";
1971 if (!CSRSets.empty()) {
1972 OS << " static const uint32_t *const Masks[] = {\n";
1973 for (const Record *CSRSet : CSRSets)
1974 OS << " " << CSRSet->getName() << "_RegMask,\n";
1975 OS << " };\n";
1976 OS << " return ArrayRef(Masks);\n";
1977 } else {
1978 OS << " return {};\n";
1979 }
1980 OS << "}\n\n";
1981
1982 const std::list<CodeGenRegisterCategory> &RegCategories =
1983 RegBank.getRegCategories();
1984 OS << "bool " << ClassName << "::\n"
1985 << "isGeneralPurposeRegister(const MachineFunction &MF, "
1986 << "MCRegister PhysReg) const {\n"
1987 << " return\n";
1988 for (const CodeGenRegisterCategory &Category : RegCategories)
1989 if (Category.getName() == "GeneralPurposeRegisters") {
1990 for (const CodeGenRegisterClass *RC : Category.getClasses())
1991 OS << " " << RC->getQualifiedName()
1992 << "RegClass.contains(PhysReg) ||\n";
1993 break;
1994 }
1995 OS << " false;\n";
1996 OS << "}\n\n";
1997
1998 OS << "bool " << ClassName << "::\n"
1999 << "isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
2000 << " const {\n"
2001 << " return\n";
2002 for (const CodeGenRegisterCategory &Category : RegCategories)
2003 if (Category.getName() == "GeneralPurposeRegisters") {
2004 for (const CodeGenRegisterClass *RC : Category.getClasses())
2005 OS << " " << RC->getQualifiedName()
2006 << "RegClass.hasSubClassEq(RC) ||\n";
2007 break;
2008 }
2009 OS << " false;\n";
2010 OS << "}\n\n";
2011
2012 OS << "bool " << ClassName << "::\n"
2013 << "isFixedRegister(const MachineFunction &MF, "
2014 << "MCRegister PhysReg) const {\n"
2015 << " return\n";
2016 for (const CodeGenRegisterCategory &Category : RegCategories)
2017 if (Category.getName() == "FixedRegisters") {
2018 for (const CodeGenRegisterClass *RC : Category.getClasses())
2019 OS << " " << RC->getQualifiedName()
2020 << "RegClass.contains(PhysReg) ||\n";
2021 break;
2022 }
2023 OS << " false;\n";
2024 OS << "}\n\n";
2025
2026 OS << "bool " << ClassName << "::\n"
2027 << "isArgumentRegister(const MachineFunction &MF, "
2028 << "MCRegister PhysReg) const {\n"
2029 << " return\n";
2030 for (const CodeGenRegisterCategory &Category : RegCategories)
2031 if (Category.getName() == "ArgumentRegisters") {
2032 for (const CodeGenRegisterClass *RC : Category.getClasses())
2033 OS << " " << RC->getQualifiedName()
2034 << "RegClass.contains(PhysReg) ||\n";
2035 break;
2036 }
2037 OS << " false;\n";
2038 OS << "}\n\n";
2039
2040 OS << "bool " << ClassName << "::\n"
2041 << "isConstantPhysReg(MCRegister PhysReg) const {\n"
2042 << " return\n";
2043 for (const auto &Reg : Regs)
2044 if (Reg.Constant)
2045 OS << " PhysReg == " << getQualifiedName(R: Reg.TheDef) << " ||\n";
2046 OS << " false;\n";
2047 OS << "}\n\n";
2048
2049 OS << "ArrayRef<const char *> " << ClassName
2050 << "::getRegMaskNames() const {\n";
2051 if (!CSRSets.empty()) {
2052 OS << " static const char *Names[] = {\n";
2053 for (const Record *CSRSet : CSRSets)
2054 OS << " " << '"' << CSRSet->getName() << '"' << ",\n";
2055 OS << " };\n";
2056 OS << " return ArrayRef(Names);\n";
2057 } else {
2058 OS << " return {};\n";
2059 }
2060 OS << "}\n\n";
2061
2062 OS << "const " << TargetName << "FrameLowering *\n"
2063 << TargetName
2064 << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
2065 << " return static_cast<const " << TargetName << "FrameLowering *>(\n"
2066 << " MF.getSubtarget().getFrameLowering());\n"
2067 << "}\n\n";
2068}
2069
2070TableGenOutputFiles RegisterInfoEmitter::run(StringRef FilenamePrefix) {
2071 TGTimer &Timer = Records.getTimer();
2072 Timer.startTimer(Name: "Print enums");
2073 std::string Main;
2074 raw_string_ostream MainOS(Main);
2075 std::string Enums;
2076 raw_string_ostream EnumsOS(Enums);
2077 runEnums(OS&: EnumsOS, MainOS, FilenamePrefix);
2078
2079 Timer.startTimer(Name: "Print MC registers");
2080 std::string MCDesc;
2081 raw_string_ostream MCDescOS(MCDesc);
2082 runMCDesc(OS&: MCDescOS, MainOS, FilenamePrefix);
2083
2084 Timer.startTimer(Name: "Print header fragment");
2085 std::string Header;
2086 raw_string_ostream HeaderOS(Header);
2087 runTargetHeader(OS&: HeaderOS, MainOS, FilenamePrefix);
2088
2089 Timer.startTimer(Name: "Print target registers");
2090 std::string TargetDesc;
2091 raw_string_ostream TargetDescOS(TargetDesc);
2092 runTargetDesc(OS&: TargetDescOS, MainOS, FilenamePrefix);
2093
2094 if (RegisterInfoDebug)
2095 debugDump(OS&: errs());
2096
2097 // The suffixes should be in sync with the tablegen function in
2098 // llvm/cmake/modules/TableGen.cmake.
2099 return {.MainFile: std::move(Main),
2100 .AdditionalFiles: {{"Enums.inc", Enums},
2101 {"MCDesc.inc", MCDesc},
2102 {"Header.inc", Header},
2103 {"TargetDesc.inc", TargetDesc}}};
2104}
2105
2106template <typename InfoTy, typename FnTy>
2107Printable RegisterInfoEmitter::printByHwMode(const InfoByHwMode<InfoTy> &Info,
2108 FnTy Func) {
2109 return Printable([&](raw_ostream &OS) {
2110 if (Info.isSimple()) {
2111 OS << Func(Info.getSimple());
2112 return;
2113 }
2114
2115 const CodeGenHwModes &CGH = Target.getHwModes();
2116
2117 OS << "{";
2118 for (unsigned M = 0, E = CGH.getNumModeIds(); M != E; ++M)
2119 OS << ' ' << CGH.getModeName(Id: M, /*IncludeDefault=*/true) << ':'
2120 << Func(Info.get(M));
2121 OS << " }";
2122 });
2123}
2124
2125void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
2126 for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
2127 OS << "RegisterClass " << RC.getName() << ":\n";
2128 OS << "\tSpillSize: " << printByHwMode(Info: RC.RSI, Func: [](const RegSizeInfo &Info) {
2129 return Info.SpillSize;
2130 }) << '\n';
2131 OS << "\tSpillAlignment: "
2132 << printByHwMode(
2133 Info: RC.RSI,
2134 Func: [](const RegSizeInfo &Info) { return Info.SpillAlignment; })
2135 << '\n';
2136 OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
2137 OS << "\tLaneMask: " << PrintLaneMask(LaneMask: RC.LaneMask) << '\n';
2138 OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
2139 OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
2140 OS << "\tAllocatable: " << RC.Allocatable << '\n';
2141 OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';
2142 OS << "\tWeight: " << RC.getWeight(RegBank) << '\n';
2143 OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';
2144 OS << "\tRegs:";
2145 for (const CodeGenRegister *R : RC.getMembers()) {
2146 OS << " " << R->getName();
2147 }
2148 OS << '\n';
2149 OS << "\tSubClasses:";
2150 const BitVector &SubClasses = RC.getSubClasses();
2151 for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {
2152 if (!SubClasses.test(Idx: SRC.EnumValue))
2153 continue;
2154 OS << " " << SRC.getName();
2155 }
2156 OS << '\n';
2157 OS << "\tSuperClasses:";
2158 for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {
2159 OS << " " << SRC->getName();
2160 }
2161 OS << '\n';
2162 if (RC.Artificial)
2163 OS << "\tArtificial: 1\n";
2164 }
2165
2166 for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
2167 OS << "SubRegIndex " << SRI.getName() << ":\n";
2168 OS << "\tLaneMask: " << PrintLaneMask(LaneMask: SRI.LaneMask) << '\n';
2169 OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
2170 OS << "\tOffset: " << printByHwMode(Info: SRI.Range, Func: [](const SubRegRange &Info) {
2171 return Info.Offset;
2172 }) << '\n';
2173 OS << "\tSize: " << printByHwMode(Info: SRI.Range, Func: [](const SubRegRange &Info) {
2174 return Info.Size;
2175 }) << '\n';
2176 if (SRI.Artificial)
2177 OS << "\tArtificial: 1\n";
2178 }
2179
2180 for (const CodeGenRegister &R : RegBank.getRegisters()) {
2181 OS << "Register " << R.getName() << ":\n";
2182 OS << "\tCostPerUse: ";
2183 for (const auto &Cost : R.CostPerUse)
2184 OS << Cost << " ";
2185 OS << '\n';
2186 OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
2187 OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
2188 for (auto &[SubIdx, SubReg] : R.getSubRegs()) {
2189 OS << "\tSubReg " << SubIdx->getName() << " = " << SubReg->getName()
2190 << '\n';
2191 }
2192 for (unsigned U : R.getNativeRegUnits())
2193 OS << "\tRegUnit " << U << '\n';
2194 if (R.Artificial)
2195 OS << "\tArtificial: 1\n";
2196 }
2197}
2198
2199static TableGen::Emitter::MultiFileOptClass<RegisterInfoEmitter>
2200 X("gen-register-info", "Generate registers and register classes info");
2201