//===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting a description of a target
// register file for a code generator.  It uses instances of the Register,
// RegisterAliases, and RegisterClass classes to gather this information.
//
//===----------------------------------------------------------------------===//

#include "Basic/SequenceToOffsetTable.h"
#include "Common/CodeGenHwModes.h"
#include "Common/CodeGenRegisters.h"
#include "Common/CodeGenTarget.h"
#include "Common/InfoByHwMode.h"
#include "Common/Types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Printable.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/CodeGenHelpers.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/SetTheory.h"
#include "llvm/TableGen/TGTimer.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <iterator>
#include <set>
#include <string>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "register-info-emitter"

STATISTIC(NumExplicitRegClasses, "Number of explicit register classes");
STATISTIC(NumSynthesizedRegClasses, "Number of synthesized register classes");
STATISTIC(NumRegPressureSets, "Number of register pressure sets");

static cl::OptionCategory RegisterInfoCat("Options for -gen-register-info");

static cl::opt<bool>
    RegisterInfoDebug("register-info-debug", cl::init(false),
                      cl::desc("Dump register information to help debugging"),
                      cl::cat(RegisterInfoCat));

namespace {

class RegisterInfoEmitter {
  const RecordKeeper &Records;
  const CodeGenTarget Target;
  CodeGenRegBank &RegBank;

  std::string MCRegisterClassStorageType;

public:
  RegisterInfoEmitter(const RecordKeeper &R)
      : Records(R), Target(R), RegBank(Target.getRegBank()) {
    RegBank.computeDerivedInfo();

    const auto &RegClasses = RegBank.getRegClasses();
    NumExplicitRegClasses =
        llvm::count_if(RegClasses, [](const CodeGenRegisterClass &RC) {
          return RC.getDef() != nullptr;
        });
    NumSynthesizedRegClasses = RegClasses.size() - NumExplicitRegClasses;
    NumRegPressureSets = RegBank.getNumRegPressureSets();
  }

  // runEnums - Print out enum values for all of the registers.
  void runEnums(raw_ostream &OS, raw_ostream &MainOS, StringRef FilenamePrefix);

  // runMCDesc - Print out MC register descriptions.
  void runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
                 StringRef FilenamePrefix);

  // runTargetHeader - Emit a header fragment for the register info emitter.
  void runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
                       StringRef FilenamePrefix);

  // runTargetDesc - Output the target register and register file descriptions.
  void runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
                     StringRef FilenamePrefix);

  // run - Output the register file description.
  TableGenOutputFiles run(StringRef FilenamePrefix);

  template <typename InfoTy, typename FnTy>
  Printable printByHwMode(const InfoByHwMode<InfoTy> &Info, FnTy Func);

  void debugDump(raw_ostream &OS);

private:
  void EmitRegMapping(raw_ostream &OS, const std::deque<CodeGenRegister> &Regs,
                      bool isCtor);
  void EmitRegMappingTables(raw_ostream &OS,
                            const std::deque<CodeGenRegister> &Regs,
                            bool isCtor);
  void EmitRegUnitPressure(raw_ostream &OS, StringRef ClassName);
  void emitComposeSubRegIndices(raw_ostream &OS, StringRef ClassName);
  void emitComposeSubRegIndexLaneMask(raw_ostream &OS, StringRef ClassName);
};

} // end anonymous namespace

static void emitInclude(StringRef FilenamePrefix, StringRef IncludeFile,
                        StringRef GuardMacro, raw_ostream &OS) {
  IfDefEmitter IfDed(OS, GuardMacro);
  OS << "#include \"" << FilenamePrefix << IncludeFile << "\"\n";
}

// runEnums - Print out enum values for all of the registers.
void RegisterInfoEmitter::runEnums(raw_ostream &OS, raw_ostream &MainOS,
                                   StringRef FilenamePrefix) {
  emitInclude(FilenamePrefix, "Enums.inc", "GET_REGINFO_ENUM", MainOS);

  const auto &Registers = RegBank.getRegisters();

  // Register enums are stored as uint16_t in the tables. Make sure we'll fit.
  assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");

  StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");

  emitSourceFileHeader("Target Register Enum Values", OS);

  NamespaceEmitter LlvmNS(OS, "llvm");

  OS << "class MCRegisterClass;\n";
  OS << "const MCRegisterClass &get" << Target.getName()
     << "MCRegisterClass(unsigned RC);\n";

  {
    NamespaceEmitter RegNS(OS, Namespace);
    OS << "enum : unsigned {\n  NoRegister,\n";

    for (const auto &Reg : Registers)
      OS << "  " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
    assert(Registers.size() == Registers.back().EnumValue &&
           "Register enum value mismatch!");
    OS << "  NUM_TARGET_REGS // " << Registers.size() + 1 << "\n";
    OS << "};\n";
  }

  const auto &RegisterClasses = RegBank.getRegClasses();
  if (!RegisterClasses.empty()) {
    // RegisterClass enums are stored as uint16_t in the tables.
    assert(RegisterClasses.size() <= UINT16_MAX &&
           "Too many register classes to fit in tables");

    OS << "\n// Register classes\n\n";
    NamespaceEmitter RegNS(OS, Namespace);
    OS << "enum {\n";
    for (const auto &RC : RegisterClasses)
      OS << "  " << RC.getIdName() << " = " << RC.EnumValue << ",\n";
    OS << "\n};\n";
  }

  ArrayRef<const Record *> RegAltNameIndices = Target.getRegAltNameIndices();
  // If the only definition is the default NoRegAltName, we don't need to
  // emit anything.
  if (RegAltNameIndices.size() > 1) {
    OS << "\n// Register alternate name indices\n\n";
    NamespaceEmitter RegNS(OS, Namespace);
    OS << "enum {\n";
    for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
      OS << "  " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n";
    OS << "  NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n";
    OS << "};\n";
  }

  auto &SubRegIndices = RegBank.getSubRegIndices();
  if (!SubRegIndices.empty()) {
    OS << "\n// Subregister indices\n\n";
    NamespaceEmitter SubRegNS(OS, SubRegIndices.front().getNamespace());
    OS << "enum : uint16_t {\n  NoSubRegister,\n";
    unsigned i = 0;
    for (const auto &Idx : SubRegIndices)
      OS << "  " << Idx.getName() << ",\t// " << ++i << "\n";
    OS << "  NUM_TARGET_SUBREGS\n};\n";
  }

  {
    OS << "// Register pressure sets enum.\n";
    NamespaceEmitter RegNS(OS, Namespace);
    OS << "enum RegisterPressureSets {\n";
    unsigned NumSets = RegBank.getNumRegPressureSets();
    for (unsigned i = 0; i < NumSets; ++i) {
      const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
      OS << "  " << RegUnits.Name << " = " << i << ",\n";
    }
    OS << "};\n";
  }

  // Note: While these functions are not enums, we need to define them in the
  // same place as <TARGET>::<REG>, so that the assembly parser can use them
  // without having to include <TARGETT>RegisterInfo.h, which may not be
  // possible due to build system structure.
  ArrayRef<const Record *> RegisterByHwModeRecords =
      Records.getAllDerivedDefinitions("RegisterByHwMode");
  if (!RegisterByHwModeRecords.empty()) {
    OS << "// Registers by HwMode\n";
    OS << "class MCRegister;\n";
    NamespaceEmitter RegClassNS(OS, Namespace + "::RegisterByHwMode");
    // Define the getters for the RegisterByHwMode in one globally accessible
    // location so they can be reused by all callers.
    for (const Record *Rec : RegisterByHwModeRecords) {
      OS << "LLVM_READONLY MCRegister get" << Rec->getName()
         << "(unsigned HwMode);\n";
    }
  }
}

static void printInt(raw_ostream &OS, int Val) { OS << Val; }

