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