Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
96333 views
//===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This tablegen backend is responsible for emitting a description of a target9// register file for a code generator. It uses instances of the Register,10// RegisterAliases, and RegisterClass classes to gather this information.11//12//===----------------------------------------------------------------------===//1314#include "Basic/SequenceToOffsetTable.h"15#include "Common/CodeGenHwModes.h"16#include "Common/CodeGenRegisters.h"17#include "Common/CodeGenTarget.h"18#include "Common/InfoByHwMode.h"19#include "Common/Types.h"20#include "llvm/ADT/ArrayRef.h"21#include "llvm/ADT/BitVector.h"22#include "llvm/ADT/STLExtras.h"23#include "llvm/ADT/SetVector.h"24#include "llvm/ADT/SmallVector.h"25#include "llvm/ADT/SparseBitVector.h"26#include "llvm/ADT/Twine.h"27#include "llvm/CodeGenTypes/MachineValueType.h"28#include "llvm/Support/Casting.h"29#include "llvm/Support/CommandLine.h"30#include "llvm/Support/Format.h"31#include "llvm/Support/raw_ostream.h"32#include "llvm/TableGen/Error.h"33#include "llvm/TableGen/Record.h"34#include "llvm/TableGen/SetTheory.h"35#include "llvm/TableGen/TableGenBackend.h"36#include <algorithm>37#include <cassert>38#include <cstddef>39#include <cstdint>40#include <deque>41#include <iterator>42#include <set>43#include <string>44#include <vector>4546using namespace llvm;4748cl::OptionCategory RegisterInfoCat("Options for -gen-register-info");4950static cl::opt<bool>51RegisterInfoDebug("register-info-debug", cl::init(false),52cl::desc("Dump register information to help debugging"),53cl::cat(RegisterInfoCat));5455namespace {5657class RegisterInfoEmitter {58CodeGenTarget Target;59RecordKeeper &Records;6061public:62RegisterInfoEmitter(RecordKeeper &R) : Target(R), Records(R) {63CodeGenRegBank &RegBank = Target.getRegBank();64RegBank.computeDerivedInfo();65}6667// runEnums - Print out enum values for all of the registers.68void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);6970// runMCDesc - Print out MC register descriptions.71void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);7273// runTargetHeader - Emit a header fragment for the register info emitter.74void runTargetHeader(raw_ostream &o, CodeGenTarget &Target,75CodeGenRegBank &Bank);7677// runTargetDesc - Output the target register and register file descriptions.78void runTargetDesc(raw_ostream &o, CodeGenTarget &Target,79CodeGenRegBank &Bank);8081// run - Output the register file description.82void run(raw_ostream &o);8384void debugDump(raw_ostream &OS);8586private:87void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs,88bool isCtor);89void EmitRegMappingTables(raw_ostream &o,90const std::deque<CodeGenRegister> &Regs,91bool isCtor);92void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,93const std::string &ClassName);94void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,95const std::string &ClassName);96void emitComposeSubRegIndexLaneMask(raw_ostream &OS, CodeGenRegBank &RegBank,97const std::string &ClassName);98};99100} // end anonymous namespace101102// runEnums - Print out enum values for all of the registers.103void RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target,104CodeGenRegBank &Bank) {105const auto &Registers = Bank.getRegisters();106107// Register enums are stored as uint16_t in the tables. Make sure we'll fit.108assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");109110StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");111112emitSourceFileHeader("Target Register Enum Values", OS);113114OS << "\n#ifdef GET_REGINFO_ENUM\n";115OS << "#undef GET_REGINFO_ENUM\n\n";116117OS << "namespace llvm {\n\n";118119OS << "class MCRegisterClass;\n"120<< "extern const MCRegisterClass " << Target.getName()121<< "MCRegisterClasses[];\n\n";122123if (!Namespace.empty())124OS << "namespace " << Namespace << " {\n";125OS << "enum {\n NoRegister,\n";126127for (const auto &Reg : Registers)128OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";129assert(Registers.size() == Registers.back().EnumValue &&130"Register enum value mismatch!");131OS << " NUM_TARGET_REGS // " << Registers.size() + 1 << "\n";132OS << "};\n";133if (!Namespace.empty())134OS << "} // end namespace " << Namespace << "\n";135136const auto &RegisterClasses = Bank.getRegClasses();137if (!RegisterClasses.empty()) {138139// RegisterClass enums are stored as uint16_t in the tables.140assert(RegisterClasses.size() <= 0xffff &&141"Too many register classes to fit in tables");142143OS << "\n// Register classes\n\n";144if (!Namespace.empty())145OS << "namespace " << Namespace << " {\n";146OS << "enum {\n";147for (const auto &RC : RegisterClasses)148OS << " " << RC.getIdName() << " = " << RC.EnumValue << ",\n";149OS << "\n};\n";150if (!Namespace.empty())151OS << "} // end namespace " << Namespace << "\n\n";152}153154const std::vector<Record *> &RegAltNameIndices =155Target.getRegAltNameIndices();156// If the only definition is the default NoRegAltName, we don't need to157// emit anything.158if (RegAltNameIndices.size() > 1) {159OS << "\n// Register alternate name indices\n\n";160if (!Namespace.empty())161OS << "namespace " << Namespace << " {\n";162OS << "enum {\n";163for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)164OS << " " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";165OS << " NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";166OS << "};\n";167if (!Namespace.empty())168OS << "} // end namespace " << Namespace << "\n\n";169}170171auto &SubRegIndices = Bank.getSubRegIndices();172if (!SubRegIndices.empty()) {173OS << "\n// Subregister indices\n\n";174std::string Namespace = SubRegIndices.front().getNamespace();175if (!Namespace.empty())176OS << "namespace " << Namespace << " {\n";177OS << "enum : uint16_t {\n NoSubRegister,\n";178unsigned i = 0;179for (const auto &Idx : SubRegIndices)180OS << " " << Idx.getName() << ",\t// " << ++i << "\n";181OS << " NUM_TARGET_SUBREGS\n};\n";182if (!Namespace.empty())183OS << "} // end namespace " << Namespace << "\n\n";184}185186OS << "// Register pressure sets enum.\n";187if (!Namespace.empty())188OS << "namespace " << Namespace << " {\n";189OS << "enum RegisterPressureSets {\n";190unsigned NumSets = Bank.getNumRegPressureSets();191for (unsigned i = 0; i < NumSets; ++i) {192const RegUnitSet &RegUnits = Bank.getRegSetAt(i);193OS << " " << RegUnits.Name << " = " << i << ",\n";194}195OS << "};\n";196if (!Namespace.empty())197OS << "} // end namespace " << Namespace << '\n';198OS << '\n';199200OS << "} // end namespace llvm\n\n";201OS << "#endif // GET_REGINFO_ENUM\n\n";202}203204static void printInt(raw_ostream &OS, int Val) { OS << Val; }205206void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS,207const CodeGenRegBank &RegBank,208const std::string &ClassName) {209unsigned NumRCs = RegBank.getRegClasses().size();210unsigned NumSets = RegBank.getNumRegPressureSets();211212OS << "/// Get the weight in units of pressure for this register class.\n"213<< "const RegClassWeight &" << ClassName << "::\n"214<< "getRegClassWeight(const TargetRegisterClass *RC) const {\n"215<< " static const RegClassWeight RCWeightTable[] = {\n";216for (const auto &RC : RegBank.getRegClasses()) {217const CodeGenRegister::Vec &Regs = RC.getMembers();218OS << " {" << RC.getWeight(RegBank) << ", ";219if (Regs.empty() || RC.Artificial)220OS << '0';221else {222std::vector<unsigned> RegUnits;223RC.buildRegUnitSet(RegBank, RegUnits);224OS << RegBank.getRegUnitSetWeight(RegUnits);225}226OS << "}, \t// " << RC.getName() << "\n";227}228OS << " };\n"229<< " return RCWeightTable[RC->getID()];\n"230<< "}\n\n";231232// Reasonable targets (not ARMv7) have unit weight for all units, so don't233// bother generating a table.234bool RegUnitsHaveUnitWeight = true;235for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();236UnitIdx < UnitEnd; ++UnitIdx) {237if (RegBank.getRegUnit(UnitIdx).Weight > 1)238RegUnitsHaveUnitWeight = false;239}240OS << "/// Get the weight in units of pressure for this register unit.\n"241<< "unsigned " << ClassName << "::\n"242<< "getRegUnitWeight(unsigned RegUnit) const {\n"243<< " assert(RegUnit < " << RegBank.getNumNativeRegUnits()244<< " && \"invalid register unit\");\n";245if (!RegUnitsHaveUnitWeight) {246OS << " static const uint8_t RUWeightTable[] = {\n ";247for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();248UnitIdx < UnitEnd; ++UnitIdx) {249const RegUnit &RU = RegBank.getRegUnit(UnitIdx);250assert(RU.Weight < 256 && "RegUnit too heavy");251OS << RU.Weight << ", ";252}253OS << "};\n"254<< " return RUWeightTable[RegUnit];\n";255} else {256OS << " // All register units have unit weight.\n"257<< " return 1;\n";258}259OS << "}\n\n";260261OS << "\n"262<< "// Get the number of dimensions of register pressure.\n"263<< "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"264<< " return " << NumSets << ";\n}\n\n";265266OS << "// Get the name of this register unit pressure set.\n"267<< "const char *" << ClassName << "::\n"268<< "getRegPressureSetName(unsigned Idx) const {\n"269<< " static const char *PressureNameTable[] = {\n";270unsigned MaxRegUnitWeight = 0;271for (unsigned i = 0; i < NumSets; ++i) {272const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);273MaxRegUnitWeight = std::max(MaxRegUnitWeight, RegUnits.Weight);274OS << " \"" << RegUnits.Name << "\",\n";275}276OS << " };\n"277<< " return PressureNameTable[Idx];\n"278<< "}\n\n";279280OS << "// Get the register unit pressure limit for this dimension.\n"281<< "// This limit must be adjusted dynamically for reserved registers.\n"282<< "unsigned " << ClassName << "::\n"283<< "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const "284"{\n"285<< " static const " << getMinimalTypeForRange(MaxRegUnitWeight, 32)286<< " PressureLimitTable[] = {\n";287for (unsigned i = 0; i < NumSets; ++i) {288const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);289OS << " " << RegUnits.Weight << ", \t// " << i << ": " << RegUnits.Name290<< "\n";291}292OS << " };\n"293<< " return PressureLimitTable[Idx];\n"294<< "}\n\n";295296SequenceToOffsetTable<std::vector<int>> PSetsSeqs;297298// This table may be larger than NumRCs if some register units needed a list299// of unit sets that did not correspond to a register class.300unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();301std::vector<std::vector<int>> PSets(NumRCUnitSets);302303for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {304ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);305PSets[i].reserve(PSetIDs.size());306for (unsigned PSetID : PSetIDs) {307PSets[i].push_back(RegBank.getRegPressureSet(PSetID).Order);308}309llvm::sort(PSets[i]);310PSetsSeqs.add(PSets[i]);311}312313PSetsSeqs.layout();314315OS << "/// Table of pressure sets per register class or unit.\n"316<< "static const int RCSetsTable[] = {\n";317PSetsSeqs.emit(OS, printInt, "-1");318OS << "};\n\n";319320OS << "/// Get the dimensions of register pressure impacted by this "321<< "register class.\n"322<< "/// Returns a -1 terminated array of pressure set IDs\n"323<< "const int *" << ClassName << "::\n"324<< "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";325OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)326<< " RCSetStartTable[] = {\n ";327for (unsigned i = 0, e = NumRCs; i != e; ++i) {328OS << PSetsSeqs.get(PSets[i]) << ",";329}330OS << "};\n"331<< " return &RCSetsTable[RCSetStartTable[RC->getID()]];\n"332<< "}\n\n";333334OS << "/// Get the dimensions of register pressure impacted by this "335<< "register unit.\n"336<< "/// Returns a -1 terminated array of pressure set IDs\n"337<< "const int *" << ClassName << "::\n"338<< "getRegUnitPressureSets(unsigned RegUnit) const {\n"339<< " assert(RegUnit < " << RegBank.getNumNativeRegUnits()340<< " && \"invalid register unit\");\n";341OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)342<< " RUSetStartTable[] = {\n ";343for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();344UnitIdx < UnitEnd; ++UnitIdx) {345OS << PSetsSeqs.get(PSets[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx])346<< ",";347}348OS << "};\n"349<< " return &RCSetsTable[RUSetStartTable[RegUnit]];\n"350<< "}\n\n";351}352353using DwarfRegNumsMapPair = std::pair<Record *, std::vector<int64_t>>;354using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>;355356static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {357// Sort and unique to get a map-like vector. We want the last assignment to358// match previous behaviour.359llvm::stable_sort(DwarfRegNums, on_first<LessRecordRegister>());360// Warn about duplicate assignments.361const Record *LastSeenReg = nullptr;362for (const auto &X : DwarfRegNums) {363const auto &Reg = X.first;364// The only way LessRecordRegister can return equal is if they're the same365// string. Use simple equality instead.366if (LastSeenReg && Reg->getName() == LastSeenReg->getName())367PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +368getQualifiedName(Reg) +369"specified multiple times");370LastSeenReg = Reg;371}372auto Last = llvm::unique(DwarfRegNums, [](const DwarfRegNumsMapPair &A,373const DwarfRegNumsMapPair &B) {374return A.first->getName() == B.first->getName();375});376DwarfRegNums.erase(Last, DwarfRegNums.end());377}378379void RegisterInfoEmitter::EmitRegMappingTables(380raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {381// Collect all information about dwarf register numbers382DwarfRegNumsVecTy DwarfRegNums;383384// First, just pull all provided information to the map385unsigned maxLength = 0;386for (auto &RE : Regs) {387Record *Reg = RE.TheDef;388std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");389maxLength = std::max((size_t)maxLength, RegNums.size());390DwarfRegNums.emplace_back(Reg, std::move(RegNums));391}392finalizeDwarfRegNumsKeys(DwarfRegNums);393394if (!maxLength)395return;396397// Now we know maximal length of number list. Append -1's, where needed398for (auto &DwarfRegNum : DwarfRegNums)399for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)400DwarfRegNum.second.push_back(-1);401402StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");403404OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";405406// Emit reverse information about the dwarf register numbers.407for (unsigned j = 0; j < 2; ++j) {408for (unsigned I = 0, E = maxLength; I != E; ++I) {409OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;410OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");411OS << I << "Dwarf2L[]";412413if (!isCtor) {414OS << " = {\n";415416// Store the mapping sorted by the LLVM reg num so lookup can be done417// with a binary search.418std::map<uint64_t, Record *> Dwarf2LMap;419for (auto &DwarfRegNum : DwarfRegNums) {420int DwarfRegNo = DwarfRegNum.second[I];421if (DwarfRegNo < 0)422continue;423Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;424}425426for (auto &I : Dwarf2LMap)427OS << " { " << I.first << "U, " << getQualifiedName(I.second)428<< " },\n";429430OS << "};\n";431} else {432OS << ";\n";433}434435// We have to store the size in a const global, it's used in multiple436// places.437OS << "extern const unsigned " << Namespace438<< (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";439if (!isCtor)440OS << " = std::size(" << Namespace441<< (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";442else443OS << ";\n\n";444}445}446447for (auto &RE : Regs) {448Record *Reg = RE.TheDef;449const RecordVal *V = Reg->getValue("DwarfAlias");450if (!V || !V->getValue())451continue;452453DefInit *DI = cast<DefInit>(V->getValue());454Record *Alias = DI->getDef();455const auto &AliasIter = llvm::lower_bound(456DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {457return LessRecordRegister()(A.first, B);458});459assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&460"Expected Alias to be present in map");461const auto &RegIter = llvm::lower_bound(462DwarfRegNums, Reg, [](const DwarfRegNumsMapPair &A, const Record *B) {463return LessRecordRegister()(A.first, B);464});465assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&466"Expected Reg to be present in map");467RegIter->second = AliasIter->second;468}469470// Emit information about the dwarf register numbers.471for (unsigned j = 0; j < 2; ++j) {472for (unsigned i = 0, e = maxLength; i != e; ++i) {473OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;474OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");475OS << i << "L2Dwarf[]";476if (!isCtor) {477OS << " = {\n";478// Store the mapping sorted by the Dwarf reg num so lookup can be done479// with a binary search.480for (auto &DwarfRegNum : DwarfRegNums) {481int RegNo = DwarfRegNum.second[i];482if (RegNo == -1) // -1 is the default value, don't emit a mapping.483continue;484485OS << " { " << getQualifiedName(DwarfRegNum.first) << ", " << RegNo486<< "U },\n";487}488OS << "};\n";489} else {490OS << ";\n";491}492493// We have to store the size in a const global, it's used in multiple494// places.495OS << "extern const unsigned " << Namespace496<< (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";497if (!isCtor)498OS << " = std::size(" << Namespace499<< (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2Dwarf);\n\n";500else501OS << ";\n\n";502}503}504}505506void RegisterInfoEmitter::EmitRegMapping(507raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {508// Emit the initializer so the tables from EmitRegMappingTables get wired up509// to the MCRegisterInfo object.510unsigned maxLength = 0;511for (auto &RE : Regs) {512Record *Reg = RE.TheDef;513maxLength = std::max((size_t)maxLength,514Reg->getValueAsListOfInts("DwarfNumbers").size());515}516517if (!maxLength)518return;519520StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");521522// Emit reverse information about the dwarf register numbers.523for (unsigned j = 0; j < 2; ++j) {524OS << " switch (";525if (j == 0)526OS << "DwarfFlavour";527else528OS << "EHFlavour";529OS << ") {\n"530<< " default:\n"531<< " llvm_unreachable(\"Unknown DWARF flavour\");\n";532533for (unsigned i = 0, e = maxLength; i != e; ++i) {534OS << " case " << i << ":\n";535OS << " ";536if (!isCtor)537OS << "RI->";538std::string Tmp;539raw_string_ostream(Tmp)540<< Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i541<< "Dwarf2L";542OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";543if (j == 0)544OS << "false";545else546OS << "true";547OS << ");\n";548OS << " break;\n";549}550OS << " }\n";551}552553// Emit information about the dwarf register numbers.554for (unsigned j = 0; j < 2; ++j) {555OS << " switch (";556if (j == 0)557OS << "DwarfFlavour";558else559OS << "EHFlavour";560OS << ") {\n"561<< " default:\n"562<< " llvm_unreachable(\"Unknown DWARF flavour\");\n";563564for (unsigned i = 0, e = maxLength; i != e; ++i) {565OS << " case " << i << ":\n";566OS << " ";567if (!isCtor)568OS << "RI->";569std::string Tmp;570raw_string_ostream(Tmp)571<< Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i572<< "L2Dwarf";573OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";574if (j == 0)575OS << "false";576else577OS << "true";578OS << ");\n";579OS << " break;\n";580}581OS << " }\n";582}583}584585// Print a BitVector as a sequence of hex numbers using a little-endian mapping.586// Width is the number of bits per hex number.587static void printBitVectorAsHex(raw_ostream &OS, const BitVector &Bits,588unsigned Width) {589assert(Width <= 32 && "Width too large");590unsigned Digits = (Width + 3) / 4;591for (unsigned i = 0, e = Bits.size(); i < e; i += Width) {592unsigned Value = 0;593for (unsigned j = 0; j != Width && i + j != e; ++j)594Value |= Bits.test(i + j) << j;595OS << format("0x%0*x, ", Digits, Value);596}597}598599// Helper to emit a set of bits into a constant byte array.600class BitVectorEmitter {601BitVector Values;602603public:604void add(unsigned v) {605if (v >= Values.size())606Values.resize(((v / 8) + 1) * 8); // Round up to the next byte.607Values[v] = true;608}609610void print(raw_ostream &OS) { printBitVectorAsHex(OS, Values, 8); }611};612613static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) {614OS << getEnumName(VT);615}616617static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {618OS << Idx->EnumValue;619}620621// Differentially encoded register and regunit lists allow for better622// compression on regular register banks. The sequence is computed from the623// differential list as:624//625// out[0] = InitVal;626// out[n+1] = out[n] + diff[n]; // n = 0, 1, ...627//628// The initial value depends on the specific list. The list is terminated by a629// 0 differential which means we can't encode repeated elements.630631typedef SmallVector<int16_t, 4> DiffVec;632typedef SmallVector<LaneBitmask, 4> MaskVec;633634// Fills V with differentials between every two consecutive elements of List.635static DiffVec &diffEncode(DiffVec &V, SparseBitVector<> List) {636assert(V.empty() && "Clear DiffVec before diffEncode.");637SparseBitVector<>::iterator I = List.begin(), E = List.end();638unsigned Val = *I;639while (++I != E) {640unsigned Cur = *I;641V.push_back(Cur - Val);642Val = Cur;643}644return V;645}646647template <typename Iter>648static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {649assert(V.empty() && "Clear DiffVec before diffEncode.");650unsigned Val = InitVal;651for (Iter I = Begin; I != End; ++I) {652unsigned Cur = (*I)->EnumValue;653V.push_back(Cur - Val);654Val = Cur;655}656return V;657}658659static void printDiff16(raw_ostream &OS, int16_t Val) { OS << Val; }660661static void printMask(raw_ostream &OS, LaneBitmask Val) {662OS << "LaneBitmask(0x" << PrintLaneMask(Val) << ')';663}664665// Try to combine Idx's compose map into Vec if it is compatible.666// Return false if it's not possible.667static bool combine(const CodeGenSubRegIndex *Idx,668SmallVectorImpl<CodeGenSubRegIndex *> &Vec) {669const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();670for (const auto &I : Map) {671CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];672if (Entry && Entry != I.second)673return false;674}675676// All entries are compatible. Make it so.677for (const auto &I : Map) {678auto *&Entry = Vec[I.first->EnumValue - 1];679assert((!Entry || Entry == I.second) && "Expected EnumValue to be unique");680Entry = I.second;681}682return true;683}684685void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,686CodeGenRegBank &RegBank,687const std::string &ClName) {688const auto &SubRegIndices = RegBank.getSubRegIndices();689OS << "unsigned " << ClName690<< "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";691692// Many sub-register indexes are composition-compatible, meaning that693//694// compose(IdxA, IdxB) == compose(IdxA', IdxB)695//696// for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.697// The illegal entries can be use as wildcards to compress the table further.698699// Map each Sub-register index to a compatible table row.700SmallVector<unsigned, 4> RowMap;701SmallVector<SmallVector<CodeGenSubRegIndex *, 4>, 4> Rows;702703auto SubRegIndicesSize =704std::distance(SubRegIndices.begin(), SubRegIndices.end());705for (const auto &Idx : SubRegIndices) {706unsigned Found = ~0u;707for (unsigned r = 0, re = Rows.size(); r != re; ++r) {708if (combine(&Idx, Rows[r])) {709Found = r;710break;711}712}713if (Found == ~0u) {714Found = Rows.size();715Rows.resize(Found + 1);716Rows.back().resize(SubRegIndicesSize);717combine(&Idx, Rows.back());718}719RowMap.push_back(Found);720}721722// Output the row map if there is multiple rows.723if (Rows.size() > 1) {724OS << " static const " << getMinimalTypeForRange(Rows.size(), 32)725<< " RowMap[" << SubRegIndicesSize << "] = {\n ";726for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)727OS << RowMap[i] << ", ";728OS << "\n };\n";729}730731// Output the rows.732OS << " static const " << getMinimalTypeForRange(SubRegIndicesSize + 1, 32)733<< " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";734for (unsigned r = 0, re = Rows.size(); r != re; ++r) {735OS << " { ";736for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)737if (Rows[r][i])738OS << Rows[r][i]->getQualifiedName() << ", ";739else740OS << "0, ";741OS << "},\n";742}743OS << " };\n\n";744745OS << " --IdxA; assert(IdxA < " << SubRegIndicesSize << "); (void) IdxA;\n"746<< " --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";747if (Rows.size() > 1)748OS << " return Rows[RowMap[IdxA]][IdxB];\n";749else750OS << " return Rows[0][IdxB];\n";751OS << "}\n\n";752}753754void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(755raw_ostream &OS, CodeGenRegBank &RegBank, const std::string &ClName) {756// See the comments in computeSubRegLaneMasks() for our goal here.757const auto &SubRegIndices = RegBank.getSubRegIndices();758759// Create a list of Mask+Rotate operations, with equivalent entries merged.760SmallVector<unsigned, 4> SubReg2SequenceIndexMap;761SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;762for (const auto &Idx : SubRegIndices) {763const SmallVector<MaskRolPair, 1> &IdxSequence =764Idx.CompositionLaneMaskTransform;765766unsigned Found = ~0u;767unsigned SIdx = 0;768unsigned NextSIdx;769for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {770SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];771NextSIdx = SIdx + Sequence.size() + 1;772if (Sequence == IdxSequence) {773Found = SIdx;774break;775}776}777if (Found == ~0u) {778Sequences.push_back(IdxSequence);779Found = SIdx;780}781SubReg2SequenceIndexMap.push_back(Found);782}783784OS << " struct MaskRolOp {\n"785" LaneBitmask Mask;\n"786" uint8_t RotateLeft;\n"787" };\n"788" static const MaskRolOp LaneMaskComposeSequences[] = {\n";789unsigned Idx = 0;790for (size_t s = 0, se = Sequences.size(); s != se; ++s) {791OS << " ";792const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];793for (size_t p = 0, pe = Sequence.size(); p != pe; ++p) {794const MaskRolPair &P = Sequence[p];795printMask(OS << "{ ", P.Mask);796OS << format(", %2u }, ", P.RotateLeft);797}798OS << "{ LaneBitmask::getNone(), 0 }";799if (s + 1 != se)800OS << ", ";801OS << " // Sequence " << Idx << "\n";802Idx += Sequence.size() + 1;803}804auto *IntType =805getMinimalTypeForRange(*llvm::max_element(SubReg2SequenceIndexMap));806OS << " };\n"807" static const "808<< IntType << " CompositeSequences[] = {\n";809for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {810OS << " ";811OS << SubReg2SequenceIndexMap[i];812if (i + 1 != e)813OS << ",";814OS << " // to " << SubRegIndices[i].getName() << "\n";815}816OS << " };\n\n";817818OS << "LaneBitmask " << ClName819<< "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"820" const {\n"821" --IdxA; assert(IdxA < "822<< SubRegIndices.size()823<< " && \"Subregister index out of bounds\");\n"824" LaneBitmask Result;\n"825" for (const MaskRolOp *Ops =\n"826" &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"827" Ops->Mask.any(); ++Ops) {\n"828" LaneBitmask::Type M = LaneMask.getAsInteger() & "829"Ops->Mask.getAsInteger();\n"830" if (unsigned S = Ops->RotateLeft)\n"831" Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - "832"S)));\n"833" else\n"834" Result |= LaneBitmask(M);\n"835" }\n"836" return Result;\n"837"}\n\n";838839OS << "LaneBitmask " << ClName840<< "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "841" LaneBitmask LaneMask) const {\n"842" LaneMask &= getSubRegIndexLaneMask(IdxA);\n"843" --IdxA; assert(IdxA < "844<< SubRegIndices.size()845<< " && \"Subregister index out of bounds\");\n"846" LaneBitmask Result;\n"847" for (const MaskRolOp *Ops =\n"848" &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"849" Ops->Mask.any(); ++Ops) {\n"850" LaneBitmask::Type M = LaneMask.getAsInteger();\n"851" if (unsigned S = Ops->RotateLeft)\n"852" Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - "853"S)));\n"854" else\n"855" Result |= LaneBitmask(M);\n"856" }\n"857" return Result;\n"858"}\n\n";859}860861//862// runMCDesc - Print out MC register descriptions.863//864void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,865CodeGenRegBank &RegBank) {866emitSourceFileHeader("MC Register Information", OS);867868OS << "\n#ifdef GET_REGINFO_MC_DESC\n";869OS << "#undef GET_REGINFO_MC_DESC\n\n";870871const auto &Regs = RegBank.getRegisters();872873auto &SubRegIndices = RegBank.getSubRegIndices();874// The lists of sub-registers and super-registers go in the same array. That875// allows us to share suffixes.876typedef std::vector<const CodeGenRegister *> RegVec;877878// Differentially encoded lists.879SequenceToOffsetTable<DiffVec> DiffSeqs;880SmallVector<DiffVec, 4> SubRegLists(Regs.size());881SmallVector<DiffVec, 4> SuperRegLists(Regs.size());882SmallVector<DiffVec, 4> RegUnitLists(Regs.size());883884// List of lane masks accompanying register unit sequences.885SequenceToOffsetTable<MaskVec> LaneMaskSeqs;886SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());887888// Keep track of sub-register names as well. These are not differentially889// encoded.890typedef SmallVector<const CodeGenSubRegIndex *, 4> SubRegIdxVec;891SequenceToOffsetTable<SubRegIdxVec, deref<std::less<>>> SubRegIdxSeqs;892SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());893894SequenceToOffsetTable<std::string> RegStrings;895896// Precompute register lists for the SequenceToOffsetTable.897unsigned i = 0;898for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {899const auto &Reg = *I;900RegStrings.add(std::string(Reg.getName()));901902// Compute the ordered sub-register list.903SetVector<const CodeGenRegister *> SR;904Reg.addSubRegsPreOrder(SR, RegBank);905diffEncode(SubRegLists[i], Reg.EnumValue, SR.begin(), SR.end());906DiffSeqs.add(SubRegLists[i]);907908// Compute the corresponding sub-register indexes.909SubRegIdxVec &SRIs = SubRegIdxLists[i];910for (const CodeGenRegister *S : SR)911SRIs.push_back(Reg.getSubRegIndex(S));912SubRegIdxSeqs.add(SRIs);913914// Super-registers are already computed.915const RegVec &SuperRegList = Reg.getSuperRegs();916diffEncode(SuperRegLists[i], Reg.EnumValue, SuperRegList.begin(),917SuperRegList.end());918DiffSeqs.add(SuperRegLists[i]);919920const SparseBitVector<> &RUs = Reg.getNativeRegUnits();921DiffSeqs.add(diffEncode(RegUnitLists[i], RUs));922923const auto &RUMasks = Reg.getRegUnitLaneMasks();924MaskVec &LaneMaskVec = RegUnitLaneMasks[i];925assert(LaneMaskVec.empty());926llvm::append_range(LaneMaskVec, RUMasks);927LaneMaskSeqs.add(LaneMaskVec);928}929930// Compute the final layout of the sequence table.931DiffSeqs.layout();932LaneMaskSeqs.layout();933SubRegIdxSeqs.layout();934935OS << "namespace llvm {\n\n";936937const std::string &TargetName = std::string(Target.getName());938939// Emit the shared table of differential lists.940OS << "extern const int16_t " << TargetName << "RegDiffLists[] = {\n";941DiffSeqs.emit(OS, printDiff16);942OS << "};\n\n";943944// Emit the shared table of regunit lane mask sequences.945OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";946// TODO: Omit the terminator since it is never used. The length of this list947// is known implicitly from the corresponding reg unit list.948LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()");949OS << "};\n\n";950951// Emit the table of sub-register indexes.952OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";953SubRegIdxSeqs.emit(OS, printSubRegIndex);954OS << "};\n\n";955956// Emit the string table.957RegStrings.layout();958RegStrings.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +959"RegStrings[]");960961OS << "extern const MCRegisterDesc " << TargetName962<< "RegDesc[] = { // Descriptors\n";963OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0, 0 },\n";964965// Emit the register descriptors now.966i = 0;967for (const auto &Reg : Regs) {968unsigned FirstRU = Reg.getNativeRegUnits().find_first();969unsigned Offset = DiffSeqs.get(RegUnitLists[i]);970// The value must be kept in sync with MCRegisterInfo.h.971constexpr unsigned RegUnitBits = 12;972assert(isUInt<RegUnitBits>(FirstRU) && "Too many regunits");973assert(isUInt<32 - RegUnitBits>(Offset) && "Offset is too big");974OS << " { " << RegStrings.get(std::string(Reg.getName())) << ", "975<< DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])976<< ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "977<< (Offset << RegUnitBits | FirstRU) << ", "978<< LaneMaskSeqs.get(RegUnitLaneMasks[i]) << ", " << Reg.Constant979<< " },\n";980++i;981}982OS << "};\n\n"; // End of register descriptors...983984// Emit the table of register unit roots. Each regunit has one or two root985// registers.986OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";987for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {988ArrayRef<const CodeGenRegister *> Roots = RegBank.getRegUnit(i).getRoots();989assert(!Roots.empty() && "All regunits must have a root register.");990assert(Roots.size() <= 2 && "More than two roots not supported yet.");991OS << " { ";992ListSeparator LS;993for (const CodeGenRegister *R : Roots)994OS << LS << getQualifiedName(R->TheDef);995OS << " },\n";996}997OS << "};\n\n";998999const auto &RegisterClasses = RegBank.getRegClasses();10001001// Loop over all of the register classes... emitting each one.1002OS << "namespace { // Register classes...\n";10031004SequenceToOffsetTable<std::string> RegClassStrings;10051006// Emit the register enum value arrays for each RegisterClass1007for (const auto &RC : RegisterClasses) {1008ArrayRef<Record *> Order = RC.getOrder();10091010// Give the register class a legal C name if it's anonymous.1011const std::string &Name = RC.getName();10121013RegClassStrings.add(Name);10141015// Emit the register list now (unless it would be a zero-length array).1016if (!Order.empty()) {1017OS << " // " << Name << " Register Class...\n"1018<< " const MCPhysReg " << Name << "[] = {\n ";1019for (Record *Reg : Order) {1020OS << getQualifiedName(Reg) << ", ";1021}1022OS << "\n };\n\n";10231024OS << " // " << Name << " Bit set.\n"1025<< " const uint8_t " << Name << "Bits[] = {\n ";1026BitVectorEmitter BVE;1027for (Record *Reg : Order) {1028BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);1029}1030BVE.print(OS);1031OS << "\n };\n\n";1032}1033}1034OS << "} // end anonymous namespace\n\n";10351036RegClassStrings.layout();1037RegClassStrings.emitStringLiteralDef(1038OS, Twine("extern const char ") + TargetName + "RegClassStrings[]");10391040OS << "extern const MCRegisterClass " << TargetName1041<< "MCRegisterClasses[] = {\n";10421043for (const auto &RC : RegisterClasses) {1044ArrayRef<Record *> Order = RC.getOrder();1045std::string RCName = Order.empty() ? "nullptr" : RC.getName();1046std::string RCBitsName = Order.empty() ? "nullptr" : RC.getName() + "Bits";1047std::string RCBitsSize = Order.empty() ? "0" : "sizeof(" + RCBitsName + ")";1048assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");1049uint32_t RegSize = 0;1050if (RC.RSI.isSimple())1051RegSize = RC.RSI.getSimple().RegSize;1052OS << " { " << RCName << ", " << RCBitsName << ", "1053<< RegClassStrings.get(RC.getName()) << ", " << RC.getOrder().size()1054<< ", " << RCBitsSize << ", " << RC.getQualifiedIdName() << ", "1055<< RegSize << ", " << RC.CopyCost << ", "1056<< (RC.Allocatable ? "true" : "false") << ", "1057<< (RC.getBaseClassOrder() ? "true" : "false") << " },\n";1058}10591060OS << "};\n\n";10611062EmitRegMappingTables(OS, Regs, false);10631064// Emit Reg encoding table1065OS << "extern const uint16_t " << TargetName;1066OS << "RegEncodingTable[] = {\n";1067// Add entry for NoRegister1068OS << " 0,\n";1069for (const auto &RE : Regs) {1070Record *Reg = RE.TheDef;1071BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");1072uint64_t Value = 0;1073for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {1074if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))1075Value |= (uint64_t)B->getValue() << b;1076}1077OS << " " << Value << ",\n";1078}1079OS << "};\n"; // End of HW encoding table10801081// MCRegisterInfo initialization routine.1082OS << "static inline void Init" << TargetName1083<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "1084<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "1085"{\n"1086<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "1087<< Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "1088<< RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, "1089<< RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, "1090<< TargetName << "LaneMaskLists, " << TargetName << "RegStrings, "1091<< TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, "1092<< (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n"1093<< TargetName << "RegEncodingTable);\n\n";10941095EmitRegMapping(OS, Regs, false);10961097OS << "}\n\n";10981099OS << "} // end namespace llvm\n\n";1100OS << "#endif // GET_REGINFO_MC_DESC\n\n";1101}11021103void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS,1104CodeGenTarget &Target,1105CodeGenRegBank &RegBank) {1106emitSourceFileHeader("Register Information Header Fragment", OS);11071108OS << "\n#ifdef GET_REGINFO_HEADER\n";1109OS << "#undef GET_REGINFO_HEADER\n\n";11101111const std::string &TargetName = std::string(Target.getName());1112std::string ClassName = TargetName + "GenRegisterInfo";11131114OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";11151116OS << "namespace llvm {\n\n";11171118OS << "class " << TargetName << "FrameLowering;\n\n";11191120OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"1121<< " explicit " << ClassName1122<< "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"1123<< " unsigned PC = 0, unsigned HwMode = 0);\n";1124if (!RegBank.getSubRegIndices().empty()) {1125OS << " unsigned composeSubRegIndicesImpl"1126<< "(unsigned, unsigned) const override;\n"1127<< " LaneBitmask composeSubRegIndexLaneMaskImpl"1128<< "(unsigned, LaneBitmask) const override;\n"1129<< " LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"1130<< "(unsigned, LaneBitmask) const override;\n"1131<< " const TargetRegisterClass *getSubClassWithSubReg"1132<< "(const TargetRegisterClass *, unsigned) const override;\n"1133<< " const TargetRegisterClass *getSubRegisterClass"1134<< "(const TargetRegisterClass *, unsigned) const override;\n";1135}1136OS << " const RegClassWeight &getRegClassWeight("1137<< "const TargetRegisterClass *RC) const override;\n"1138<< " unsigned getRegUnitWeight(unsigned RegUnit) const override;\n"1139<< " unsigned getNumRegPressureSets() const override;\n"1140<< " const char *getRegPressureSetName(unsigned Idx) const override;\n"1141<< " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "1142"Idx) const override;\n"1143<< " const int *getRegClassPressureSets("1144<< "const TargetRegisterClass *RC) const override;\n"1145<< " const int *getRegUnitPressureSets("1146<< "unsigned RegUnit) const override;\n"1147<< " ArrayRef<const char *> getRegMaskNames() const override;\n"1148<< " ArrayRef<const uint32_t *> getRegMasks() const override;\n"1149<< " bool isGeneralPurposeRegister(const MachineFunction &, "1150<< "MCRegister) const override;\n"1151<< " bool isFixedRegister(const MachineFunction &, "1152<< "MCRegister) const override;\n"1153<< " bool isArgumentRegister(const MachineFunction &, "1154<< "MCRegister) const override;\n"1155<< " bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"1156<< " /// Devirtualized TargetFrameLowering.\n"1157<< " static const " << TargetName << "FrameLowering *getFrameLowering(\n"1158<< " const MachineFunction &MF);\n";11591160const auto &RegisterClasses = RegBank.getRegClasses();1161if (llvm::any_of(RegisterClasses,1162[](const auto &RC) { return RC.getBaseClassOrder(); })) {1163OS << " const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "1164"const override;\n";1165}11661167OS << "};\n\n";11681169if (!RegisterClasses.empty()) {1170OS << "namespace " << RegisterClasses.front().Namespace1171<< " { // Register classes\n";11721173for (const auto &RC : RegisterClasses) {1174const std::string &Name = RC.getName();11751176// Output the extern for the instance.1177OS << " extern const TargetRegisterClass " << Name << "RegClass;\n";1178}1179OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n\n";1180}1181OS << "} // end namespace llvm\n\n";1182OS << "#endif // GET_REGINFO_HEADER\n\n";1183}11841185//1186// runTargetDesc - Output the target register and register file descriptions.1187//1188void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,1189CodeGenRegBank &RegBank) {1190emitSourceFileHeader("Target Register and Register Classes Information", OS);11911192OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";1193OS << "#undef GET_REGINFO_TARGET_DESC\n\n";11941195OS << "namespace llvm {\n\n";11961197// Get access to MCRegisterClass data.1198OS << "extern const MCRegisterClass " << Target.getName()1199<< "MCRegisterClasses[];\n";12001201// Start out by emitting each of the register classes.1202const auto &RegisterClasses = RegBank.getRegClasses();1203const auto &SubRegIndices = RegBank.getSubRegIndices();12041205// Collect all registers belonging to any allocatable class.1206std::set<Record *> AllocatableRegs;12071208// Collect allocatable registers.1209for (const auto &RC : RegisterClasses) {1210ArrayRef<Record *> Order = RC.getOrder();12111212if (RC.Allocatable)1213AllocatableRegs.insert(Order.begin(), Order.end());1214}12151216const CodeGenHwModes &CGH = Target.getHwModes();1217unsigned NumModes = CGH.getNumModeIds();12181219// Build a shared array of value types.1220SequenceToOffsetTable<std::vector<MVT::SimpleValueType>> VTSeqs;1221for (unsigned M = 0; M < NumModes; ++M) {1222for (const auto &RC : RegisterClasses) {1223std::vector<MVT::SimpleValueType> S;1224for (const ValueTypeByHwMode &VVT : RC.VTs)1225if (VVT.hasDefault() || VVT.hasMode(M))1226S.push_back(VVT.get(M).SimpleTy);1227VTSeqs.add(S);1228}1229}1230VTSeqs.layout();1231OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";1232VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");1233OS << "};\n";12341235// Emit SubRegIndex names, skipping 0.1236OS << "\nstatic const char *SubRegIndexNameTable[] = { \"";12371238for (const auto &Idx : SubRegIndices) {1239OS << Idx.getName();1240OS << "\", \"";1241}1242OS << "\" };\n\n";12431244// Emit the table of sub-register index sizes.1245OS << "static const TargetRegisterInfo::SubRegCoveredBits "1246"SubRegIdxRangeTable[] = {\n";1247for (unsigned M = 0; M < NumModes; ++M) {1248OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";1249for (const auto &Idx : SubRegIndices) {1250const SubRegRange &Range = Idx.Range.get(M);1251OS << " { " << Range.Offset << ", " << Range.Size << " },\t// "1252<< Idx.getName() << "\n";1253}1254}1255OS << "};\n\n";12561257// Emit SubRegIndex lane masks, including 0.1258OS << "\nstatic const LaneBitmask SubRegIndexLaneMaskTable[] = {\n "1259"LaneBitmask::getAll(),\n";1260for (const auto &Idx : SubRegIndices) {1261printMask(OS << " ", Idx.LaneMask);1262OS << ", // " << Idx.getName() << '\n';1263}1264OS << " };\n\n";12651266OS << "\n";12671268// Now that all of the structs have been emitted, emit the instances.1269if (!RegisterClasses.empty()) {1270OS << "\nstatic const TargetRegisterInfo::RegClassInfo RegClassInfos[]"1271<< " = {\n";1272for (unsigned M = 0; M < NumModes; ++M) {1273unsigned EV = 0;1274OS << " // Mode = " << M << " (";1275if (M == 0)1276OS << "Default";1277else1278OS << CGH.getMode(M).Name;1279OS << ")\n";1280for (const auto &RC : RegisterClasses) {1281assert(RC.EnumValue == EV && "Unexpected order of register classes");1282++EV;1283(void)EV;1284const RegSizeInfo &RI = RC.RSI.get(M);1285OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", "1286<< RI.SpillAlignment;1287std::vector<MVT::SimpleValueType> VTs;1288for (const ValueTypeByHwMode &VVT : RC.VTs)1289if (VVT.hasDefault() || VVT.hasMode(M))1290VTs.push_back(VVT.get(M).SimpleTy);1291OS << ", /*VTLists+*/" << VTSeqs.get(VTs) << " }, // "1292<< RC.getName() << '\n';1293}1294}1295OS << "};\n";12961297OS << "\nstatic const TargetRegisterClass *const "1298<< "NullRegClasses[] = { nullptr };\n\n";12991300// Emit register class bit mask tables. The first bit mask emitted for a1301// register class, RC, is the set of sub-classes, including RC itself.1302//1303// If RC has super-registers, also create a list of subreg indices and bit1304// masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,1305// SuperRC, that satisfies:1306//1307// For all SuperReg in SuperRC: SuperReg:Idx in RC1308//1309// The 0-terminated list of subreg indices starts at:1310//1311// RC->getSuperRegIndices() = SuperRegIdxSeqs + ...1312//1313// The corresponding bitmasks follow the sub-class mask in memory. Each1314// mask has RCMaskWords uint32_t entries.1315//1316// Every bit mask present in the list has at least one bit set.13171318// Compress the sub-reg index lists.1319typedef std::vector<const CodeGenSubRegIndex *> IdxList;1320SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());1321SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;1322BitVector MaskBV(RegisterClasses.size());13231324for (const auto &RC : RegisterClasses) {1325OS << "static const uint32_t " << RC.getName()1326<< "SubClassMask[] = {\n ";1327printBitVectorAsHex(OS, RC.getSubClasses(), 32);13281329// Emit super-reg class masks for any relevant SubRegIndices that can1330// project into RC.1331IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];1332for (auto &Idx : SubRegIndices) {1333MaskBV.reset();1334RC.getSuperRegClasses(&Idx, MaskBV);1335if (MaskBV.none())1336continue;1337SRIList.push_back(&Idx);1338OS << "\n ";1339printBitVectorAsHex(OS, MaskBV, 32);1340OS << "// " << Idx.getName();1341}1342SuperRegIdxSeqs.add(SRIList);1343OS << "\n};\n\n";1344}13451346OS << "static const uint16_t SuperRegIdxSeqs[] = {\n";1347SuperRegIdxSeqs.layout();1348SuperRegIdxSeqs.emit(OS, printSubRegIndex);1349OS << "};\n\n";13501351// Emit NULL terminated super-class lists.1352for (const auto &RC : RegisterClasses) {1353ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();13541355// Skip classes without supers. We can reuse NullRegClasses.1356if (Supers.empty())1357continue;13581359OS << "static const TargetRegisterClass *const " << RC.getName()1360<< "Superclasses[] = {\n";1361for (const auto *Super : Supers)1362OS << " &" << Super->getQualifiedName() << "RegClass,\n";1363OS << " nullptr\n};\n\n";1364}13651366// Emit methods.1367for (const auto &RC : RegisterClasses) {1368if (!RC.AltOrderSelect.empty()) {1369OS << "\nstatic inline unsigned " << RC.getName()1370<< "AltOrderSelect(const MachineFunction &MF) {" << RC.AltOrderSelect1371<< "}\n\n"1372<< "static ArrayRef<MCPhysReg> " << RC.getName()1373<< "GetRawAllocationOrder(const MachineFunction &MF) {\n";1374for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {1375ArrayRef<Record *> Elems = RC.getOrder(oi);1376if (!Elems.empty()) {1377OS << " static const MCPhysReg AltOrder" << oi << "[] = {";1378for (unsigned elem = 0; elem != Elems.size(); ++elem)1379OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);1380OS << " };\n";1381}1382}1383OS << " const MCRegisterClass &MCR = " << Target.getName()1384<< "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"1385<< " const ArrayRef<MCPhysReg> Order[] = {\n"1386<< " ArrayRef(MCR.begin(), MCR.getNumRegs()";1387for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)1388if (RC.getOrder(oi).empty())1389OS << "),\n ArrayRef<MCPhysReg>(";1390else1391OS << "),\n ArrayRef(AltOrder" << oi;1392OS << ")\n };\n const unsigned Select = " << RC.getName()1393<< "AltOrderSelect(MF);\n assert(Select < " << RC.getNumOrders()1394<< ");\n return Order[Select];\n}\n";1395}1396}13971398// Now emit the actual value-initialized register class instances.1399OS << "\nnamespace " << RegisterClasses.front().Namespace1400<< " { // Register class instances\n";14011402for (const auto &RC : RegisterClasses) {1403OS << " extern const TargetRegisterClass " << RC.getName()1404<< "RegClass = {\n " << '&' << Target.getName()1405<< "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "1406<< RC.getName() << "SubClassMask,\n SuperRegIdxSeqs + "1407<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n ";1408printMask(OS, RC.LaneMask);1409OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "1410<< (RC.GlobalPriority ? "true" : "false") << ",\n "1411<< format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n "1412<< (RC.HasDisjunctSubRegs ? "true" : "false")1413<< ", /* HasDisjunctSubRegs */\n "1414<< (RC.CoveredBySubRegs ? "true" : "false")1415<< ", /* CoveredBySubRegs */\n ";1416if (RC.getSuperClasses().empty())1417OS << "NullRegClasses,\n ";1418else1419OS << RC.getName() << "Superclasses,\n ";1420if (RC.AltOrderSelect.empty())1421OS << "nullptr\n";1422else1423OS << RC.getName() << "GetRawAllocationOrder\n";1424OS << " };\n\n";1425}14261427OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n";1428}14291430OS << "\nnamespace {\n";1431OS << " const TargetRegisterClass *const RegisterClasses[] = {\n";1432for (const auto &RC : RegisterClasses)1433OS << " &" << RC.getQualifiedName() << "RegClass,\n";1434OS << " };\n";1435OS << "} // end anonymous namespace\n";14361437// Emit extra information about registers.1438const std::string &TargetName = std::string(Target.getName());1439const auto &Regs = RegBank.getRegisters();1440unsigned NumRegCosts = 1;1441for (const auto &Reg : Regs)1442NumRegCosts = std::max((size_t)NumRegCosts, Reg.CostPerUse.size());14431444std::vector<unsigned> AllRegCostPerUse;1445llvm::BitVector InAllocClass(Regs.size() + 1, false);1446AllRegCostPerUse.insert(AllRegCostPerUse.end(), NumRegCosts, 0);14471448// Populate the vector RegCosts with the CostPerUse list of the registers1449// in the order they are read. Have at most NumRegCosts entries for1450// each register. Fill with zero for values which are not explicitly given.1451for (const auto &Reg : Regs) {1452auto Costs = Reg.CostPerUse;1453AllRegCostPerUse.insert(AllRegCostPerUse.end(), Costs.begin(), Costs.end());1454if (NumRegCosts > Costs.size())1455AllRegCostPerUse.insert(AllRegCostPerUse.end(),1456NumRegCosts - Costs.size(), 0);14571458if (AllocatableRegs.count(Reg.TheDef))1459InAllocClass.set(Reg.EnumValue);1460}14611462// Emit the cost values as a 1D-array after grouping them by their indices,1463// i.e. the costs for all registers corresponds to index 0, 1, 2, etc.1464// Size of the emitted array should be NumRegCosts * (Regs.size() + 1).1465OS << "\nstatic const uint8_t "1466<< "CostPerUseTable[] = { \n";1467for (unsigned int I = 0; I < NumRegCosts; ++I) {1468for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)1469OS << AllRegCostPerUse[J] << ", ";1470}1471OS << "};\n\n";14721473OS << "\nstatic const bool "1474<< "InAllocatableClassTable[] = { \n";1475for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {1476OS << (InAllocClass[I] ? "true" : "false") << ", ";1477}1478OS << "};\n\n";14791480OS << "\nstatic const TargetRegisterInfoDesc " << TargetName1481<< "RegInfoDesc = { // Extra Descriptors\n";1482OS << "CostPerUseTable, " << NumRegCosts << ", "1483<< "InAllocatableClassTable";1484OS << "};\n\n"; // End of register descriptors...14851486std::string ClassName = Target.getName().str() + "GenRegisterInfo";14871488auto SubRegIndicesSize =1489std::distance(SubRegIndices.begin(), SubRegIndices.end());14901491if (!SubRegIndices.empty()) {1492emitComposeSubRegIndices(OS, RegBank, ClassName);1493emitComposeSubRegIndexLaneMask(OS, RegBank, ClassName);1494}14951496if (!SubRegIndices.empty()) {1497// Emit getSubClassWithSubReg.1498OS << "const TargetRegisterClass *" << ClassName1499<< "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"1500<< " const {\n";1501// Use the smallest type that can hold a regclass ID with room for a1502// sentinel.1503if (RegisterClasses.size() <= UINT8_MAX)1504OS << " static const uint8_t Table[";1505else if (RegisterClasses.size() <= UINT16_MAX)1506OS << " static const uint16_t Table[";1507else1508PrintFatalError("Too many register classes.");1509OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";1510for (const auto &RC : RegisterClasses) {1511OS << " {\t// " << RC.getName() << "\n";1512for (auto &Idx : SubRegIndices) {1513if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))1514OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()1515<< " -> " << SRC->getName() << "\n";1516else1517OS << " 0,\t// " << Idx.getName() << "\n";1518}1519OS << " },\n";1520}1521OS << " };\n assert(RC && \"Missing regclass\");\n"1522<< " if (!Idx) return RC;\n --Idx;\n"1523<< " assert(Idx < " << SubRegIndicesSize << " && \"Bad subreg\");\n"1524<< " unsigned TV = Table[RC->getID()][Idx];\n"1525<< " return TV ? getRegClass(TV - 1) : nullptr;\n}\n\n";15261527// Emit getSubRegisterClass1528OS << "const TargetRegisterClass *" << ClassName1529<< "::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx)"1530<< " const {\n";15311532// Use the smallest type that can hold a regclass ID with room for a1533// sentinel.1534if (RegisterClasses.size() <= UINT8_MAX)1535OS << " static const uint8_t Table[";1536else if (RegisterClasses.size() <= UINT16_MAX)1537OS << " static const uint16_t Table[";1538else1539PrintFatalError("Too many register classes.");15401541OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";15421543for (const auto &RC : RegisterClasses) {1544OS << " {\t// " << RC.getName() << '\n';1545for (auto &Idx : SubRegIndices) {1546std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>1547MatchingSubClass = RC.getMatchingSubClassWithSubRegs(RegBank, &Idx);15481549unsigned EnumValue = 0;1550if (MatchingSubClass) {1551CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;1552EnumValue = SubRegClass->EnumValue + 1;1553}15541555OS << " " << EnumValue << ",\t// " << RC.getName() << ':'1556<< Idx.getName();15571558if (MatchingSubClass) {1559CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;1560OS << " -> " << SubRegClass->getName();1561}15621563OS << '\n';1564}15651566OS << " },\n";1567}1568OS << " };\n assert(RC && \"Missing regclass\");\n"1569<< " if (!Idx) return RC;\n --Idx;\n"1570<< " assert(Idx < " << SubRegIndicesSize << " && \"Bad subreg\");\n"1571<< " unsigned TV = Table[RC->getID()][Idx];\n"1572<< " return TV ? getRegClass(TV - 1) : nullptr;\n}\n\n";1573}15741575EmitRegUnitPressure(OS, RegBank, ClassName);15761577// Emit register base class mapper1578if (!RegisterClasses.empty()) {1579// Collect base classes1580SmallVector<const CodeGenRegisterClass *> BaseClasses;1581for (const auto &RC : RegisterClasses) {1582if (RC.getBaseClassOrder())1583BaseClasses.push_back(&RC);1584}1585if (!BaseClasses.empty()) {1586assert(BaseClasses.size() < UINT16_MAX &&1587"Too many base register classes");15881589// Apply order1590struct BaseClassOrdering {1591bool operator()(const CodeGenRegisterClass *LHS,1592const CodeGenRegisterClass *RHS) const {1593return std::pair(*LHS->getBaseClassOrder(), LHS->EnumValue) <1594std::pair(*RHS->getBaseClassOrder(), RHS->EnumValue);1595}1596};1597llvm::stable_sort(BaseClasses, BaseClassOrdering());15981599OS << "\n// Register to base register class mapping\n\n";1600OS << "\n";1601OS << "const TargetRegisterClass *" << ClassName1602<< "::getPhysRegBaseClass(MCRegister Reg)"1603<< " const {\n";1604OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";1605OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";1606OS << " InvalidRegClassID, // NoRegister\n";1607for (const CodeGenRegister &Reg : Regs) {1608const CodeGenRegisterClass *BaseRC = nullptr;1609for (const CodeGenRegisterClass *RC : BaseClasses) {1610if (is_contained(RC->getMembers(), &Reg)) {1611BaseRC = RC;1612break;1613}1614}16151616OS << " "1617<< (BaseRC ? BaseRC->getQualifiedIdName() : "InvalidRegClassID")1618<< ", // " << Reg.getName() << "\n";1619}1620OS << " };\n\n"1621" assert(Reg < ArrayRef(Mapping).size());\n"1622" unsigned RCID = Mapping[Reg];\n"1623" if (RCID == InvalidRegClassID)\n"1624" return nullptr;\n"1625" return RegisterClasses[RCID];\n"1626"}\n";1627}1628}16291630// Emit the constructor of the class...1631OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";1632OS << "extern const int16_t " << TargetName << "RegDiffLists[];\n";1633OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";1634OS << "extern const char " << TargetName << "RegStrings[];\n";1635OS << "extern const char " << TargetName << "RegClassStrings[];\n";1636OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";1637OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";1638OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";16391640EmitRegMappingTables(OS, Regs, true);16411642OS << ClassName << "::\n"1643<< ClassName1644<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,\n"1645" unsigned PC, unsigned HwMode)\n"1646<< " : TargetRegisterInfo(&" << TargetName << "RegInfoDesc"1647<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() << ",\n"1648<< " SubRegIndexNameTable, SubRegIdxRangeTable, "1649"SubRegIndexLaneMaskTable,\n"1650<< " ";1651printMask(OS, RegBank.CoveringLanes);1652OS << ", RegClassInfos, VTLists, HwMode) {\n"1653<< " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size() + 11654<< ", RA, PC,\n " << TargetName1655<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"1656<< " " << TargetName << "RegUnitRoots,\n"1657<< " " << RegBank.getNumNativeRegUnits() << ",\n"1658<< " " << TargetName << "RegDiffLists,\n"1659<< " " << TargetName << "LaneMaskLists,\n"1660<< " " << TargetName << "RegStrings,\n"1661<< " " << TargetName << "RegClassStrings,\n"1662<< " " << TargetName << "SubRegIdxLists,\n"1663<< " " << SubRegIndicesSize + 1 << ",\n"1664<< " " << TargetName << "RegEncodingTable);\n\n";16651666EmitRegMapping(OS, Regs, true);16671668OS << "}\n\n";16691670// Emit CalleeSavedRegs information.1671std::vector<Record *> CSRSets =1672Records.getAllDerivedDefinitions("CalleeSavedRegs");1673for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {1674Record *CSRSet = CSRSets[i];1675const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);1676assert(Regs && "Cannot expand CalleeSavedRegs instance");16771678// Emit the *_SaveList list of callee-saved registers.1679OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { ";1680for (unsigned r = 0, re = Regs->size(); r != re; ++r)1681OS << getQualifiedName((*Regs)[r]) << ", ";1682OS << "0 };\n";16831684// Emit the *_RegMask bit mask of call-preserved registers.1685BitVector Covered = RegBank.computeCoveredRegisters(*Regs);16861687// Check for an optional OtherPreserved set.1688// Add those registers to RegMask, but not to SaveList.1689if (DagInit *OPDag =1690dyn_cast<DagInit>(CSRSet->getValueInit("OtherPreserved"))) {1691SetTheory::RecSet OPSet;1692RegBank.getSets().evaluate(OPDag, OPSet, CSRSet->getLoc());1693Covered |= RegBank.computeCoveredRegisters(1694ArrayRef<Record *>(OPSet.begin(), OPSet.end()));1695}16961697// Add all constant physical registers to the preserved mask:1698SetTheory::RecSet ConstantSet;1699for (auto &Reg : RegBank.getRegisters()) {1700if (Reg.Constant)1701ConstantSet.insert(Reg.TheDef);1702}1703Covered |= RegBank.computeCoveredRegisters(1704ArrayRef<Record *>(ConstantSet.begin(), ConstantSet.end()));17051706OS << "static const uint32_t " << CSRSet->getName() << "_RegMask[] = { ";1707printBitVectorAsHex(OS, Covered, 32);1708OS << "};\n";1709}1710OS << "\n\n";17111712OS << "ArrayRef<const uint32_t *> " << ClassName1713<< "::getRegMasks() const {\n";1714if (!CSRSets.empty()) {1715OS << " static const uint32_t *const Masks[] = {\n";1716for (Record *CSRSet : CSRSets)1717OS << " " << CSRSet->getName() << "_RegMask,\n";1718OS << " };\n";1719OS << " return ArrayRef(Masks);\n";1720} else {1721OS << " return std::nullopt;\n";1722}1723OS << "}\n\n";17241725const std::list<CodeGenRegisterCategory> &RegCategories =1726RegBank.getRegCategories();1727OS << "bool " << ClassName << "::\n"1728<< "isGeneralPurposeRegister(const MachineFunction &MF, "1729<< "MCRegister PhysReg) const {\n"1730<< " return\n";1731for (const CodeGenRegisterCategory &Category : RegCategories)1732if (Category.getName() == "GeneralPurposeRegisters") {1733for (const CodeGenRegisterClass *RC : Category.getClasses())1734OS << " " << RC->getQualifiedName()1735<< "RegClass.contains(PhysReg) ||\n";1736break;1737}1738OS << " false;\n";1739OS << "}\n\n";17401741OS << "bool " << ClassName << "::\n"1742<< "isFixedRegister(const MachineFunction &MF, "1743<< "MCRegister PhysReg) const {\n"1744<< " return\n";1745for (const CodeGenRegisterCategory &Category : RegCategories)1746if (Category.getName() == "FixedRegisters") {1747for (const CodeGenRegisterClass *RC : Category.getClasses())1748OS << " " << RC->getQualifiedName()1749<< "RegClass.contains(PhysReg) ||\n";1750break;1751}1752OS << " false;\n";1753OS << "}\n\n";17541755OS << "bool " << ClassName << "::\n"1756<< "isArgumentRegister(const MachineFunction &MF, "1757<< "MCRegister PhysReg) const {\n"1758<< " return\n";1759for (const CodeGenRegisterCategory &Category : RegCategories)1760if (Category.getName() == "ArgumentRegisters") {1761for (const CodeGenRegisterClass *RC : Category.getClasses())1762OS << " " << RC->getQualifiedName()1763<< "RegClass.contains(PhysReg) ||\n";1764break;1765}1766OS << " false;\n";1767OS << "}\n\n";17681769OS << "bool " << ClassName << "::\n"1770<< "isConstantPhysReg(MCRegister PhysReg) const {\n"1771<< " return\n";1772for (const auto &Reg : Regs)1773if (Reg.Constant)1774OS << " PhysReg == " << getQualifiedName(Reg.TheDef) << " ||\n";1775OS << " false;\n";1776OS << "}\n\n";17771778OS << "ArrayRef<const char *> " << ClassName1779<< "::getRegMaskNames() const {\n";1780if (!CSRSets.empty()) {1781OS << " static const char *Names[] = {\n";1782for (Record *CSRSet : CSRSets)1783OS << " " << '"' << CSRSet->getName() << '"' << ",\n";1784OS << " };\n";1785OS << " return ArrayRef(Names);\n";1786} else {1787OS << " return std::nullopt;\n";1788}1789OS << "}\n\n";17901791OS << "const " << TargetName << "FrameLowering *\n"1792<< TargetName1793<< "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"1794<< " return static_cast<const " << TargetName << "FrameLowering *>(\n"1795<< " MF.getSubtarget().getFrameLowering());\n"1796<< "}\n\n";17971798OS << "} // end namespace llvm\n\n";1799OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";1800}18011802void RegisterInfoEmitter::run(raw_ostream &OS) {1803CodeGenRegBank &RegBank = Target.getRegBank();1804Records.startTimer("Print enums");1805runEnums(OS, Target, RegBank);18061807Records.startTimer("Print MC registers");1808runMCDesc(OS, Target, RegBank);18091810Records.startTimer("Print header fragment");1811runTargetHeader(OS, Target, RegBank);18121813Records.startTimer("Print target registers");1814runTargetDesc(OS, Target, RegBank);18151816if (RegisterInfoDebug)1817debugDump(errs());1818}18191820void RegisterInfoEmitter::debugDump(raw_ostream &OS) {1821CodeGenRegBank &RegBank = Target.getRegBank();1822const CodeGenHwModes &CGH = Target.getHwModes();1823unsigned NumModes = CGH.getNumModeIds();1824auto getModeName = [CGH](unsigned M) -> StringRef {1825if (M == 0)1826return "Default";1827return CGH.getMode(M).Name;1828};18291830for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {1831OS << "RegisterClass " << RC.getName() << ":\n";1832OS << "\tSpillSize: {";1833for (unsigned M = 0; M != NumModes; ++M)1834OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillSize;1835OS << " }\n\tSpillAlignment: {";1836for (unsigned M = 0; M != NumModes; ++M)1837OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillAlignment;1838OS << " }\n\tNumRegs: " << RC.getMembers().size() << '\n';1839OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';1840OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';1841OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';1842OS << "\tAllocatable: " << RC.Allocatable << '\n';1843OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';1844OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';1845OS << "\tRegs:";1846for (const CodeGenRegister *R : RC.getMembers()) {1847OS << " " << R->getName();1848}1849OS << '\n';1850OS << "\tSubClasses:";1851const BitVector &SubClasses = RC.getSubClasses();1852for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {1853if (!SubClasses.test(SRC.EnumValue))1854continue;1855OS << " " << SRC.getName();1856}1857OS << '\n';1858OS << "\tSuperClasses:";1859for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {1860OS << " " << SRC->getName();1861}1862OS << '\n';1863}18641865for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {1866OS << "SubRegIndex " << SRI.getName() << ":\n";1867OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n';1868OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';1869OS << "\tOffset: {";1870for (unsigned M = 0; M != NumModes; ++M)1871OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Offset;1872OS << " }\n\tSize: {";1873for (unsigned M = 0; M != NumModes; ++M)1874OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Size;1875OS << " }\n";1876}18771878for (const CodeGenRegister &R : RegBank.getRegisters()) {1879OS << "Register " << R.getName() << ":\n";1880OS << "\tCostPerUse: ";1881for (const auto &Cost : R.CostPerUse)1882OS << Cost << " ";1883OS << '\n';1884OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';1885OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';1886for (std::pair<CodeGenSubRegIndex *, CodeGenRegister *> P :1887R.getSubRegs()) {1888OS << "\tSubReg " << P.first->getName() << " = " << P.second->getName()1889<< '\n';1890}1891}1892}18931894static TableGen::Emitter::OptClass<RegisterInfoEmitter>1895X("gen-register-info", "Generate registers and register classes info");189618971898