void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS,
                                              StringRef ClassName) {
  unsigned NumRCs = RegBank.getRegClasses().size();
  unsigned NumSets = RegBank.getNumRegPressureSets();
  std::vector<std::pair<const CodeGenRegisterClass *, unsigned>> PSetRegClasses(
      NumSets);

  OS << "/// Get the weight in units of pressure for this register class.\n"
     << "const RegClassWeight &" << ClassName << "::\n"
     << "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
     << "  static const RegClassWeight RCWeightTable[] = {\n";
  for (const auto &[RCIdx, RC] : enumerate(RegBank.getRegClasses())) {
    const CodeGenRegister::Vec &Regs = RC.getMembers();
    OS << "    {" << RC.getWeight(RegBank) << ", ";
    unsigned WeightLimit = 0;
    if (Regs.empty() || RC.Artificial)
      OS << '0';
    else {
      std::vector<unsigned> RegUnits;
      RC.buildRegUnitSet(RegBank, RegUnits);
      WeightLimit = RegBank.getRegUnitSetWeight(RegUnits);
      OS << WeightLimit;
    }
    OS << "},  \t// " << RC.getName() << "\n";
    for (unsigned PSetID : RegBank.getRCPressureSetIDs(RCIdx)) {
      unsigned PSetIdx = RegBank.getRegPressureSet(PSetID).Order;
      auto &[LargestRC, LargestWeightLimit] = PSetRegClasses[PSetIdx];
      if (!LargestRC || WeightLimit > LargestWeightLimit) {
        LargestRC = &RC;
        LargestWeightLimit = WeightLimit;
      }
    }
  }
  OS << "  };\n"
     << "  return RCWeightTable[RC->getID()];\n"
     << "}\n\n";

  // Reasonable targets (not ARMv7) have unit weight for all units, so don't
  // bother generating a table.
  bool RegUnitsHaveUnitWeight = true;
  for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
       UnitIdx < UnitEnd; ++UnitIdx) {
    if (RegBank.getRegUnit(UnitIdx).Weight > 1)
      RegUnitsHaveUnitWeight = false;
  }
  OS << "/// Get the weight in units of pressure for this register unit.\n"
     << "unsigned " << ClassName << "::\n"
     << "getRegUnitWeight(MCRegUnit RegUnit) const {\n"
     << "  assert(static_cast<unsigned>(RegUnit) < "
     << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n";
  if (!RegUnitsHaveUnitWeight) {
    OS << "  static const uint8_t RUWeightTable[] = {\n    ";
    for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
         UnitIdx < UnitEnd; ++UnitIdx) {
      const RegUnit &RU = RegBank.getRegUnit(UnitIdx);
      assert(RU.Weight < 256 && "RegUnit too heavy");
      OS << RU.Weight << ", ";
    }
    OS << "};\n"
       << "  return RUWeightTable[static_cast<unsigned>(RegUnit)];\n";
  } else {
    OS << "  // All register units have unit weight.\n"
       << "  return 1;\n";
  }
  OS << "}\n\n";

  OS << "\n"
     << "// Get the number of dimensions of register pressure.\n"
     << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
     << "  return " << NumSets << ";\n}\n\n";

  OS << "// Get the name of this register unit pressure set.\n"
     << "const char *" << ClassName << "::\n"
     << "getRegPressureSetName(unsigned Idx) const {\n"
     << "  static const char *PressureNameTable[] = {\n";
  unsigned MaxRegUnitWeight = 0;
  for (unsigned i = 0; i < NumSets; ++i) {
    const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
    MaxRegUnitWeight = std::max(MaxRegUnitWeight, RegUnits.Weight);
    OS << "    \"" << RegUnits.Name << "\",\n";
  }
  OS << "  };\n"
     << "  return PressureNameTable[Idx];\n"
     << "}\n\n";

  OS << "// Get the register unit pressure limit for this dimension.\n"
     << "// This limit must be adjusted dynamically for reserved registers.\n"
     << "unsigned " << ClassName << "::\n"
     << "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const "
        "{\n"
     << "  static const " << getMinimalTypeForRange(MaxRegUnitWeight, 32)
     << " PressureLimitTable[] = {\n";
  for (unsigned i = 0; i < NumSets; ++i) {
    const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
    OS << "    " << RegUnits.Weight << ",  \t// " << i << ": " << RegUnits.Name
       << "\n";
  }
  OS << "  };\n"
     << "  return PressureLimitTable[Idx];\n"
     << "}\n\n";

  OS << "/// Get the register class for this pressure set with the largest\n"
     << "/// `RegClassWeight::WeightLimit`.\n"
     << "const TargetRegisterClass *" << ClassName << "::\n"
     << "getLargestRegClassForRegPressureSet(unsigned Idx) const {\n"
     << "  static const " << getMinimalTypeForRange(NumRCs - 1, 32)
     << " PSetRegClassTable[] = {\n";
  for (unsigned i = 0; i < NumSets; ++i) {
    const CodeGenRegisterClass *RC = PSetRegClasses[i].first;
    assert(RC && "register pressure set has no register class");
    OS << "    " << RC->getQualifiedIdName() << ",  \t// " << i << ": "
       << RegBank.getRegSetAt(i).Name << "\n";
  }
  OS << "  };\n"
     << "  return getRegClass(PSetRegClassTable[Idx]);\n"
     << "}\n\n";

  SequenceToOffsetTable<std::vector<int>> PSetsSeqs(/*Terminator=*/-1);

  // This table may be larger than NumRCs if some register units needed a list
  // of unit sets that did not correspond to a register class.
  unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
  std::vector<std::vector<int>> PSets(NumRCUnitSets);

  for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
    ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
    PSets[i].reserve(PSetIDs.size());
    for (unsigned PSetID : PSetIDs) {
      PSets[i].push_back(RegBank.getRegPressureSet(PSetID).Order);
    }
    llvm::sort(PSets[i]);
    PSetsSeqs.add(PSets[i]);
  }

  PSetsSeqs.layout();

  OS << "/// Table of pressure sets per register class or unit.\n"
     << "static const int RCSetsTable[] = {\n";
  PSetsSeqs.emit(OS, printInt);
  OS << "};\n\n";

  OS << "/// Get the dimensions of register pressure impacted by this "
     << "register class.\n"
     << "/// Returns a -1 terminated array of pressure set IDs\n"
     << "const int *" << ClassName << "::\n"
     << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
  OS << "  static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)
     << " RCSetStartTable[] = {\n    ";
  for (unsigned i = 0, e = NumRCs; i != e; ++i) {
    OS << PSetsSeqs.get(PSets[i]) << ",";
  }
  OS << "};\n"
     << "  return &RCSetsTable[RCSetStartTable[RC->getID()]];\n"
     << "}\n\n";

  OS << "/// Get the dimensions of register pressure impacted by this "
     << "register unit.\n"
     << "/// Returns a -1 terminated array of pressure set IDs\n"
     << "const int *" << ClassName << "::\n"
     << "getRegUnitPressureSets(MCRegUnit RegUnit) const {\n"
     << "  assert(static_cast<unsigned>(RegUnit) < "
     << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n";
  OS << "  static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32)
     << " RUSetStartTable[] = {\n    ";
  for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
       UnitIdx < UnitEnd; ++UnitIdx) {
    OS << PSetsSeqs.get(PSets[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx])
       << ",";
  }
  OS << "};\n"
     << "  return "
        "&RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];\n"
     << "}\n\n";
}

using DwarfRegNumsMapPair = std::pair<const Record *, std::vector<int64_t>>;
using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>;

static void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) {
  // Sort and unique to get a map-like vector. We want the last assignment to
  // match previous behaviour.
  llvm::stable_sort(DwarfRegNums, on_first<LessRecordRegister>());
  // Warn about duplicate assignments.
  const Record *LastSeenReg = nullptr;
  for (const auto &X : DwarfRegNums) {
    const auto &Reg = X.first;
    // The only way LessRecordRegister can return equal is if they're the same
    // string. Use simple equality instead.
    if (LastSeenReg && Reg->getName() == LastSeenReg->getName())
      PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") +
                                      getQualifiedName(Reg) +
                                      "specified multiple times");
    LastSeenReg = Reg;
  }
  auto Last = llvm::unique(DwarfRegNums, [](const DwarfRegNumsMapPair &A,
                                            const DwarfRegNumsMapPair &B) {
    return A.first->getName() == B.first->getName();
  });
  DwarfRegNums.erase(Last, DwarfRegNums.end());
}

void RegisterInfoEmitter::EmitRegMappingTables(
    raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
  // Collect all information about dwarf register numbers
  DwarfRegNumsVecTy DwarfRegNums;

  // First, just pull all provided information to the map
  unsigned maxLength = 0;
  for (auto &RE : Regs) {
    const Record *Reg = RE.TheDef;
    std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
    maxLength = std::max((size_t)maxLength, RegNums.size());
    DwarfRegNums.emplace_back(Reg, std::move(RegNums));
  }
  finalizeDwarfRegNumsKeys(DwarfRegNums);

  if (!maxLength)
    return;

  // Now we know maximal length of number list. Append -1's, where needed
  for (auto &DwarfRegNum : DwarfRegNums)
    for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)
      DwarfRegNum.second.push_back(-1);

  StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");

  OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";

  // Emit reverse information about the dwarf register numbers.
  for (unsigned j = 0; j < 2; ++j) {
    for (unsigned I = 0, E = maxLength; I != E; ++I) {
      OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
      OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
      OS << I << "Dwarf2L[]";

      if (!isCtor) {
        OS << " = {\n";

        // Store the mapping sorted by the LLVM reg num so lookup can be done
        // with a binary search.
        std::map<uint64_t, const Record *> Dwarf2LMap;
        for (auto &DwarfRegNum : DwarfRegNums) {
          int DwarfRegNo = DwarfRegNum.second[I];
          if (DwarfRegNo < 0)
            continue;
          Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;
        }

        for (auto &I : Dwarf2LMap)
          OS << "  { " << I.first << "U, " << getQualifiedName(I.second)
             << " },\n";

        OS << "};\n";
      } else {
        OS << ";\n";
      }

      // We have to store the size in a const global, it's used in multiple
      // places.
      OS << "extern const unsigned " << Namespace
         << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";
      if (!isCtor)
        OS << " = std::size(" << Namespace
           << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";
      else
        OS << ";\n\n";
    }
  }

  for (auto &RE : Regs) {
    const Record *Reg = RE.TheDef;
    const RecordVal *V = Reg->getValue("DwarfAlias");
    if (!V || !V->getValue())
      continue;

    const DefInit *DI = cast<DefInit>(V->getValue());
    const Record *Alias = DI->getDef();
    const auto &AliasIter = llvm::lower_bound(
        DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {
          return LessRecordRegister()(A.first, B);
        });
    assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias &&
           "Expected Alias to be present in map");
    const auto &RegIter = llvm::lower_bound(
        DwarfRegNums, Reg, [](const DwarfRegNumsMapPair &A, const Record *B) {
          return LessRecordRegister()(A.first, B);
        });
    assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg &&
           "Expected Reg to be present in map");
    RegIter->second = AliasIter->second;
  }

  // Emit information about the dwarf register numbers.
  for (unsigned j = 0; j < 2; ++j) {
    for (unsigned i = 0, e = maxLength; i != e; ++i) {
      OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
      OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
      OS << i << "L2Dwarf[]";
      if (!isCtor) {
        OS << " = {\n";
        // Store the mapping sorted by the Dwarf reg num so lookup can be done
        // with a binary search.
        for (auto &DwarfRegNum : DwarfRegNums) {
          int RegNo = DwarfRegNum.second[i];
          if (RegNo == -1) // -1 is the default value, don't emit a mapping.
            continue;

          OS << "  { " << getQualifiedName(DwarfRegNum.first) << ", " << RegNo
             << "U },\n";
        }
        OS << "};\n";
      } else {
        OS << ";\n";
      }

      // We have to store the size in a const global, it's used in multiple
      // places.
      OS << "extern const unsigned " << Namespace
         << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";
      if (!isCtor)
        OS << " = std::size(" << Namespace
           << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2Dwarf);\n\n";
      else
        OS << ";\n\n";
    }
  }
}

void RegisterInfoEmitter::EmitRegMapping(
    raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
  // Emit the initializer so the tables from EmitRegMappingTables get wired up
  // to the MCRegisterInfo object.
  unsigned maxLength = 0;
  for (auto &RE : Regs) {
    const Record *Reg = RE.TheDef;
    maxLength = std::max((size_t)maxLength,
                         Reg->getValueAsListOfInts("DwarfNumbers").size());
  }

  if (!maxLength)
    return;

  StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");

  // Emit reverse information about the dwarf register numbers.
  for (unsigned j = 0; j < 2; ++j) {
    OS << "  switch (";
    if (j == 0)
      OS << "DwarfFlavour";
    else
      OS << "EHFlavour";
    OS << ") {\n"
       << "  default:\n"
       << "    llvm_unreachable(\"Unknown DWARF flavour\");\n";

    for (unsigned i = 0, e = maxLength; i != e; ++i) {
      OS << "  case " << i << ":\n";
      OS << "    ";
      if (!isCtor)
        OS << "RI->";
      std::string Tmp;
      raw_string_ostream(Tmp)
          << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
          << "Dwarf2L";
      OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";
      if (j == 0)
        OS << "false";
      else
        OS << "true";
      OS << ");\n";
      OS << "    break;\n";
    }
    OS << "  }\n";
  }

  // Emit information about the dwarf register numbers.
  for (unsigned j = 0; j < 2; ++j) {
    OS << "  switch (";
    if (j == 0)
      OS << "DwarfFlavour";
    else
      OS << "EHFlavour";
    OS << ") {\n"
       << "  default:\n"
       << "    llvm_unreachable(\"Unknown DWARF flavour\");\n";

    for (unsigned i = 0, e = maxLength; i != e; ++i) {
      OS << "  case " << i << ":\n";
      OS << "    ";
      if (!isCtor)
        OS << "RI->";
      std::string Tmp;
      raw_string_ostream(Tmp)
          << Namespace << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
          << "L2Dwarf";
      OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";
      if (j == 0)
        OS << "false";
      else
        OS << "true";
      OS << ");\n";
      OS << "    break;\n";
    }
    OS << "  }\n";
  }
}

// Print a BitVector as a sequence of hex numbers using a little-endian mapping.
// Width is the number of bits per hex number.
static void printBitVectorAsHex(raw_ostream &OS, const BitVector &Bits,
                                unsigned Width) {
  assert(Width <= 32 && "Width too large");
  unsigned Digits = (Width + 3) / 4;
  for (unsigned i = 0, e = Bits.size(); i < e; i += Width) {
    unsigned Value = 0;
    for (unsigned j = 0; j != Width && i + j != e; ++j)
      Value |= Bits.test(i + j) << j;
    OS << format("0x%0*x, ", Digits, Value);
  }
}

// Helper to emit a set of bits into a constant byte array.
class BitVectorEmitter {
  BitVector Values;

public:
  void add(unsigned v) {
    if (v >= Values.size())
      Values.resize(((v / 8) + 1) * 8); // Round up to the next byte.
    Values[v] = true;
  }

  unsigned byteSize() const { return (Values.size() + 7) / 8; }

  void print(raw_ostream &OS) { printBitVectorAsHex(OS, Values, 8); }
};

static void printSimpleValueType(raw_ostream &OS, MVT VT) {
  OS << getEnumName(VT);
}

static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
  OS << (Idx ? Idx->EnumValue : 0);
}

// Differentially encoded register and regunit lists allow for better
// compression on regular register banks. The sequence is computed from the
// differential list as:
//
//   out[0] = InitVal;
//   out[n+1] = out[n] + diff[n]; // n = 0, 1, ...
//
// The initial value depends on the specific list. The list is terminated by a
// 0 differential which means we can't encode repeated elements.

using DiffVec = SmallVector<int16_t, 4>;
using MaskVec = SmallVector<LaneBitmask, 4>;

// Fills V with differentials between every two consecutive elements of List.
static DiffVec &diffEncode(DiffVec &V, SparseBitVector<> List) {
  assert(V.empty() && "Clear DiffVec before diffEncode.");
  SparseBitVector<>::iterator I = List.begin(), E = List.end();
  unsigned Val = *I;
  while (++I != E) {
    unsigned Cur = *I;
    V.push_back(Cur - Val);
    Val = Cur;
  }
  return V;
}

template <typename Iter>
static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) {
  assert(V.empty() && "Clear DiffVec before diffEncode.");
  unsigned Val = InitVal;
  for (Iter I = Begin; I != End; ++I) {
    unsigned Cur = (*I)->EnumValue;
    V.push_back(Cur - Val);
    Val = Cur;
  }
  return V;
}

static void printDiff16(raw_ostream &OS, int16_t Val) { OS << Val; }

static void printMask(raw_ostream &OS, LaneBitmask Val) {
  OS << "LaneBitmask(0x" << PrintLaneMask(Val) << ')';
}

// Try to combine Idx's compose map into Vec if it is compatible.
// Return false if it's not possible.
static bool combine(const CodeGenSubRegIndex *Idx,
                    SmallVectorImpl<const CodeGenSubRegIndex *> &Vec) {
  const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
  for (const auto &I : Map) {
    const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
    if (Entry && Entry != I.second)
      return false;
  }

  // All entries are compatible. Make it so.
  for (const auto &I : Map) {
    const CodeGenSubRegIndex *&Entry = Vec[I.first->EnumValue - 1];
    assert((!Entry || Entry == I.second) && "Expected EnumValue to be unique");
    Entry = I.second;
  }
  return true;
}

void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
                                                   StringRef ClassName) {
  const auto &SubRegIndices = RegBank.getSubRegIndices();

  // Many sub-register indexes are composition-compatible, meaning that
  //
  //   compose(IdxA, IdxB) == compose(IdxA', IdxB)
  //
  // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
  // The illegal entries can be use as wildcards to compress the table further.

  // Map each Sub-register index to a compatible table row.
  SmallVector<unsigned, 4> RowMap;
  SmallVector<SmallVector<const CodeGenSubRegIndex *, 4>, 4> Rows;

  size_t SubRegIndicesSize = llvm::size(SubRegIndices);
  for (const auto &Idx : SubRegIndices) {
    unsigned Found = ~0u;
    for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
      if (combine(&Idx, Rows[r])) {
        Found = r;
        break;
      }
    }
    if (Found == ~0u) {
      Found = Rows.size();
      Rows.resize(Found + 1);
      Rows.back().resize(SubRegIndicesSize);
      combine(&Idx, Rows.back());
    }
    RowMap.push_back(Found);
  }

  OS << "unsigned " << ClassName
     << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";

  // Output the row map if there are multiple rows.
  if (Rows.size() > 1) {
    OS << "  static const " << getMinimalTypeForRange(Rows.size(), 32)
       << " RowMap[" << SubRegIndicesSize << "] = {\n    ";
    for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i)
      OS << RowMap[i] << ", ";
    OS << "\n  };\n";
  }

  // Output the rows.
  OS << "  static const " << getMinimalTypeForRange(SubRegIndicesSize + 1, 32)
     << " Rows[" << Rows.size() << "][" << SubRegIndicesSize << "] = {\n";
  for (const auto &Row : Rows) {
    OS << "    { ";
    for (const llvm::CodeGenSubRegIndex *Elem :
         ArrayRef(&Row[0], SubRegIndicesSize))
      if (Elem)
        OS << Elem->getQualifiedName() << ", ";
      else
        OS << "0, ";
    OS << "},\n";
  }
  OS << "  };\n\n";

  OS << "  --IdxA; assert(IdxA < " << SubRegIndicesSize << "); (void) IdxA;\n"
     << "  --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
  if (Rows.size() > 1)
    OS << "  return Rows[RowMap[IdxA]][IdxB];\n";
  else
    OS << "  return Rows[0][IdxB];\n";
  OS << "}\n\n";

  // Generate the reverse case.
  //
  // FIXME: This is the brute force approach. Compress the table similar to the
  // forward case.
  OS << "unsigned " << ClassName
     << "::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const "
        "{\n";
  OS << "  static const " << getMinimalTypeForRange(SubRegIndicesSize + 1, 32)
     << " Table[" << SubRegIndicesSize << "][" << SubRegIndicesSize
     << "] = {\n";

  // Find values where composeSubReg(A, X) == B;
  for (const auto &IdxA : SubRegIndices) {
    OS << "    { ";

    SmallVectorImpl<const CodeGenSubRegIndex *> &Row =
        Rows[RowMap[IdxA.EnumValue - 1]];
    for (const auto &IdxB : SubRegIndices) {
      const CodeGenSubRegIndex *FoundReverse = nullptr;

      for (unsigned i = 0, e = SubRegIndicesSize; i != e; ++i) {
        const CodeGenSubRegIndex *This = &SubRegIndices[i];
        const CodeGenSubRegIndex *Composed = Row[i];
        if (Composed == &IdxB) {
          if (FoundReverse && FoundReverse != This) // Not unique
            break;
          FoundReverse = This;
        }
      }

      if (FoundReverse) {
        OS << FoundReverse->getQualifiedName() << ", ";
      } else {
        OS << "0, ";
      }
    }
    OS << "},\n";
  }

  OS << "  };\n\n";
  OS << "  --IdxA; assert(IdxA < " << SubRegIndicesSize << ");\n"
     << "  --IdxB; assert(IdxB < " << SubRegIndicesSize << ");\n";
  OS << "  return Table[IdxA][IdxB];\n";
  OS << "  }\n\n";
}

void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
                                                         StringRef ClassName) {
  // See the comments in computeSubRegLaneMasks() for our goal here.
  const auto &SubRegIndices = RegBank.getSubRegIndices();

  // Create a list of Mask+Rotate operations, with equivalent entries merged.
  SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
  SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
  for (const auto &Idx : SubRegIndices) {
    const SmallVector<MaskRolPair, 1> &IdxSequence =
        Idx.CompositionLaneMaskTransform;

    unsigned Found = ~0u;
    unsigned SIdx = 0;
    unsigned NextSIdx;
    for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
      SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
      NextSIdx = SIdx + Sequence.size() + 1;
      if (Sequence == IdxSequence) {
        Found = SIdx;
        break;
      }
    }
    if (Found == ~0u) {
      Sequences.push_back(IdxSequence);
      Found = SIdx;
    }
    SubReg2SequenceIndexMap.push_back(Found);
  }

  OS << "  struct MaskRolOp {\n"
        "    LaneBitmask Mask;\n"
        "    uint8_t  RotateLeft;\n"
        "  };\n"
        "  static const MaskRolOp LaneMaskComposeSequences[] = {\n";
  unsigned Idx = 0;
  for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
    OS << "    ";
    const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
    for (const MaskRolPair &P : Sequence) {
      printMask(OS << "{ ", P.Mask);
      OS << format(", %2u }, ", P.RotateLeft);
    }
    OS << "{ LaneBitmask::getNone(), 0 }";
    if (s + 1 != se)
      OS << ", ";
    OS << "  // Sequence " << Idx << "\n";
    Idx += Sequence.size() + 1;
  }
  auto *IntType =
      getMinimalTypeForRange(*llvm::max_element(SubReg2SequenceIndexMap));
  OS << "  };\n"
        "  static const "
     << IntType << " CompositeSequences[] = {\n";
  for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
    OS << "    ";
    OS << SubReg2SequenceIndexMap[i];
    if (i + 1 != e)
      OS << ",";
    OS << " // to " << SubRegIndices[i].getName() << "\n";
  }
  OS << "  };\n\n";

  OS << "LaneBitmask " << ClassName
     << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask)"
        " const {\n"
        "  --IdxA; assert(IdxA < "
     << SubRegIndices.size()
     << " && \"Subregister index out of bounds\");\n"
        "  LaneBitmask Result;\n"
        "  for (const MaskRolOp *Ops =\n"
        "       &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
        "       Ops->Mask.any(); ++Ops) {\n"
        "    LaneBitmask::Type M = LaneMask.getAsInteger() & "
        "Ops->Mask.getAsInteger();\n"
        "    if (unsigned S = Ops->RotateLeft)\n"
        "      Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - "
        "S)));\n"
        "    else\n"
        "      Result |= LaneBitmask(M);\n"
        "  }\n"
        "  return Result;\n"
        "}\n\n";

  OS << "LaneBitmask " << ClassName
     << "::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, "
        " LaneBitmask LaneMask) const {\n"
        "  LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
        "  --IdxA; assert(IdxA < "
     << SubRegIndices.size()
     << " && \"Subregister index out of bounds\");\n"
        "  LaneBitmask Result;\n"
        "  for (const MaskRolOp *Ops =\n"
        "       &LaneMaskComposeSequences[CompositeSequences[IdxA]];\n"
        "       Ops->Mask.any(); ++Ops) {\n"
        "    LaneBitmask::Type M = LaneMask.getAsInteger();\n"
        "    if (unsigned S = Ops->RotateLeft)\n"
        "      Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - "
        "S)));\n"
        "    else\n"
        "      Result |= LaneBitmask(M);\n"
        "  }\n"
        "  return Result;\n"
        "}\n\n";
}

//
// runMCDesc - Print out MC register descriptions.
//
void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
                                    StringRef FilenamePrefix) {
  emitInclude(FilenamePrefix, "MCDesc.inc", "GET_REGINFO_MC_DESC", MainOS);

  emitSourceFileHeader("MC Register Information", OS);

  const auto &Regs = RegBank.getRegisters();

  auto &SubRegIndices = RegBank.getSubRegIndices();
  // The lists of sub-registers and super-registers go in the same array.  That
  // allows us to share suffixes.
  using RegVec = std::vector<const CodeGenRegister *>;

  // Differentially encoded lists.
  SequenceToOffsetTable<DiffVec> DiffSeqs;
  SmallVector<DiffVec, 4> SubRegLists(Regs.size());
  SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
  SmallVector<DiffVec, 4> RegUnitLists(Regs.size());

  // List of lane masks accompanying register unit sequences.
  SequenceToOffsetTable<MaskVec> LaneMaskSeqs(/*Terminator=*/std::nullopt);
  SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());

  // Keep track of sub-register names as well. These are not differentially
  // encoded.
  using SubRegIdxVec = SmallVector<const CodeGenSubRegIndex *, 4>;
  SequenceToOffsetTable<SubRegIdxVec, deref<std::less<>>> SubRegIdxSeqs(
      /*Terminator=*/std::nullopt);
  SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());

  SequenceToOffsetTable<std::string> RegStrings;

  // Precompute register lists for the SequenceToOffsetTable.
  unsigned i = 0;
  for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
    const auto &Reg = *I;
    RegStrings.add(Reg.getName().str());

    // Compute the ordered sub-register list.
    SetVector<const CodeGenRegister *> SR;
    Reg.addSubRegsPreOrder(SR, RegBank);
    diffEncode(SubRegLists[i], Reg.EnumValue, SR.begin(), SR.end());
    DiffSeqs.add(SubRegLists[i]);

    // Compute the corresponding sub-register indexes.
    SubRegIdxVec &SRIs = SubRegIdxLists[i];
    for (const CodeGenRegister *S : SR)
      SRIs.push_back(Reg.getSubRegIndex(S));
    SubRegIdxSeqs.add(SRIs);

    // Super-registers are already computed.
    const RegVec &SuperRegList = Reg.getSuperRegs();
    diffEncode(SuperRegLists[i], Reg.EnumValue, SuperRegList.begin(),
               SuperRegList.end());
    DiffSeqs.add(SuperRegLists[i]);

    const SparseBitVector<> &RUs = Reg.getNativeRegUnits();
    DiffSeqs.add(diffEncode(RegUnitLists[i], RUs));

    const auto &RUMasks = Reg.getRegUnitLaneMasks();
    MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
    assert(LaneMaskVec.empty());
    llvm::append_range(LaneMaskVec, RUMasks);
    LaneMaskSeqs.add(LaneMaskVec);
  }

  // Compute the final layout of the sequence table.
  DiffSeqs.layout();
  LaneMaskSeqs.layout();
  SubRegIdxSeqs.layout();

  NamespaceEmitter LlvmNS(OS, "llvm");

  StringRef TargetName = Target.getName();

  // Emit the shared table of differential lists.
  OS << "extern const int16_t " << TargetName << "RegDiffLists[] = {\n";
  DiffSeqs.emit(OS, printDiff16);
  OS << "};\n\n";

  // Emit the shared table of regunit lane mask sequences.
  OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
  LaneMaskSeqs.emit(OS, printMask);
  OS << "};\n\n";

  // Emit the table of sub-register indexes.
  OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
  SubRegIdxSeqs.emit(OS, printSubRegIndex);
  OS << "};\n\n";

  // Emit the string table.
  RegStrings.layout();
  RegStrings.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
                                          "RegStrings[]");

  OS << "extern const MCRegisterDesc " << TargetName
     << "RegDesc[] = { // Descriptors\n";
  OS << "  { " << RegStrings.get("") << ", 0, 0, 0, 0, 0, 0, 0 },\n";

  // Emit the register descriptors now.
  i = 0;
  for (const auto &Reg : Regs) {
    unsigned FirstRU = Reg.getNativeRegUnits().find_first();
    unsigned Offset = DiffSeqs.get(RegUnitLists[i]);
    // The value must be kept in sync with MCRegisterInfo.h.
    constexpr unsigned RegUnitBits = 12;
    assert(isUInt<RegUnitBits>(FirstRU) && "Too many regunits");
    assert(isUInt<32 - RegUnitBits>(Offset) && "Offset is too big");
    OS << "  { " << RegStrings.get(Reg.getName().str()) << ", "
       << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
       << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
       << (Offset << RegUnitBits | FirstRU) << ", "
       << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << ", " << Reg.Constant << ", "
       << Reg.Artificial << " },\n";
    ++i;
  }
  OS << "};\n\n"; // End of register descriptors...

  // Emit the table of register unit roots. Each regunit has one or two root
  // registers.
  OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
  for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) {
    ArrayRef<const CodeGenRegister *> Roots = RegBank.getRegUnit(i).getRoots();
    assert(!Roots.empty() && "All regunits must have a root register.");
    assert(Roots.size() <= 2 && "More than two roots not supported yet.");
    OS << "  { ";
    ListSeparator LS;
    for (const CodeGenRegister *R : Roots)
      OS << LS << getQualifiedName(R->TheDef);
    OS << " },\n";
  }
  OS << "};\n\n";

  // Emit the table of register unit intervals.
  if (Target.getRegistersAreIntervals()) {
    OS << "extern const unsigned " << TargetName
       << "RegUnitIntervals[][2] = {\n";
    // Add entry for NoRegister
    OS << "  { 0, 0 },\n";
    for (const CodeGenRegister &Reg : Regs) {
      const auto &Units = Reg.getNativeRegUnits();
      if (Units.empty()) {
        OS << "  { 0, 0 },\n";
      } else {
        unsigned First = Units.find_first();
        unsigned Last = Units.find_last();
        OS << "  { " << First << ", " << Last + 1 << " },\n";
      }
    }
    OS << "};\n\n";
  }

  // Emit register class bit mask tables. The first bit mask emitted for a
  // register class, RC, is the set of sub-classes, including RC itself.
  //
  // If RC has super-registers, also create a list of subreg indices and bit
  // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
  // SuperRC, that satisfies:
  //
  //   For all SuperReg in SuperRC: SuperReg:Idx in RC
  //
  // The 0-terminated list of subreg indices starts at:
  //
  //   RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
  //
  // The corresponding bitmasks follow the sub-class mask in memory. Each
  // mask has RCMaskWords uint32_t entries.
  //
  // Every bit mask present in the list has at least one bit set.

  const auto &RegisterClasses = RegBank.getRegClasses();

  OS << "// Register classes...\n";

  SequenceToOffsetTable<std::string> RegClassStrings;
  // Start indices for per-reg-class info in the respective arrays.
  struct StartIndex {
    unsigned RegIdx;
    unsigned BitSetIdx;
    unsigned SubClassMaskIdx;
    unsigned SuperClassIdx;
    // Not strictly an index, but to avoid recomputation: cache reg set range.
    unsigned MinRegVal;
    unsigned RegSetSize;
  };
  SmallVector<StartIndex> StartIndices;
  StartIndices.reserve(RegisterClasses.size() + 1);
  StartIndices.push_back(StartIndex{0, 0, 0, 0, 0, 0});

  // For compressing the sub-reg index lists.
  using IdxList = std::vector<const CodeGenSubRegIndex *>;
  SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
  SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
  BitVector MaskBV(RegisterClasses.size());
  for (const auto &RC : RegisterClasses) {
    ArrayRef<const Record *> Order = RC.getOrder();
    RegClassStrings.add(RC.getName());

    unsigned MinRegVal = UINT_MAX, MaxRegVal = 0;
    for (const Record *Reg : Order) {
      MinRegVal = std::min(MinRegVal, RegBank.getReg(Reg)->EnumValue);
      MaxRegVal = std::max(MaxRegVal, RegBank.getReg(Reg)->EnumValue);
    }

    unsigned SubClassMaskSize = (RC.getSubClasses().size() + 31) / 32;
    IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
    for (auto &Idx : SubRegIndices) {
      MaskBV.reset();
      RC.getSuperRegClasses(&Idx, MaskBV);
      if (MaskBV.none())
        continue;
      SRIList.push_back(&Idx);
      SubClassMaskSize += (MaskBV.size() + 31) / 32;
    }
    SuperRegIdxSeqs.add(SRIList);

    auto &Last = StartIndices.back();
    Last.MinRegVal = Order.empty() ? 0 : MinRegVal;
    Last.RegSetSize = Order.empty() ? 0 : MaxRegVal - MinRegVal + 1;
    StartIndices.push_back(StartIndex{
        Last.RegIdx + unsigned(Order.size()),
        // Round to next byte size.
        Last.BitSetIdx +
            (Order.empty() ? 0 : ((MaxRegVal - MinRegVal) / 8) + 1),
        Last.SubClassMaskIdx + SubClassMaskSize,
        Last.SuperClassIdx + unsigned(RC.getSuperClasses().size()),
        0, // MinRegVal for next RegClass.
        0, // RegSetSize for next RegClass.
    });
  }

  RegClassStrings.layout();
  RegClassStrings.emitStringLiteralDef(
      OS, Twine("extern const char ") + TargetName + "RegClassStrings[]");

  SuperRegIdxSeqs.layout();

  const auto &Totals = StartIndices.back();
  raw_string_ostream(MCRegisterClassStorageType)
      << "MCRegisterClassStorage<" << RegisterClasses.size() << ", "
      << Totals.RegIdx << ", " << Totals.BitSetIdx << ", "
      << Totals.SubClassMaskIdx << ", " << SuperRegIdxSeqs.size() << ", "
      << Totals.SuperClassIdx << ">";
  OS << "using " << TargetName
     << "RegisterClassStorage = " << MCRegisterClassStorageType << ";\n";
  OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
     << "MCRegisterClassStorage = {\n"
     << "  {\n";

  for (const auto &It : enumerate(RegisterClasses)) {
    const auto &RC = It.value();
    const auto &RCIndices = StartIndices[It.index()];
    uint32_t RegSize = 0;
    if (RC.RSI.isSimple())
      RegSize = RC.RSI.getSimple().RegSize;

    // Helper to generate offsetof macro for relative offset in storage.
    auto GetOff = [&](std::string_view Member,
                      unsigned DataIdx) -> std::string {
      return ("offsetof(" + Twine(TargetName) + "RegisterClassStorage, " +
              Member + "[" + Twine(DataIdx) + "]) - " + Twine(It.index()) +
              " * sizeof(MCRegisterClass)")
          .str();
    };

    OS << "    {\n      " << GetOff("Regs", RCIndices.RegIdx) << ",\n      "
       << GetOff("BitSets", RCIndices.BitSetIdx) << ",\n      "
       << RegClassStrings.get(RC.getName()) << ",\n      " << RegSize
       << ",\n      " << RC.getOrder().size() << ",\n      "
       << RCIndices.MinRegVal << ", /* MinRegVal */\n      "
       << RCIndices.RegSetSize << ", /* RegSetSize */\n      "
       << RC.getQualifiedIdName() << ",\n      "
       << static_cast<unsigned>(RC.CopyCost) << ", /* CopyCost */\n      "
       << (RC.Allocatable ? "true" : "false") << ", /* Allocatable */\n      "
       << (RC.getBaseClassOrder() ? "true" : "false") << ",\n      "
       << GetOff("SubClassMasks", RCIndices.SubClassMaskIdx) << ",\n      "
       << GetOff("SuperRegIdxSeqs",
                 SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]))
       << ",\n      ";
    printMask(OS, RC.LaneMask);
    OS << ",\n      " << (unsigned)RC.AllocationPriority << ",\n      "
       << (RC.GlobalPriority ? "true" : "false") << ",\n      "
       << format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n      "
       << (unsigned)RC.SpillStackID << ", /* SpillStackID */\n      "
       << (RC.HasDisjunctSubRegs ? "true" : "false")
       << ", /* HasDisjunctSubRegs */\n      "
       << (RC.CoveredBySubRegs ? "true" : "false")
       << ", /* CoveredBySubRegs */\n      "
       << GetOff("SuperClasses", RCIndices.SuperClassIdx) << ",\n      "
       << RC.getSuperClasses().size() << "\n    },\n";
  }

  OS << "  },\n  {\n";

  // Emit registers.
  // TODO: these sequences often have overlaps which could be deduplicated.
  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
    ArrayRef<const Record *> Order = RC.getOrder();
    if (Order.empty())
      continue;
    OS << "    /* " << StartIndices[Idx].RegIdx << " */ ";
    for (const Record *Reg : Order)
      OS << getQualifiedName(Reg) << ", ";
    OS << "\n";
  }

  OS << "  },\n  {\n";

  // Emit register bit sets.
  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
    ArrayRef<const Record *> Order = RC.getOrder();
    if (!Order.empty()) {
      OS << "    /* " << StartIndices[Idx].BitSetIdx << " */ ";
      BitVectorEmitter BVE;
      for (const Record *Reg : Order)
        BVE.add(RegBank.getReg(Reg)->EnumValue - StartIndices[Idx].MinRegVal);
      BVE.print(OS);
      OS << "\n";
    }
  }
  OS << "  },\n  {\n";

  // Emit subclass masks.
  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
    OS << "    // " << StartIndices[Idx].SubClassMaskIdx << " " << RC.getName()
       << "\n    ";
    printBitVectorAsHex(OS, RC.getSubClasses(), 32);

    // Emit super-reg class masks for any relevant SubRegIndices that can
    // project into RC.
    for (auto &Idx : SubRegIndices) {
      MaskBV.reset();
      RC.getSuperRegClasses(&Idx, MaskBV);
      if (MaskBV.none())
        continue;
      OS << "\n    ";
      printBitVectorAsHex(OS, MaskBV, 32);
      OS << "// " << Idx.getName();
    }
    OS << "\n";
  }
  OS << "  },\n  {\n";

  // Emit SubRegIdxSeqs.
  SuperRegIdxSeqs.emit(OS, printSubRegIndex);
  OS << "  },\n  {\n";

  // Emit super-class lists.
  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
    ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
    OS << "    /* " << StartIndices[Idx].SuperClassIdx << " " << RC.getName()
       << " */ ";
    for (const auto *Super : Supers)
      OS << Super->getQualifiedIdName() << ", ";
    OS << "\n";
  }

  OS << "  }\n};\n\n";
  OS << "const MCRegisterClass &get" << Target.getName()
     << "MCRegisterClass(unsigned RC) {\n"
     << "  return " << Target.getName()
     << "MCRegisterClassStorage.Classes[RC];\n"
     << "}\n\n";

  EmitRegMappingTables(OS, Regs, false);

  // Emit Reg encoding table
  OS << "extern const uint16_t " << TargetName;
  OS << "RegEncodingTable[] = {\n";
  // Add entry for NoRegister
  OS << "  0,\n";
  for (const auto &RE : Regs) {
    const Record *Reg = RE.TheDef;
    const BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
    uint64_t Value = BI->convertKnownBitsToInt();
    OS << "  " << Value << ",\n";
  }
  OS << "};\n"; // End of HW encoding table

  // MCRegisterInfo initialization routine.
  OS << "static inline void Init" << TargetName
     << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
     << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) "
        "{\n"
     << "  RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
     << Regs.size() + 1 << ", RA, PC, " << TargetName
     << "MCRegisterClassStorage.Classes, " << RegisterClasses.size() << ", "
     << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", "
     << TargetName << "RegDiffLists, " << TargetName << "LaneMaskLists, "
     << TargetName << "RegStrings, " << TargetName << "RegClassStrings, "
     << TargetName << "SubRegIdxLists, " << (llvm::size(SubRegIndices) + 1)
     << ",\n"
     << TargetName << "RegEncodingTable, "
     << (Target.getRegistersAreIntervals() ? TargetName + "RegUnitIntervals"
                                           : "nullptr")
     << ");\n\n";

  EmitRegMapping(OS, Regs, false);

  OS << "}\n\n";

  // Emit the register by HwMode (if present).
  ArrayRef<const Record *> RegisterByHwModeRecords =
      Records.getAllDerivedDefinitions("RegisterByHwMode");
  if (!RegisterByHwModeRecords.empty()) {
    OS << "// Registers by HwMode\n";
    NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace +
                                        "::RegisterByHwMode");

    unsigned NumModes = Target.getHwModes().getNumModeIds();
    for (const Record *Rec : RegisterByHwModeRecords) {
      RegisterByHwMode RegByMode(Rec, RegBank);
      OS << "LLVM_READONLY MCRegister get" << Rec->getName()
         << "(unsigned HwMode) {\n";
      OS << indent(2) << "switch (HwMode) {\n";
      for (unsigned M = 0; M < NumModes; ++M) {
        if (RegByMode.hasMode(M)) {
          const CodeGenRegister *R = RegByMode.get(M);
          OS << indent(2) << "case " << M << ": return "
             << getQualifiedName(R->TheDef) << "; // "
             << Target.getHwModes().getModeName(M, true) << "\n";
        }
      }
      OS << indent(2)
         << "default: llvm_unreachable(\"Unhandled HwMode for Register "
         << Rec->getName() << "\");\n"
         << indent(2) << "}\n"
         << "}\n";
    }
  }
}

void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
                                          StringRef FilenamePrefix) {
  emitInclude(FilenamePrefix, "Header.inc", "GET_REGINFO_HEADER", MainOS);

  emitSourceFileHeader("Register Information Header Fragment", OS);

  const std::string &TargetName = Target.getName().str();
  std::string ClassName = TargetName + "GenRegisterInfo";

  OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";

  NamespaceEmitter LlvmNS(OS, "llvm");

  OS << "class " << TargetName << "FrameLowering;\n\n";

  OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
     << "MCRegisterClassStorage;\n\n";

  OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
     << "  explicit " << ClassName
     << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
     << "      unsigned PC = 0, unsigned HwMode = 0);\n";
  if (!RegBank.getSubRegIndices().empty()) {
    OS << "  unsigned composeSubRegIndicesImpl"
       << "(unsigned, unsigned) const override;\n"
       << "  unsigned reverseComposeSubRegIndicesImpl"
       << "(unsigned, unsigned) const override;\n"
       << "  LaneBitmask composeSubRegIndexLaneMaskImpl"
       << "(unsigned, LaneBitmask) const override;\n"
       << "  LaneBitmask reverseComposeSubRegIndexLaneMaskImpl"
       << "(unsigned, LaneBitmask) const override;\n"
       << "  const TargetRegisterClass *getSubClassWithSubReg"
       << "(const TargetRegisterClass *, unsigned) const override;\n"
       << "  const TargetRegisterClass *getSubRegisterClass"
       << "(const TargetRegisterClass *, unsigned) const override;\n";
  }
  OS << "  const RegClassWeight &getRegClassWeight("
     << "const TargetRegisterClass *RC) const override;\n"
     << "  unsigned getRegUnitWeight(MCRegUnit RegUnit) const override;\n"
     << "  unsigned getNumRegPressureSets() const override;\n"
     << "  const char *getRegPressureSetName(unsigned Idx) const override;\n"
     << "  unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
        "Idx) const override;\n"
     << "  const TargetRegisterClass *getLargestRegClassForRegPressureSet("
        "unsigned Idx) const override;\n"
     << "  const int *getRegClassPressureSets("
     << "const TargetRegisterClass *RC) const override;\n"
     << "  const int *getRegUnitPressureSets("
     << "MCRegUnit RegUnit) const override;\n"
     << "  ArrayRef<const char *> getRegMaskNames() const override;\n"
     << "  ArrayRef<const uint32_t *> getRegMasks() const override;\n"
     << "  bool isGeneralPurposeRegister(const MachineFunction &, "
     << "MCRegister) const override;\n"
     << "  bool isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
     << " const override;\n"
     << "  bool isFixedRegister(const MachineFunction &, "
     << "MCRegister) const override;\n"
     << "  bool isArgumentRegister(const MachineFunction &, "
     << "MCRegister) const override;\n"
     << "  bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"
     << "  /// Devirtualized TargetFrameLowering.\n"
     << "  static const " << TargetName << "FrameLowering *getFrameLowering(\n"
     << "      const MachineFunction &MF);\n";

  const auto &RegisterClasses = RegBank.getRegClasses();
  if (llvm::any_of(RegisterClasses,
                   [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
    OS << "   ArrayRef<MCPhysReg> getRawAllocationOrder("
          "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
          "const override;\n";
  }
  if (llvm::any_of(RegisterClasses,
                   [](const auto &RC) { return RC.getBaseClassOrder(); })) {
    OS << "  const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "
          "const override;\n";
  }
  if (!RegisterClasses.empty()) {
    OS << "  const TargetRegisterClass *getMinimalPhysRegClass("
          "MCRegister Reg) const override;\n";
  }

  OS << "};\n\n";

  if (!RegisterClasses.empty()) {
    NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace);
    OS << "// Register classes\n";

    for (const auto &RC : RegisterClasses) {
      // Output the extern for the instance.
      OS << "static constexpr const TargetRegisterClass &" << RC.getName()
         << "RegClass = " << TargetName << "MCRegisterClassStorage.Classes["
         << RC.EnumValue << "];\n";
    }
  }
}

//
// runTargetDesc - Output the target register and register file descriptions.
//
void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
                                        StringRef FilenamePrefix) {
  emitInclude(FilenamePrefix, "TargetDesc.inc", "GET_REGINFO_TARGET_DESC",
              MainOS);

  emitSourceFileHeader("Target Register and Register Classes Information", OS);

  NamespaceEmitter LlvmNS(OS, "llvm");

  // Get access to MCRegisterClass data.
  OS << "extern const " << MCRegisterClassStorageType << " " << Target.getName()
     << "MCRegisterClassStorage;\n";

  // Start out by emitting each of the register classes.
  const auto &RegisterClasses = RegBank.getRegClasses();
  const auto &SubRegIndices = RegBank.getSubRegIndices();

  // Collect all registers belonging to any allocatable class.
  std::set<const Record *> AllocatableRegs;

  // Collect allocatable registers.
  for (const auto &RC : RegisterClasses) {
    ArrayRef<const Record *> Order = RC.getOrder();

    if (RC.Allocatable)
      AllocatableRegs.insert(Order.begin(), Order.end());
  }

  const CodeGenHwModes &CGH = Target.getHwModes();
  unsigned NumModes = CGH.getNumModeIds();
  StringRef TargetName = Target.getName();

  // Build a shared array of value types.
  SequenceToOffsetTable<std::vector<MVT>> VTSeqs(
      /*Terminator=*/MVT::Other);
  for (unsigned M = 0; M < NumModes; ++M) {
    for (const auto &RC : RegisterClasses) {
      std::vector<MVT> S;
      for (const ValueTypeByHwMode &VVT : RC.VTs)
        if (VVT.hasDefault() || VVT.hasMode(M))
          S.push_back(VVT.get(M));
      VTSeqs.add(S);
    }
  }
  VTSeqs.layout();
  OS << "\nstatic const MVT::SimpleValueType " << TargetName
     << "VTLists[] = {\n";
  VTSeqs.emit(OS, printSimpleValueType);
  OS << "};\n";

  // Emit SubRegIndex names, skipping 0.
  SequenceToOffsetTable<std::string> SubRegIndexStrings;
  for (const auto &Idx : SubRegIndices)
    SubRegIndexStrings.add(Idx.getName());
  SubRegIndexStrings.layout();

  SubRegIndexStrings.emitStringLiteralDef(OS, Twine("static constexpr char ") +
                                                  TargetName +
                                                  "SubRegIndexStrings[]");

  OS << "\nstatic constexpr uint32_t " << TargetName
     << "SubRegIndexNameOffsets[] = {\n";
  for (const auto &Idx : SubRegIndices)
    OS << "  " << SubRegIndexStrings.get(Idx.getName()) << ", \n";
  if (SubRegIndices.empty())
    OS << "  /* dummy */ 0\n";
  OS << "};\n\n";

  // Emit the table of sub-register index sizes.
  OS << "static const TargetRegisterInfo::SubRegCoveredBits " << TargetName
     << "SubRegIdxRangeTable[] = {\n";
  for (unsigned M = 0; M < NumModes; ++M) {
    OS << "  { " << (uint32_t)-1 << ", " << (uint32_t)-1 << " },\n";
    for (const auto &Idx : SubRegIndices) {
      const SubRegRange &Range = Idx.Range.get(M);
      OS << "  { " << Range.Offset << ", " << Range.Size << " },\t// "
         << Idx.getName() << "\n";
    }
  }
  OS << "};\n\n";

  // Emit SubRegIndex lane masks, including 0.
  OS << "\nstatic const LaneBitmask " << TargetName
     << "SubRegIndexLaneMaskTable[] = {\n  "
        "LaneBitmask::getAll(),\n";
  for (const auto &Idx : SubRegIndices) {
    printMask(OS << "  ", Idx.LaneMask);
    OS << ", // " << Idx.getName() << '\n';
  }
  OS << " };\n\n";

  OS << "\n";

  // Now that all of the structs have been emitted, emit the instances.
  if (!RegisterClasses.empty()) {
    OS << "\nstatic const TargetRegisterInfo::RegClassInfo " << TargetName
       << "RegClassInfos[]" << " = {\n";
    for (unsigned M = 0; M < NumModes; ++M) {
      unsigned EV = 0;
      OS << "  // Mode = " << M << " ("
         << CGH.getModeName(M, /*IncludeDefault=*/true) << ")\n";
      for (const auto &RC : RegisterClasses) {
        assert(RC.EnumValue == EV && "Unexpected order of register classes");
        ++EV;
        (void)EV;
        const RegSizeInfo &RI = RC.RSI.get(M);
        OS << "  { " << RI.RegSize << ", " << RI.SpillSize << ", "
           << RI.SpillAlignment;
        std::vector<MVT> VTs;
        for (const ValueTypeByHwMode &VVT : RC.VTs)
          if (VVT.hasDefault() || VVT.hasMode(M))
            VTs.push_back(VVT.get(M));
        OS << ", /*" << TargetName << "VTLists+*/" << VTSeqs.get(VTs)
           << " },    // " << RC.getName() << '\n';
      }
    }
    OS << "};\n";

    // Emit methods.
    for (const auto &RC : RegisterClasses) {
      if (!RC.AltOrderSelect.empty()) {
        OS << "\nstatic inline unsigned " << RC.getName()
           << "AltOrderSelect(const MachineFunction &MF, bool Rev) {"
           << RC.AltOrderSelect << "}\n\n"
           << "static ArrayRef<MCPhysReg> " << RC.getName()
           << "GetRawAllocationOrder(const TargetRegisterClass &RC, "
           << "const MachineFunction &MF, bool Rev) {\n";
        for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {
          ArrayRef<const Record *> Elems = RC.getOrder(oi);
          if (!Elems.empty()) {
            OS << "  static const MCPhysReg AltOrder" << oi << "[] = {";
            for (unsigned elem = 0; elem != Elems.size(); ++elem)
              OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
            OS << " };\n";
          }
        }
        OS << "  const ArrayRef<MCPhysReg> Order[] = {\n"
           << "    RC.getRegisters(";
        for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
          if (RC.getOrder(oi).empty())
            OS << "),\n    ArrayRef<MCPhysReg>(";
          else
            OS << "),\n    ArrayRef(AltOrder" << oi;
        OS << ")\n  };\n  const unsigned Select = " << RC.getName()
           << "AltOrderSelect(MF, Rev);\n  assert(Select < "
           << RC.getNumOrders() << ");\n  return Order[Select];\n}\n";
      }
    }
  }

  // Emit extra information about registers.
  const auto &Regs = RegBank.getRegisters();
  unsigned NumRegCosts = 1;
  for (const auto &Reg : Regs)
    NumRegCosts = std::max((size_t)NumRegCosts, Reg.CostPerUse.size());

  std::vector<unsigned> AllRegCostPerUse;
  llvm::BitVector InAllocClass(Regs.size() + 1, false);
  AllRegCostPerUse.insert(AllRegCostPerUse.end(), NumRegCosts, 0);

  // Populate the vector RegCosts with the CostPerUse list of the registers
  // in the order they are read. Have at most NumRegCosts entries for
  // each register. Fill with zero for values which are not explicitly given.
  for (const auto &Reg : Regs) {
    auto Costs = Reg.CostPerUse;
    llvm::append_range(AllRegCostPerUse, Costs);
    if (NumRegCosts > Costs.size())
      AllRegCostPerUse.insert(AllRegCostPerUse.end(),
                              NumRegCosts - Costs.size(), 0);

    if (AllocatableRegs.count(Reg.TheDef))
      InAllocClass.set(Reg.EnumValue);
  }

  // Emit the cost values as a 1D-array after grouping them by their indices,
  // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
  // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
  OS << "\nstatic const uint8_t " << TargetName << "CostPerUseTable[] = { \n";
  for (unsigned int I = 0; I < NumRegCosts; ++I) {
    for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
      OS << AllRegCostPerUse[J] << ", ";
  }
  OS << "};\n\n";

  OS << "\nstatic const bool " << TargetName
     << "InAllocatableClassTable[] = { \n";
  for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
    OS << (InAllocClass[I] ? "true" : "false") << ", ";
  }
  OS << "};\n\n";

  OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
     << "RegInfoDesc = { // Extra Descriptors\n";
  OS << TargetName << "CostPerUseTable, " << NumRegCosts << ", " << TargetName
     << "InAllocatableClassTable";
  OS << "};\n\n"; // End of register descriptors.

  std::string ClassName = Target.getName().str() + "GenRegisterInfo";

  size_t SubRegIndicesSize = llvm::size(SubRegIndices);

  if (!SubRegIndices.empty()) {
    emitComposeSubRegIndices(OS, ClassName);
    emitComposeSubRegIndexLaneMask(OS, ClassName);
  }

  if (!SubRegIndices.empty()) {
    // Emit getSubClassWithSubReg.
    OS << "const TargetRegisterClass *" << ClassName
       << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
       << " const {\n";
    // Use the smallest type that can hold a regclass ID with room for a
    // sentinel.
    const size_t NumRegClasses = RegisterClasses.size();
    const char *RegClassTy = getMinimalTypeForRange(NumRegClasses + 1);
    auto EmitTableLookup = [&]() {
      OS << formatv(R"(
  };
  assert(RC && "Missing regclass");
  if (!Idx) return RC;
  --Idx;
  assert(Idx < {} && "Bad subreg");
  unsigned TV = Table[RC->getID()][Idx];
  return TV ? getRegClass(TV - 1) : nullptr;
})",
                    SubRegIndicesSize);
    };

    OS << formatv("  static constexpr {} Table[{}][{}] = {{\n", RegClassTy,
                  NumRegClasses, SubRegIndicesSize);
    for (const auto &RC : RegisterClasses) {
      OS << "    {\t// " << RC.getName() << "\n";
      for (auto &Idx : SubRegIndices) {
        if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
          OS << "      " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
             << " -> " << SRC->getName() << "\n";
        else
          OS << "      0,\t// " << Idx.getName() << "\n";
      }
      OS << "    },\n";
    }
    EmitTableLookup();

    // Emit getSubRegisterClass.
    OS << "const TargetRegisterClass *" << ClassName
       << "::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx)"
       << " const {\n";

    OS << formatv("  static constexpr {} Table[{}][{}] = {{\n", RegClassTy,
                  NumRegClasses, SubRegIndicesSize);
    for (const auto &RC : RegisterClasses) {
      OS << "    {\t// " << RC.getName() << '\n';
      for (auto &Idx : SubRegIndices) {
        std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
            MatchingSubClass = RC.getMatchingSubClassWithSubRegs(RegBank, &Idx);

        unsigned EnumValue = 0;
        if (MatchingSubClass) {
          CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
          EnumValue = SubRegClass->EnumValue + 1;
        }

        OS << "      " << EnumValue << ",\t// " << RC.getName() << ':'
           << Idx.getName();

        if (MatchingSubClass) {
          CodeGenRegisterClass *SubRegClass = MatchingSubClass->second;
          OS << " -> " << SubRegClass->getName();
        }

        OS << '\n';
      }

      OS << "    },\n";
    }
    EmitTableLookup();
  }

  EmitRegUnitPressure(OS, ClassName);

  if (llvm::any_of(RegisterClasses,
                   [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
    OS << "ArrayRef<MCPhysReg> " << ClassName
       << "::getRawAllocationOrder("
          "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
          "const {\n";
    OS << "  switch (RC.getID()) {\n";
    for (const auto &RC : RegisterClasses) {
      if (RC.AltOrderSelect.empty())
        continue;
      OS << "  case " << RC.getQualifiedIdName() << ":\n"
         << "    return " << RC.getName()
         << "GetRawAllocationOrder(RC, MF, Rev);\n";
      ;
    }
    OS << "  }\n";
    OS << "  return RC.getRegisters();\n";
    OS << "}\n\n";
  }

  // Emit register base class mapper
  if (!RegisterClasses.empty()) {
    // Collect base classes
    SmallVector<const CodeGenRegisterClass *> BaseClasses;
    for (const auto &RC : RegisterClasses) {
      if (RC.getBaseClassOrder())
        BaseClasses.push_back(&RC);
    }
    if (!BaseClasses.empty()) {
      assert(BaseClasses.size() < UINT16_MAX &&
             "Too many base register classes");

      // Apply order
      struct BaseClassOrdering {
        bool operator()(const CodeGenRegisterClass *LHS,
                        const CodeGenRegisterClass *RHS) const {
          return std::pair(*LHS->getBaseClassOrder(), LHS->EnumValue) <
                 std::pair(*RHS->getBaseClassOrder(), RHS->EnumValue);
        }
      };
      llvm::stable_sort(BaseClasses, BaseClassOrdering());

      OS << "\n// Register to base register class mapping\n\n";
      OS << "\n";
      OS << "const TargetRegisterClass *" << ClassName
         << "::getPhysRegBaseClass(MCRegister Reg)"
         << " const {\n";
      OS << "  static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
      OS << "  static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
      OS << "    InvalidRegClassID,  // NoRegister\n";
      for (const CodeGenRegister &Reg : Regs) {
        const CodeGenRegisterClass *BaseRC = nullptr;
        for (const CodeGenRegisterClass *RC : BaseClasses) {
          if (RC->contains(&Reg)) {
            BaseRC = RC;
            break;
          }
        }

        OS << "    "
           << (BaseRC ? BaseRC->getQualifiedIdName() : "InvalidRegClassID")
           << ",  // " << Reg.getName() << "\n";
      }
      OS << "  };\n\n"
            "  assert(Reg < ArrayRef(Mapping).size());\n"
            "  unsigned RCID = Mapping[Reg.id()];\n"
            "  if (RCID == InvalidRegClassID)\n"
            "    return nullptr;\n"
            "  return &"
         << TargetName
         << "MCRegisterClassStorage.Classes[RCID];\n"
            "}\n";
    }
  }

  if (!RegisterClasses.empty()) {
    assert(RegisterClasses.size() < UINT16_MAX &&
           "Too many minimal register classes");

    OS << "\n// Register to minimal register class mapping\n\n";
    OS << "const TargetRegisterClass *" << ClassName
       << "::getMinimalPhysRegClass(MCRegister Reg)" << " const {\n";
    OS << "  static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
    OS << "  static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
    OS << "    InvalidRegClassID,  // NoRegister\n";
    for (const CodeGenRegister &Reg : Regs) {
      const CodeGenRegisterClass *MinimalRC = nullptr;
      for (const auto &RC : RegisterClasses) {
        if (RC.contains(&Reg) && (!MinimalRC || MinimalRC->hasSubClass(&RC)))
          MinimalRC = &RC;
      }

      OS << "    "
         << (MinimalRC ? MinimalRC->getQualifiedIdName() : "InvalidRegClassID")
         << ",  // " << Reg.getName() << "\n";
    }
    OS << "  };\n\n"
          "  assert(Reg < ArrayRef(Mapping).size());\n"
          "  unsigned RCID = Mapping[Reg.id()];\n"
          "  if (RCID == InvalidRegClassID)\n"
          "    return nullptr;\n"
          "  return &"
       << TargetName
       << "MCRegisterClassStorage.Classes[RCID];\n"
          "}\n";
  }

  // Emit the constructor of the class...
  OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
  OS << "extern const int16_t " << TargetName << "RegDiffLists[];\n";
  OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";
  OS << "extern const char " << TargetName << "RegStrings[];\n";
  OS << "extern const char " << TargetName << "RegClassStrings[];\n";
  OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
  OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
  OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
  if (Target.getRegistersAreIntervals())
    OS << "extern const unsigned " << TargetName << "RegUnitIntervals[][2];\n";

  EmitRegMappingTables(OS, Regs, true);

  OS << formatv(R"(
{0}::
{0}(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
    unsigned PC, unsigned HwMode)
  : TargetRegisterInfo(&{1}RegInfoDesc,
      {1}SubRegIndexStrings, {1}SubRegIndexNameOffsets,
      {1}SubRegIdxRangeTable, {1}SubRegIndexLaneMaskTable,

  )",
                ClassName, TargetName);
  printMask(OS, RegBank.CoveringLanes);
  OS << formatv(R"(, {0}RegClassInfos, {0}VTLists, HwMode) {{
  InitMCRegisterInfo({0}RegDesc, {1}, RA, PC,
    &get{0}MCRegisterClass(0), {2}, {0}RegUnitRoots, {3}, {0}RegDiffLists,
    {0}LaneMaskLists, {0}RegStrings, {0}RegClassStrings, {0}SubRegIdxLists, {4},
    {0}RegEncodingTable, {5});

)",
                TargetName, Regs.size() + 1, RegisterClasses.size(),
                RegBank.getNumNativeRegUnits(), SubRegIndicesSize + 1,
                Target.getRegistersAreIntervals()
                    ? TargetName + "RegUnitIntervals"
                    : Twine("nullptr"));
  EmitRegMapping(OS, Regs, true);

  OS << "}\n\n";

  // Emit CalleeSavedRegs information.
  ArrayRef<const Record *> CSRSets =
      Records.getAllDerivedDefinitions("CalleeSavedRegs");
  for (const Record *CSRSet : CSRSets) {
    const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
    assert(Regs && "Cannot expand CalleeSavedRegs instance");

    // Emit the *_SaveList list of callee-saved registers.
    OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { ";
    for (const Record *Reg : *Regs)
      OS << getQualifiedName(Reg) << ", ";
    OS << "0 };\n";

    // Emit the *_RegMask bit mask of call-preserved registers.
    BitVector Covered = RegBank.computeCoveredRegisters(*Regs);

    // Check for an optional OtherPreserved set.
    // Add those registers to RegMask, but not to SaveList.
    if (const DagInit *OPDag =
            dyn_cast<DagInit>(CSRSet->getValueInit("OtherPreserved"))) {
      SetTheory::RecSet OPSet;
      RegBank.getSets().evaluate(OPDag, OPSet, CSRSet->getLoc());
      Covered |= RegBank.computeCoveredRegisters(OPSet.getArrayRef());
    }

    // Add all constant physical registers to the preserved mask:
    SetTheory::RecSet ConstantSet;
    for (const auto &Reg : RegBank.getRegisters()) {
      if (Reg.Constant)
        ConstantSet.insert(Reg.TheDef);
    }
    Covered |= RegBank.computeCoveredRegisters(ConstantSet.getArrayRef());

    OS << "static const uint32_t " << CSRSet->getName() << "_RegMask[] = { ";
    printBitVectorAsHex(OS, Covered, 32);
    OS << "};\n";
  }
  OS << "\n\n";

  OS << "ArrayRef<const uint32_t *> " << ClassName
     << "::getRegMasks() const {\n";
  if (!CSRSets.empty()) {
    OS << "  static const uint32_t *const Masks[] = {\n";
    for (const Record *CSRSet : CSRSets)
      OS << "    " << CSRSet->getName() << "_RegMask,\n";
    OS << "  };\n";
    OS << "  return ArrayRef(Masks);\n";
  } else {
    OS << "  return {};\n";
  }
  OS << "}\n\n";

  const std::list<CodeGenRegisterCategory> &RegCategories =
      RegBank.getRegCategories();
  OS << "bool " << ClassName << "::\n"
     << "isGeneralPurposeRegister(const MachineFunction &MF, "
     << "MCRegister PhysReg) const {\n"
     << "  return\n";
  for (const CodeGenRegisterCategory &Category : RegCategories)
    if (Category.getName() == "GeneralPurposeRegisters") {
      for (const CodeGenRegisterClass *RC : Category.getClasses())
        OS << "      " << RC->getQualifiedName()
           << "RegClass.contains(PhysReg) ||\n";
      break;
    }
  OS << "      false;\n";
  OS << "}\n\n";

  OS << "bool " << ClassName << "::\n"
     << "isGeneralPurposeRegisterClass(const TargetRegisterClass *RC)"
     << " const {\n"
     << "  return\n";
  for (const CodeGenRegisterCategory &Category : RegCategories)
    if (Category.getName() == "GeneralPurposeRegisters") {
      for (const CodeGenRegisterClass *RC : Category.getClasses())
        OS << "      " << RC->getQualifiedName()
           << "RegClass.hasSubClassEq(RC) ||\n";
      break;
    }
  OS << "      false;\n";
  OS << "}\n\n";

  OS << "bool " << ClassName << "::\n"
     << "isFixedRegister(const MachineFunction &MF, "
     << "MCRegister PhysReg) const {\n"
     << "  return\n";
  for (const CodeGenRegisterCategory &Category : RegCategories)
    if (Category.getName() == "FixedRegisters") {
      for (const CodeGenRegisterClass *RC : Category.getClasses())
        OS << "      " << RC->getQualifiedName()
           << "RegClass.contains(PhysReg) ||\n";
      break;
    }
  OS << "      false;\n";
  OS << "}\n\n";

  OS << "bool " << ClassName << "::\n"
     << "isArgumentRegister(const MachineFunction &MF, "
     << "MCRegister PhysReg) const {\n"
     << "  return\n";
  for (const CodeGenRegisterCategory &Category : RegCategories)
    if (Category.getName() == "ArgumentRegisters") {
      for (const CodeGenRegisterClass *RC : Category.getClasses())
        OS << "      " << RC->getQualifiedName()
           << "RegClass.contains(PhysReg) ||\n";
      break;
    }
  OS << "      false;\n";
  OS << "}\n\n";

  OS << "bool " << ClassName << "::\n"
     << "isConstantPhysReg(MCRegister PhysReg) const {\n"
     << "  return\n";
  for (const auto &Reg : Regs)
    if (Reg.Constant)
      OS << "      PhysReg == " << getQualifiedName(Reg.TheDef) << " ||\n";
  OS << "      false;\n";
  OS << "}\n\n";

  OS << "ArrayRef<const char *> " << ClassName
     << "::getRegMaskNames() const {\n";
  if (!CSRSets.empty()) {
    OS << "  static const char *Names[] = {\n";
    for (const Record *CSRSet : CSRSets)
      OS << "    " << '"' << CSRSet->getName() << '"' << ",\n";
    OS << "  };\n";
    OS << "  return ArrayRef(Names);\n";
  } else {
    OS << "  return {};\n";
  }
  OS << "}\n\n";

  OS << "const " << TargetName << "FrameLowering *\n"
     << TargetName
     << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
     << "  return static_cast<const " << TargetName << "FrameLowering *>(\n"
     << "      MF.getSubtarget().getFrameLowering());\n"
     << "}\n\n";
}

TableGenOutputFiles RegisterInfoEmitter::run(StringRef FilenamePrefix) {
  TGTimer &Timer = Records.getTimer();
  Timer.startTimer("Print enums");
  std::string Main;
  raw_string_ostream MainOS(Main);
  std::string Enums;
  raw_string_ostream EnumsOS(Enums);
  runEnums(EnumsOS, MainOS, FilenamePrefix);

  Timer.startTimer("Print MC registers");
  std::string MCDesc;
  raw_string_ostream MCDescOS(MCDesc);
  runMCDesc(MCDescOS, MainOS, FilenamePrefix);

  Timer.startTimer("Print header fragment");
  std::string Header;
  raw_string_ostream HeaderOS(Header);
  runTargetHeader(HeaderOS, MainOS, FilenamePrefix);

  Timer.startTimer("Print target registers");
  std::string TargetDesc;
  raw_string_ostream TargetDescOS(TargetDesc);
  runTargetDesc(TargetDescOS, MainOS, FilenamePrefix);

  if (RegisterInfoDebug)
    debugDump(errs());

  // The suffixes should be in sync with the tablegen function in
  // llvm/cmake/modules/TableGen.cmake.
  return {std::move(Main),
          {{"Enums.inc", Enums},
           {"MCDesc.inc", MCDesc},
           {"Header.inc", Header},
           {"TargetDesc.inc", TargetDesc}}};
}

template <typename InfoTy, typename FnTy>
Printable RegisterInfoEmitter::printByHwMode(const InfoByHwMode<InfoTy> &Info,
                                             FnTy Func) {
  return Printable([&](raw_ostream &OS) {
    if (Info.isSimple()) {
      OS << Func(Info.getSimple());
      return;
    }

    const CodeGenHwModes &CGH = Target.getHwModes();

    OS << "{";
    for (unsigned M = 0, E = CGH.getNumModeIds(); M != E; ++M)
      OS << ' ' << CGH.getModeName(M, /*IncludeDefault=*/true) << ':'
         << Func(Info.get(M));
    OS << " }";
  });
}

void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
  for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
    OS << "RegisterClass " << RC.getName() << ":\n";
    OS << "\tSpillSize: " << printByHwMode(RC.RSI, [](const RegSizeInfo &Info) {
      return Info.SpillSize;
    }) << '\n';
    OS << "\tSpillAlignment: "
       << printByHwMode(
              RC.RSI,
              [](const RegSizeInfo &Info) { return Info.SpillAlignment; })
       << '\n';
    OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
    OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';
    OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
    OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
    OS << "\tAllocatable: " << RC.Allocatable << '\n';
    OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';
    OS << "\tWeight: " << RC.getWeight(RegBank) << '\n';
    OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';
    OS << "\tRegs:";
    for (const CodeGenRegister *R : RC.getMembers()) {
      OS << " " << R->getName();
    }
    OS << '\n';
    OS << "\tSubClasses:";
    const BitVector &SubClasses = RC.getSubClasses();
    for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {
      if (!SubClasses.test(SRC.EnumValue))
        continue;
      OS << " " << SRC.getName();
    }
    OS << '\n';
    OS << "\tSuperClasses:";
    for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {
      OS << " " << SRC->getName();
    }
    OS << '\n';
    if (RC.Artificial)
      OS << "\tArtificial: 1\n";
  }

  for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
    OS << "SubRegIndex " << SRI.getName() << ":\n";
    OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n';
    OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
    OS << "\tOffset: " << printByHwMode(SRI.Range, [](const SubRegRange &Info) {
      return Info.Offset;
    }) << '\n';
    OS << "\tSize: " << printByHwMode(SRI.Range, [](const SubRegRange &Info) {
      return Info.Size;
    }) << '\n';
    if (SRI.Artificial)
      OS << "\tArtificial: 1\n";
  }

  for (const CodeGenRegister &R : RegBank.getRegisters()) {
    OS << "Register " << R.getName() << ":\n";
    OS << "\tCostPerUse: ";
    for (const auto &Cost : R.CostPerUse)
      OS << Cost << " ";
    OS << '\n';
    OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
    OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
    for (auto &[SubIdx, SubReg] : R.getSubRegs()) {
      OS << "\tSubReg " << SubIdx->getName() << " = " << SubReg->getName()
         << '\n';
    }
    for (unsigned U : R.getNativeRegUnits())
      OS << "\tRegUnit " << U << '\n';
    if (R.Artificial)
      OS << "\tArtificial: 1\n";
  }
}

static TableGen::Emitter::MultiFileOptClass<RegisterInfoEmitter>
    X("gen-register-info", "Generate registers and register classes info");
