//===- InstrInfoEmitter.cpp - Generate a Instruction Set 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 the target
// instruction set for the code generator.
//
//===----------------------------------------------------------------------===//

#include "Basic/SequenceToOffsetTable.h"
#include "Common/CodeGenDAGPatterns.h"
#include "Common/CodeGenInstruction.h"
#include "Common/CodeGenRegisters.h"
#include "Common/CodeGenSchedule.h"
#include "Common/CodeGenTarget.h"
#include "Common/PredicateExpander.h"
#include "Common/SubtargetFeatureInfo.h"
#include "Common/Types.h"
#include "TableGenBackends.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/SourceMgr.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/TGTimer.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <map>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

static cl::OptionCategory InstrInfoEmitterCat("Options for -gen-instr-info");
static cl::opt<bool> ExpandMIOperandInfo(
    "instr-info-expand-mi-operand-info",
    cl::desc("Expand operand's MIOperandInfo DAG into suboperands"),
    cl::cat(InstrInfoEmitterCat), cl::init(true));

namespace {

class InstrInfoEmitter {
  const RecordKeeper &Records;
  const CodeGenDAGPatterns CDP;
  const CodeGenSchedModels &SchedModels;

public:
  InstrInfoEmitter(const RecordKeeper &R)
      : Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}

  // run - Output the instruction set description.
  void run(raw_ostream &OS);

private:
  void emitEnums(raw_ostream &OS,
                 ArrayRef<const CodeGenInstruction *> NumberedInstructions);

  using OperandInfoTy = std::vector<std::string>;
  using OperandInfoListTy = std::vector<OperandInfoTy>;
  using OperandInfoMapTy = std::map<OperandInfoTy, unsigned>;

  /// Generate member functions in the target-specific GenInstrInfo class.
  ///
  /// This method is used to custom expand TIIPredicate definitions.
  /// See file llvm/Target/TargetInstPredicates.td for a description of what is
  /// a TIIPredicate and how to use it.
  void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
                            bool ExpandDefinition = true);

  /// Expand TIIPredicate definitions to functions that accept a const MCInst
  /// reference.
  void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);

  /// Write verifyInstructionPredicates methods.
  void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
  void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                  const Record *InstrInfo,
                  std::map<std::vector<const Record *>, unsigned> &EL,
                  const OperandInfoMapTy &OperandInfo, raw_ostream &OS);
  void emitOperandTypeMappings(
      raw_ostream &OS, const CodeGenTarget &Target,
      ArrayRef<const CodeGenInstruction *> NumberedInstructions);
  void emitOperandNameMappings(
      raw_ostream &OS, const CodeGenTarget &Target,
      ArrayRef<const CodeGenInstruction *> TargetInstructions);
  void emitLogicalOperandSizeMappings(
      raw_ostream &OS, StringRef Namespace,
      ArrayRef<const CodeGenInstruction *> TargetInstructions);

  // Operand information.
  unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
                              OperandInfoMapTy &OperandInfoMap);
  void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList);
  OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst);
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Operand Info Emission.
//===----------------------------------------------------------------------===//

InstrInfoEmitter::OperandInfoTy
InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
  OperandInfoTy Result;
  StringRef Namespace = CDP.getTargetInfo().getInstNamespace();

  for (auto &Op : Inst.Operands) {
    // Handle aggregate operands and normal operands the same way by expanding
    // either case into a list of operands for this op.
    std::vector<CGIOperandList::OperandInfo> OperandList;

    // This might be a multiple operand thing. Targets like X86 have registers
    // in their multi-operand operands. It may also be an anonymous operand,
    // which has a single operand, but no declared class for the operand.
    const DagInit *MIOI = Op.MIOperandInfo;

    if (!MIOI || MIOI->getNumArgs() == 0) {
      // Single, anonymous, operand.
      OperandList.push_back(Op);
    } else {
      for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
        OperandList.push_back(Op);

        auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
        OperandList.back().Rec = OpR;
      }
    }

    for (const auto &[OpInfo, Constraint] :
         zip_equal(OperandList, Op.Constraints)) {
      const Record *OpR = OpInfo.Rec;
      std::string Res;

      if (OpR->isSubClassOf("RegisterOperand"))
        OpR = OpR->getValueAsDef("RegClass");

      if (OpR->isSubClassOf("RegClassByHwMode")) {
        Res += Namespace;
        Res += "::";
        Res += OpR->getName();
        Res += ", ";
      } else if (OpR->isSubClassOf("RegisterClass"))
        Res += getQualifiedName(OpR) + "RegClassID, ";
      else if (OpR->isSubClassOf("PointerLikeRegClass"))
        Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
      else
        // -1 means the operand does not have a fixed register class.
        Res += "-1, ";

      // Fill in applicable flags.
      Res += "0";

      if (OpR->isSubClassOf("RegClassByHwMode")) {
        Res += "|(1<<MCOI::LookupRegClassByHwMode)";
      } else if (OpR->isSubClassOf("PointerLikeRegClass")) {
        // Ptr value whose register class is resolved via callback.
        Res += "|(1<<MCOI::LookupPtrRegClass)";
      }

      // Predicate operands.  Check to see if the original unexpanded operand
      // was of type PredicateOp.
      if (Op.Rec->isSubClassOf("PredicateOp"))
        Res += "|(1<<MCOI::Predicate)";

      // Optional def operands.  Check to see if the original unexpanded operand
      // was of type OptionalDefOperand.
      if (Op.Rec->isSubClassOf("OptionalDefOperand"))
        Res += "|(1<<MCOI::OptionalDef)";

      // Branch target operands.  Check to see if the original unexpanded
      // operand was of type BranchTargetOperand.
      if (Op.Rec->isSubClassOf("BranchTargetOperand"))
        Res += "|(1<<MCOI::BranchTarget)";

      // Fill in operand type.
      Res += ", ";
      assert(!Op.OperandType.empty() && "Invalid operand type.");
      Res += Op.OperandType;

      // Fill in constraint info.
      Res += ", ";

      if (Constraint.isNone()) {
        Res += "0";
      } else if (Constraint.isEarlyClobber()) {
        Res += "MCOI_EARLY_CLOBBER";
      } else {
        assert(Constraint.isTied());
        Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
      }

      Result.push_back(Res);
    }
  }

  return Result;
}

unsigned
InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList,
                                     OperandInfoMapTy &OperandInfoMap) {
  const CodeGenTarget &Target = CDP.getTargetInfo();
  unsigned Offset = 0;
  for (const CodeGenInstruction *Inst : Target.getInstructions()) {
    OperandInfoTy OperandInfo = GetOperandInfo(*Inst);
    if (OperandInfoMap.try_emplace(OperandInfo, Offset).second) {
      OperandInfoList.push_back(OperandInfo);
      Offset += OperandInfo.size();
    }
  }
  return Offset;
}

void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
                                       OperandInfoListTy &OperandInfoList) {
  unsigned Offset = 0;
  for (auto &OperandInfo : OperandInfoList) {
    OS << "    /* " << Offset << " */";
    for (auto &Info : OperandInfo)
      OS << " { " << Info << " },";
    OS << '\n';
    Offset += OperandInfo.size();
  }
}

static void emitGetInstructionIndexForOpLookup(
    raw_ostream &OS, const MapVector<SmallVector<int>, unsigned> &OperandMap,
    ArrayRef<unsigned> InstructionIndex) {
  StringRef Type = OperandMap.size() <= UINT8_MAX + 1 ? "uint8_t" : "uint16_t";
  OS << "LLVM_READONLY static " << Type
     << " getInstructionIndexForOpLookup(uint16_t Opcode) {\n"
        "  static constexpr "
     << Type << " InstructionIndex[] = {";
  for (auto [TableIndex, Entry] : enumerate(InstructionIndex))
    OS << (TableIndex % 16 == 0 ? "\n    " : " ") << Entry << ',';
  OS << "\n  };\n"
        "  return InstructionIndex[Opcode];\n"
        "}\n";
}

static void
emitGetNamedOperandIdx(raw_ostream &OS,
                       const MapVector<SmallVector<int>, unsigned> &OperandMap,
                       unsigned MaxOperandNo, unsigned NumOperandNames) {
  OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
        "Name) {\n";
  OS << "  assert(Name != OpName::NUM_OPERAND_NAMES);\n";
  if (!NumOperandNames) {
    // There are no operands, so no need to emit anything
    OS << "  return -1;\n}\n";
    return;
  }
  assert(MaxOperandNo <= INT16_MAX &&
         "Too many operands for the operand name -> index table");
  StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
  OS << "  static constexpr " << Type << " OperandMap[][" << NumOperandNames
     << "] = {\n";
  for (const auto &[OpList, _] : OperandMap) {
    // Emit a row of the OperandMap table.
    OS << "    {";
    for (unsigned ID = 0; ID < NumOperandNames; ++ID)
      OS << (ID < OpList.size() ? OpList[ID] : -1) << ", ";
    OS << "},\n";
  }
  OS << "  };\n";

  OS << "  unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);\n"
        "  return OperandMap[InstrIdx][(unsigned)Name];\n"
        "}\n";
}

static void
emitGetOperandIdxName(raw_ostream &OS,
                      const MapVector<StringRef, unsigned> &OperandNameToID,
                      const MapVector<SmallVector<int>, unsigned> &OperandMap,
                      unsigned MaxNumOperands, unsigned NumOperandNames) {
  OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t Idx) "
        "{\n";
  OS << "  assert(Idx >= 0 && Idx < " << MaxNumOperands << ");\n";
  if (!MaxNumOperands) {
    // There are no operands, so no need to emit anything
    OS << "  return -1;\n}\n";
    return;
  }
  OS << "  static constexpr OpName OperandMap[][" << MaxNumOperands
     << "] = {\n";
  for (const auto &[OpList, _] : OperandMap) {
    SmallVector<unsigned> IDs(MaxNumOperands, NumOperandNames);
    for (const auto &[ID, Idx] : enumerate(OpList)) {
      if (Idx >= 0)
        IDs[Idx] = ID;
    }
    // Emit a row of the OperandMap table. Map operand indices to enum values.
    OS << "    {";
    for (unsigned ID : IDs) {
      if (ID == NumOperandNames)
        OS << "OpName::NUM_OPERAND_NAMES, ";
      else
        OS << "OpName::" << OperandNameToID.getArrayRef()[ID].first << ", ";
    }
    OS << "},\n";
  }
  OS << "  };\n";

  OS << "  unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);\n"
        "  return OperandMap[InstrIdx][(unsigned)Idx];\n"
        "}\n";
}

/// Generate a table and function for looking up the indices of operands by
/// name.
///
/// This code generates:
/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
///   for each operand name.
/// - A 2-dimensional table for mapping OpName enum values to operand indices.
/// - A function called getNamedOperandIdx(uint16_t Opcode, OpName Name)
///   for looking up the operand index for an instruction, given a value from
///   OpName enum
/// - A 2-dimensional table for mapping operand indices to OpName enum values.
/// - A function called getOperandIdxName(uint16_t Opcode, int16_t Idx)
///   for looking up the OpName enum for an instruction, given the operand
///   index. This is the inverse of getNamedOperandIdx().
///
/// Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
/// we can just skip them. Hence accept just the TargetInstructions.
void InstrInfoEmitter::emitOperandNameMappings(
    raw_ostream &OS, const CodeGenTarget &Target,
    ArrayRef<const CodeGenInstruction *> TargetInstructions) {
  // Map of operand names to their ID.
  MapVector<StringRef, unsigned> OperandNameToID;

  /// A key in this map is a vector mapping OpName ID values to instruction
  /// operand indices or -1 (but without any trailing -1 values which will be
  /// added later). The corresponding value in this map is the index of that row
  /// in the emitted OperandMap table. This map helps to unique entries among
  /// instructions that have identical OpName -> Operand index mapping.
  MapVector<SmallVector<int>, unsigned> OperandMap;

  // Max operand index seen.
  unsigned MaxOperandNo = 0;

  // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
  // add a dummy map entry for them.
  OperandMap.try_emplace({}, 0);
  unsigned FirstTargetVal = TargetInstructions.front()->EnumVal;
  SmallVector<unsigned> InstructionIndex(FirstTargetVal, 0);
  for (const CodeGenInstruction *Inst : TargetInstructions) {
    if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) {
      InstructionIndex.push_back(0);
      continue;
    }
    SmallVector<int> OpList;
    for (const auto &Info : Inst->Operands) {
      unsigned ID =
          OperandNameToID.try_emplace(Info.Name, OperandNameToID.size())
              .first->second;
      OpList.resize(std::max((unsigned)OpList.size(), ID + 1), -1);
      OpList[ID] = Info.MIOperandNo;
      MaxOperandNo = std::max(MaxOperandNo, Info.MIOperandNo);
    }
    auto [It, Inserted] =
        OperandMap.try_emplace(std::move(OpList), OperandMap.size());
    InstructionIndex.push_back(It->second);
  }

  const size_t NumOperandNames = OperandNameToID.size();
  const unsigned MaxNumOperands = MaxOperandNo + 1;

  const SmallString<32> Namespace({"llvm::", Target.getInstNamespace()});
  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_ENUM");
    NamespaceEmitter NS(OS, Namespace);

    assert(NumOperandNames <= UINT16_MAX &&
           "Too many operands for the operand index -> name table");
    StringRef EnumType = getMinimalTypeForRange(NumOperandNames);
    OS << "enum class OpName : " << EnumType << " {\n";
    for (const auto &[Op, I] : OperandNameToID)
      OS << "  " << Op << " = " << I << ",\n";
    OS << "  NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
    OS << "}; // enum class OpName\n\n";

    OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
          "Name);\n";
    OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t "
          "Idx);\n";
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_NAMED_OPS");
    NamespaceEmitter NS(OS, Namespace);
    emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);

    emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
    emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
                          NumOperandNames);
  }
}

/// Generate an enum for all the operand types for this target, under the
/// llvm::TargetNamespace::OpTypes namespace.
/// Operand types are all definitions derived of the Operand Target.td class.
///
void InstrInfoEmitter::emitOperandTypeMappings(
    raw_ostream &OS, const CodeGenTarget &Target,
    ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
  StringRef Namespace = Target.getInstNamespace();

  // These generated functions are used only by the X86 target
  // (in bolt/lib/Target/X86/X86MCPlusBuilder.cpp). So emit them only
  // for X86.
  if (Namespace != "X86")
    return;

  ArrayRef<const Record *> Operands =
      Records.getAllDerivedDefinitions("Operand");
  ArrayRef<const Record *> RegisterOperands =
      Records.getAllDerivedDefinitions("RegisterOperand");
  ArrayRef<const Record *> RegisterClasses =
      Records.getAllDerivedDefinitions("RegisterClass");

  unsigned EnumVal = 0;

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_TYPES_ENUM");
    NamespaceEmitter NS(OS, ("llvm::" + Namespace + "::OpTypes").str());
    OS << "enum OperandType {\n";

    for (ArrayRef<const Record *> RecordsToAdd :
         {Operands, RegisterOperands, RegisterClasses}) {
      for (const Record *Op : RecordsToAdd) {
        if (!Op->isAnonymous())
          OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
        ++EnumVal;
      }
    }

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

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_TYPE");
    NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
    OS << "LLVM_READONLY\n";
    OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
    auto getInstrName = [&](int I) -> StringRef {
      return NumberedInstructions[I]->getName();
    };
    // TODO: Factor out duplicate operand lists to compress the tables.
    std::vector<size_t> OperandOffsets;
    std::vector<const Record *> OperandRecords;
    size_t CurrentOffset = 0;
    for (const CodeGenInstruction *Inst : NumberedInstructions) {
      OperandOffsets.push_back(CurrentOffset);
      for (const auto &Op : Inst->Operands) {
        const DagInit *MIOI = Op.MIOperandInfo;
        if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
          // Single, anonymous, operand.
          OperandRecords.push_back(Op.Rec);
          ++CurrentOffset;
        } else {
          for (const Init *Arg : MIOI->getArgs()) {
            OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
            ++CurrentOffset;
          }
        }
      }
    }

    // Emit the table of offsets (indexes) into the operand type table.
    // Size the unsigned integer offset to save space.
    assert(OperandRecords.size() <= UINT32_MAX &&
           "Too many operands for offset table");
    OS << "  static constexpr "
       << getMinimalTypeForRange(OperandRecords.size());
    OS << " Offsets[] = {\n";
    for (const auto &[Idx, Offset] : enumerate(OperandOffsets))
      OS << "    " << Offset << ", // " << getInstrName(Idx) << '\n';
    OS << "  };\n";

    // Add an entry for the end so that we don't need to special case it below.
    OperandOffsets.push_back(OperandRecords.size());

    // Emit the actual operand types in a flat table.
    // Size the signed integer operand type to save space.
    assert(EnumVal <= INT16_MAX &&
           "Too many operand types for operand types table");
    OS << "\n  using namespace OpTypes;\n";
    OS << "  static";
    OS << (EnumVal <= INT8_MAX ? " constexpr int8_t" : " constexpr int16_t");
    OS << " OpcodeOperandTypes[] = {";
    size_t CurOffset = 0;
    for (auto [Idx, OpR] : enumerate(OperandRecords)) {
      // We print each Opcode's operands in its own row.
      if (Idx == OperandOffsets[CurOffset]) {
        OS << "\n    /* " << getInstrName(CurOffset) << " */\n    ";
        while (OperandOffsets[++CurOffset] == Idx)
          OS << "/* " << getInstrName(CurOffset) << " */\n    ";
      }
      if ((OpR->isSubClassOf("Operand") ||
           OpR->isSubClassOf("RegisterOperand") ||
           OpR->isSubClassOf("RegisterClass")) &&
          !OpR->isAnonymous())
        OS << OpR->getName();
      else
        OS << -1;
      OS << ", ";
    }
    OS << "\n  };\n";

    OS << "  return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
    OS << "}\n";
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MEM_OPERAND_SIZE");
    NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());

    OS << "LLVM_READONLY\n";
    OS << "static int getMemOperandSize(int OpType) {\n";
    OS << "  switch (OpType) {\n";
    std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
    for (const Record *Op : Operands) {
      if (!Op->isSubClassOf("X86MemOperand"))
        continue;
      if (int Size = Op->getValueAsInt("Size"))
        SizeToOperandName[Size].push_back(Op->getName());
    }
    OS << "  default: return 0;\n";
    for (const auto &[Size, OperandNames] : SizeToOperandName) {
      for (const StringRef &OperandName : OperandNames)
        OS << "  case OpTypes::" << OperandName << ":\n";
      OS << "    return " << Size << ";\n\n";
    }
    OS << "  }\n}\n";
  }
}

// Fixed/Predefined instructions do not have UseLogicalOperandMappings
// enabled, so we can just skip them. Hence accept TargetInstructions.
void InstrInfoEmitter::emitLogicalOperandSizeMappings(
    raw_ostream &OS, StringRef Namespace,
    ArrayRef<const CodeGenInstruction *> TargetInstructions) {
  std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
  std::map<unsigned, std::vector<std::string>> InstMap;

  size_t LogicalOpListSize = 0U;
  std::vector<unsigned> LogicalOpList;

  for (const auto *Inst : TargetInstructions) {
    if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
      continue;

    LogicalOpList.clear();
    llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList),
                    [](const CGIOperandList::OperandInfo &Op) -> unsigned {
                      auto *MIOI = Op.MIOperandInfo;
                      if (!MIOI || MIOI->getNumArgs() == 0)
                        return 1;
                      return MIOI->getNumArgs();
                    });
    LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize);

    auto I =
        LogicalOpSizeMap.try_emplace(LogicalOpList, LogicalOpSizeMap.size())
            .first;
    InstMap[I->second].push_back((Namespace + "::" + Inst->getName()).str());
  }

  IfDefEmitter IfDef(OS, "GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP");
  NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
  OS << "LLVM_READONLY static unsigned\n";
  OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
  if (!InstMap.empty()) {
    std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
        LogicalOpSizeMap.size());
    for (auto &P : LogicalOpSizeMap) {
      LogicalOpSizeList[P.second] = &P.first;
    }
    OS << "  static const unsigned SizeMap[][" << LogicalOpListSize
       << "] = {\n";
    for (auto &R : LogicalOpSizeList) {
      const auto &Row = *R;
      OS << "   {";
      int i;
      for (i = 0; i < static_cast<int>(Row.size()); ++i) {
        OS << Row[i] << ", ";
      }
      for (; i < static_cast<int>(LogicalOpListSize); ++i) {
        OS << "0, ";
      }
      OS << "}, \n";
    }
    OS << "  };\n";

    OS << "  switch (Opcode) {\n";
    OS << "  default: return LogicalOpIdx;\n";
    for (auto &P : InstMap) {
      auto OpMapIdx = P.first;
      const auto &Insts = P.second;
      for (const auto &Inst : Insts) {
        OS << "  case " << Inst << ":\n";
      }
      OS << "    return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
    }
    OS << "  }\n";
  } else {
    OS << "  return LogicalOpIdx;\n";
  }
  OS << "}\n";

  OS << "LLVM_READONLY static inline unsigned\n";
  OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
  OS << "  auto S = 0U;\n";
  OS << "  for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
  OS << "    S += getLogicalOperandSize(Opcode, i);\n";
  OS << "  return S;\n";
  OS << "}\n";
}

void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
                                             StringRef TargetName) {
  ArrayRef<const Record *> TIIPredicates =
      Records.getAllDerivedDefinitions("TIIPredicate");

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPER_DECLS");
    NamespaceEmitter LlvmNS(OS, "llvm");
    OS << "class MCInst;\n";
    OS << "class FeatureBitset;\n\n";

    NamespaceEmitter TargetNS(OS, (TargetName + "_MC").str());
    for (const Record *Rec : TIIPredicates)
      OS << "bool " << Rec->getValueAsString("FunctionName")
         << "(const MCInst &MI);\n";

    OS << "void verifyInstructionPredicates(unsigned Opcode, const "
          "FeatureBitset "
          "&Features);\n";
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPERS");
    NamespaceEmitter NS(OS, ("llvm::" + TargetName + "_MC").str());

    PredicateExpander PE(TargetName);
    PE.setExpandForMC(true);

    for (const Record *Rec : TIIPredicates) {
      OS << "bool " << Rec->getValueAsString("FunctionName");
      OS << "(const MCInst &MI) {\n";

      OS << PE.getIndent();
      PE.expandStatement(OS, Rec->getValueAsDef("Body"));
      OS << "\n}\n\n";
    }
  }
}

static std::string
getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset) {
  std::string Name = "CEFBS";
  for (const Record *Feature : FeatureBitset)
    Name += ("_" + Feature->getName()).str();
  return Name;
}

void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
                                           const CodeGenTarget &Target) {
  const auto &All = SubtargetFeatureInfo::getAll(Records);
  SubtargetFeatureInfoMap SubtargetFeatures;
  SubtargetFeatures.insert(All.begin(), All.end());

  OS << "#if (defined(ENABLE_INSTR_PREDICATE_VERIFIER) && !defined(NDEBUG)) "
     << "||\\\n"
     << "    defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
     << "#define GET_COMPUTE_FEATURES\n"
     << "#endif\n";
  std::string Namespace = ("llvm::" + Target.getName() + "_MC").str();
  {
    IfDefEmitter IfDef(OS, "GET_COMPUTE_FEATURES");
    NamespaceEmitter NS(OS, Namespace);

    // Emit the subtarget feature enumeration.
    SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
                                                             OS);
    // Emit the available features compute function.
    OS << "inline ";
    SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
        Target.getName(), "", "computeAvailableFeatures", SubtargetFeatures,
        OS);

    std::vector<std::vector<const Record *>> FeatureBitsets;
    for (const CodeGenInstruction *Inst : Target.getInstructions()) {
      FeatureBitsets.emplace_back();
      for (const Record *Predicate :
           Inst->TheDef->getValueAsListOfDefs("Predicates")) {
        const auto &I = SubtargetFeatures.find(Predicate);
        if (I != SubtargetFeatures.end())
          FeatureBitsets.back().push_back(I->second.TheDef);
      }
    }

    llvm::sort(FeatureBitsets, [&](ArrayRef<const Record *> A,
                                   ArrayRef<const Record *> B) {
      if (A.size() < B.size())
        return true;
      if (A.size() > B.size())
        return false;
      for (auto Pair : zip(A, B)) {
        if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
          return true;
        if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
          return false;
      }
      return false;
    });
    FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());
    OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
       << "  enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
       << "    CEFBS_None,\n";
    for (const auto &FeatureBitset : FeatureBitsets) {
      if (FeatureBitset.empty())
        continue;
      OS << "    " << getNameForFeatureBitset(FeatureBitset) << ",\n";
    }
    OS << "  };\n\n"
       << "  static constexpr FeatureBitset FeatureBitsets[] = {\n"
       << "    {}, // CEFBS_None\n";
    for (const auto &FeatureBitset : FeatureBitsets) {
      if (FeatureBitset.empty())
        continue;
      OS << "    {";
      for (const auto &Feature : FeatureBitset) {
        const auto &I = SubtargetFeatures.find(Feature);
        assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
        OS << I->second.getEnumBitName() << ", ";
      }
      OS << "},\n";
    }
    OS << "  };\n"
       << "  static constexpr " << getMinimalTypeForRange(FeatureBitsets.size())
       << " RequiredFeaturesRefs[] = {\n";
    ArrayRef<const CodeGenInstruction *> NumberedInstructions =
        Target.getInstructions();
    for (const CodeGenInstruction *Inst : NumberedInstructions) {
      OS << "    CEFBS";
      unsigned NumPredicates = 0;
      for (const Record *Predicate :
           Inst->TheDef->getValueAsListOfDefs("Predicates")) {
        const auto &I = SubtargetFeatures.find(Predicate);
        if (I != SubtargetFeatures.end()) {
          OS << '_' << I->second.TheDef->getName();
          NumPredicates++;
        }
      }
      if (!NumPredicates)
        OS << "_None";
      OS << ", // " << Inst->getName() << '\n';
    }
    OS << "  };\n\n"
       << "  assert(Opcode < " << NumberedInstructions.size() << ");\n"
       << "  return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
       << "}\n\n";
  } // end scope for GET_COMPUTE_FEATURES

  {
    IfDefEmitter IfDef(OS, "GET_AVAILABLE_OPCODE_CHECKER");
    NamespaceEmitter NS(OS, Namespace);
    OS << "bool isOpcodeAvailable("
       << "unsigned Opcode, const FeatureBitset &Features) {\n"
       << "  FeatureBitset AvailableFeatures = "
       << "computeAvailableFeatures(Features);\n"
       << "  FeatureBitset RequiredFeatures = "
       << "computeRequiredFeatures(Opcode);\n"
       << "  FeatureBitset MissingFeatures =\n"
       << "      (AvailableFeatures & RequiredFeatures) ^\n"
       << "      RequiredFeatures;\n"
       << "  return !MissingFeatures.any();\n"
       << "}\n";
  }

  {
    IfDefEmitter IfDef(OS, "ENABLE_INSTR_PREDICATE_VERIFIER");
    OS << "#include <sstream>\n\n";
    NamespaceEmitter NS(OS, Namespace);
    // Emit the name table for error messages.
    OS << "#ifndef NDEBUG\n";
    SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
    OS << "#endif // NDEBUG\n\n";
    // Emit the predicate verifier.
    OS << "void verifyInstructionPredicates(\n"
       << "    unsigned Opcode, const FeatureBitset &Features) {\n"
       << "#ifndef NDEBUG\n";
    OS << "  FeatureBitset AvailableFeatures = "
          "computeAvailableFeatures(Features);\n";
    OS << "  FeatureBitset RequiredFeatures = "
       << "computeRequiredFeatures(Opcode);\n";
    OS << "  FeatureBitset MissingFeatures =\n"
       << "      (AvailableFeatures & RequiredFeatures) ^\n"
       << "      RequiredFeatures;\n"
       << "  if (MissingFeatures.any()) {\n"
       << "    std::ostringstream Msg;\n"
       << "    Msg << \"Attempting to emit \" << &" << Target.getName()
       << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
       << "        << \" instruction but the \";\n"
       << "    for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
       << "      if (MissingFeatures.test(i))\n"
       << "        Msg << SubtargetFeatureNames[i] << \" \";\n"
       << "    Msg << \"predicate(s) are not met\";\n"
       << "    report_fatal_error(Msg.str().c_str());\n"
       << "  }\n"
       << "#endif // NDEBUG\n";
    OS << "}\n";
  }
}

void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
                                            StringRef TargetName,
                                            bool ExpandDefinition) {
  ArrayRef<const Record *> TIIPredicates =
      Records.getAllDerivedDefinitions("TIIPredicate");
  if (TIIPredicates.empty())
    return;

  PredicateExpander PE(TargetName);
  PE.setExpandForMC(false);

  for (const Record *Rec : TIIPredicates) {
    OS << (ExpandDefinition ? "" : "static ") << "bool ";
    if (ExpandDefinition)
      OS << TargetName << "InstrInfo::";
    OS << Rec->getValueAsString("FunctionName");
    OS << "(const MachineInstr &MI)";
    if (!ExpandDefinition) {
      OS << ";\n";
      continue;
    }

    OS << " {\n";
    OS << PE.getIndent();
    PE.expandStatement(OS, Rec->getValueAsDef("Body"));
    OS << "\n}\n\n";
  }
}

//===----------------------------------------------------------------------===//
// Main Output.
//===----------------------------------------------------------------------===//

// run - Emit the main instruction description records for the target...
void InstrInfoEmitter::run(raw_ostream &OS) {
  TGTimer &Timer = Records.getTimer();
  Timer.startTimer("Analyze DAG patterns");

  emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);

  const CodeGenTarget &Target = CDP.getTargetInfo();
  ArrayRef<const CodeGenInstruction *> NumberedInstructions =
      Target.getInstructions();

  emitEnums(OS, NumberedInstructions);

  StringRef TargetName = Target.getName();
  const Record *InstrInfo = Target.getInstructionSet();

  // Collect all of the operand info records.
  Timer.startTimer("Collect operand info");
  OperandInfoListTy OperandInfoList;
  OperandInfoMapTy OperandInfoMap;
  unsigned OperandInfoSize =
      CollectOperandInfo(OperandInfoList, OperandInfoMap);

  // Collect all of the instruction's implicit uses and defs.
  // Also collect which features are enabled by instructions to control
  // emission of various mappings.

  bool HasUseLogicalOperandMappings = false;
  bool HasUseNamedOperandTable = false;

  Timer.startTimer("Collect uses/defs");
  std::map<std::vector<const Record *>, unsigned> EmittedLists;
  std::vector<std::vector<const Record *>> ImplicitLists;
  unsigned ImplicitListSize = 0;
  for (const CodeGenInstruction *Inst : NumberedInstructions) {
    HasUseLogicalOperandMappings |=
        Inst->TheDef->getValueAsBit("UseLogicalOperandMappings");
    HasUseNamedOperandTable |=
        Inst->TheDef->getValueAsBit("UseNamedOperandTable");

    std::vector<const Record *> ImplicitOps = Inst->ImplicitUses;
    llvm::append_range(ImplicitOps, Inst->ImplicitDefs);
    if (EmittedLists.try_emplace(ImplicitOps, ImplicitListSize).second) {
      ImplicitLists.push_back(ImplicitOps);
      ImplicitListSize += ImplicitOps.size();
    }
  }

  OS << "#if defined(GET_INSTRINFO_MC_DESC) || "
        "defined(GET_INSTRINFO_CTOR_DTOR)\n";

  OS << "namespace llvm {\n\n";

  OS << "struct " << TargetName << "InstrTable {\n";
  OS << "  MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
  OS << "  static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
        "\"Unwanted padding between Insts and OperandInfo\");\n";
  OS << "  MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
  OS << "  static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), "
        "\"Unwanted padding between OperandInfo and ImplicitOps\");\n";
  OS << "  MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n";
  OS << "};\n\n";

  OS << "} // end namespace llvm\n";
  OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
        "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";

  const CodeGenRegBank &RegBank = Target.getRegBank();
  const CodeGenHwModes &CGH = Target.getHwModes();
  unsigned NumModes = CGH.getNumModeIds();
  ArrayRef<const Record *> RegClassByHwMode = Target.getAllRegClassByHwMode();
  unsigned NumClassesByHwMode = RegClassByHwMode.size();

  bool HasDeprecationFeatures =
      llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
        return !Inst->HasComplexDeprecationPredicate &&
               !Inst->DeprecatedReason.empty();
      });
  bool HasComplexDeprecationInfos =
      llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
        return Inst->HasComplexDeprecationPredicate;
      });

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_DESC");
    NamespaceEmitter LlvmNS(OS, "llvm");

    // Emit all of the MCInstrDesc records in reverse ENUM ordering.
    Timer.startTimer("Emit InstrDesc records");
    OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
    OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
       << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";

    OS << "extern const " << TargetName << "InstrTable " << TargetName
       << "Descs = {\n  {\n";
    SequenceToOffsetTable<StringRef> InstrNames;
    unsigned Num = NumberedInstructions.size();
    for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
      // Keep a list of the instruction names.
      InstrNames.add(Inst->getName());
      // Emit the record into the table.
      emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
    }

    OS << "  }, {\n";

    // Emit all of the operand info records.
    Timer.startTimer("Emit operand info");
    EmitOperandInfo(OS, OperandInfoList);

    OS << "  }, {\n";

    // Emit all of the instruction's implicit uses and defs.
    Timer.startTimer("Emit uses/defs");
    for (auto &List : ImplicitLists) {
      OS << "    /* " << EmittedLists[List] << " */";
      for (auto &Reg : List)
        OS << ' ' << getQualifiedName(Reg) << ',';
      OS << '\n';
    }

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

    // Emit the array of instruction names.
    Timer.startTimer("Emit instruction names");
    InstrNames.layout();
    InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") +
                                            TargetName + "InstrNameData[]");
    OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
    Num = 0;
    for (const CodeGenInstruction *Inst : NumberedInstructions) {
      // Newline every eight entries.
      if (Num % 8 == 0)
        OS << "\n    ";
      OS << InstrNames.get(Inst->getName()) << "U, ";
      ++Num;
    }
    OS << "\n};\n\n";

    if (HasDeprecationFeatures) {
      OS << "extern const uint8_t " << TargetName
         << "InstrDeprecationFeatures[] = {";
      Num = 0;
      for (const CodeGenInstruction *Inst : NumberedInstructions) {
        if (Num % 8 == 0)
          OS << "\n    ";
        if (!Inst->HasComplexDeprecationPredicate &&
            !Inst->DeprecatedReason.empty())
          OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
             << ", ";
        else
          OS << "uint8_t(-1), ";
        ++Num;
      }
      OS << "\n};\n\n";
    }

    if (HasComplexDeprecationInfos) {
      OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
         << TargetName << "InstrComplexDeprecationInfos[] = {";
      Num = 0;
      for (const CodeGenInstruction *Inst : NumberedInstructions) {
        if (Num % 8 == 0)
          OS << "\n    ";
        if (Inst->HasComplexDeprecationPredicate)
          // Emit a function pointer to the complex predicate method.
          OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
        else
          OS << "nullptr, ";
        ++Num;
      }
      OS << "\n};\n\n";
    }

    // MCInstrInfo initialization routine.
    Timer.startTimer("Emit initialization routine");

    if (NumClassesByHwMode != 0) {
      OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
         << NumModes << "][" << NumClassesByHwMode << "] = {\n";

      for (unsigned M = 0; M < NumModes; ++M) {
        OS << "  { // " << CGH.getModeName(M, /*IncludeDefault=*/true) << '\n';
        for (unsigned I = 0; I != NumClassesByHwMode; ++I) {
          const Record *Class = RegClassByHwMode[I];
          const HwModeSelect &ModeSelect = CGH.getHwModeSelect(Class);

          auto FoundMode =
              find_if(ModeSelect.Items, [=](const HwModeSelect::PairType P) {
                return P.first == M;
              });

          if (FoundMode == ModeSelect.Items.end()) {
            // If a RegClassByHwMode doesn't have an entry corresponding to a
            // mode, pad with default register class.
            OS << indent(4) << "-1, // Missing mode entry\n";
          } else {
            const CodeGenRegisterClass *RegClass =
                RegBank.getRegClass(FoundMode->second);
            OS << indent(4) << RegClass->getQualifiedIdName() << ",\n";
          }
        }

        OS << "  },\n";
      }

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

    OS << "static inline void Init" << TargetName
       << "MCInstrInfo(MCInstrInfo *II) {\n";
    OS << "  II->InitMCInstrInfo(" << TargetName << "Descs.Insts, "
       << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, ";
    if (HasDeprecationFeatures)
      OS << TargetName << "InstrDeprecationFeatures, ";
    else
      OS << "nullptr, ";
    if (HasComplexDeprecationInfos)
      OS << TargetName << "InstrComplexDeprecationInfos, ";
    else
      OS << "nullptr, ";
    OS << NumberedInstructions.size() << ", ";

    if (NumClassesByHwMode != 0) {
      OS << '&' << TargetName << "RegClassByHwModeTables[0][0], "
         << NumClassesByHwMode;
    } else
      OS << "nullptr, 0";

    OS << ");\n}\n\n";
  } // end GET_INSTRINFO_MC_DESC scope.

  {
    // Create a TargetInstrInfo subclass to hide the MC layer initialization.
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HEADER");
    {
      NamespaceEmitter LlvmNS(OS, "llvm");
      Twine ClassName = TargetName + "GenInstrInfo";
      OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
         << "  explicit " << ClassName
         << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, "
            "unsigned CFDestroyOpcode = ~0u, "
            "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
         << "  ~" << ClassName << "() override = default;\n"
         << "};\n";
    } // end llvm namespace.

    OS << "\n";
    NamespaceEmitter InstNS(OS, ("llvm::" + Target.getInstNamespace()).str());
    for (const Record *R : Records.getAllDerivedDefinitions("Operand")) {
      if (R->isAnonymous())
        continue;
      const DagInit *D = R->getValueAsDag("MIOperandInfo");
      if (!D)
        continue;
      for (const auto &[Idx, Name] : enumerate(D->getArgNames())) {
        if (Name)
          OS << "constexpr unsigned SUBOP_" << R->getName() << "_"
             << Name->getValue() << " = " << Idx << ";\n";
      }
    }
  } // end GET_INSTRINFO_HEADER scope.

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPER_DECLS");
    emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPERS");
    emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_CTOR_DTOR");
    NamespaceEmitter LlvmNS(OS, "llvm");
    OS << "extern const " << TargetName << "InstrTable " << TargetName
       << "Descs;\n";
    OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
    OS << "extern const char " << TargetName << "InstrNameData[];\n";

    if (NumClassesByHwMode != 0) {
      OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
         << NumModes << "][" << NumClassesByHwMode << "];\n";
    }

    if (HasDeprecationFeatures)
      OS << "extern const uint8_t " << TargetName
         << "InstrDeprecationFeatures[];\n";
    if (HasComplexDeprecationInfos)
      OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
         << TargetName << "InstrComplexDeprecationInfos[];\n";
    Twine ClassName = TargetName + "GenInstrInfo";
    OS << ClassName << "::" << ClassName
       << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned "
          "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
       << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
          "ReturnOpcode";
    if (NumClassesByHwMode != 0)
      OS << ", " << TargetName
         << "RegClassByHwModeTables[STI.getHwMode(MCSubtargetInfo::HwMode_"
            "RegInfo)]";

    OS << ") {\n"
       << "  InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
       << "InstrNameIndices, " << TargetName << "InstrNameData, ";
    if (HasDeprecationFeatures)
      OS << TargetName << "InstrDeprecationFeatures, ";
    else
      OS << "nullptr, ";
    if (HasComplexDeprecationInfos)
      OS << TargetName << "InstrComplexDeprecationInfos, ";
    else
      OS << "nullptr, ";
    OS << NumberedInstructions.size();

    if (NumClassesByHwMode != 0) {
      OS << ", &" << TargetName << "RegClassByHwModeTables[0][0], "
         << NumClassesByHwMode;
    }

    OS << ");\n"
          "}\n";
  } // end GET_INSTRINFO_CTOR_DTOR scope.

  ArrayRef<const CodeGenInstruction *> TargetInstructions =
      Target.getTargetInstructions();

  if (HasUseNamedOperandTable) {
    Timer.startTimer("Emit operand name mappings");
    emitOperandNameMappings(OS, Target, TargetInstructions);
  }

  Timer.startTimer("Emit operand type mappings");
  emitOperandTypeMappings(OS, Target, NumberedInstructions);

  if (HasUseLogicalOperandMappings) {
    Timer.startTimer("Emit logical operand size mappings");
    emitLogicalOperandSizeMappings(OS, TargetName, TargetInstructions);
  }

  Timer.startTimer("Emit helper methods");
  emitMCIIHelperMethods(OS, TargetName);

  Timer.startTimer("Emit verifier methods");
  emitFeatureVerifier(OS, Target);

  Timer.startTimer("Emit map table");
  EmitMapTable(Records, OS);
}

void InstrInfoEmitter::emitRecord(
    const CodeGenInstruction &Inst, unsigned Num, const Record *InstrInfo,
    std::map<std::vector<const Record *>, unsigned> &EmittedLists,
    const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) {
  int MinOperands = 0;
  if (!Inst.Operands.empty())
    // Each logical operand can be multiple MI operands.
    MinOperands =
        Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands;
  // Even the logical output operand may be multiple MI operands.
  int DefOperands = 0;
  if (Inst.Operands.NumDefs) {
    auto &Opnd = Inst.Operands[Inst.Operands.NumDefs - 1];
    DefOperands = Opnd.MIOperandNo + Opnd.MINumOperands;
  }

  OS << "    { ";
  OS << Num << ",\t" << MinOperands << ",\t" << DefOperands << ",\t"
     << Inst.TheDef->getValueAsInt("Size") << ",\t"
     << SchedModels.getSchedClassIdx(Inst) << ",\t";

  const CodeGenTarget &Target = CDP.getTargetInfo();

  // Emit the implicit use/def list...
  OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
  std::vector<const Record *> ImplicitOps = Inst.ImplicitUses;
  llvm::append_range(ImplicitOps, Inst.ImplicitDefs);

  // Emit the operand info offset.
  OperandInfoTy OperandInfo = GetOperandInfo(Inst);
  OS << OperandInfoMap.find(OperandInfo)->second << ",\t";

  // Emit implicit operand base.
  OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps]
     << ",\t0";

  // Emit all of the target independent flags...
  if (Inst.isPreISelOpcode)
    OS << "|(1ULL<<MCID::PreISelOpcode)";
  if (Inst.isPseudo)
    OS << "|(1ULL<<MCID::Pseudo)";
  if (Inst.isMeta)
    OS << "|(1ULL<<MCID::Meta)";
  if (Inst.isReturn)
    OS << "|(1ULL<<MCID::Return)";
  if (Inst.isEHScopeReturn)
    OS << "|(1ULL<<MCID::EHScopeReturn)";
  if (Inst.isBranch)
    OS << "|(1ULL<<MCID::Branch)";
  if (Inst.isIndirectBranch)
    OS << "|(1ULL<<MCID::IndirectBranch)";
  if (Inst.isCompare)
    OS << "|(1ULL<<MCID::Compare)";
  if (Inst.isMoveImm)
    OS << "|(1ULL<<MCID::MoveImm)";
  if (Inst.isMoveReg)
    OS << "|(1ULL<<MCID::MoveReg)";
  if (Inst.isBitcast)
    OS << "|(1ULL<<MCID::Bitcast)";
  if (Inst.isAdd)
    OS << "|(1ULL<<MCID::Add)";
  if (Inst.isTrap)
    OS << "|(1ULL<<MCID::Trap)";
  if (Inst.isSelect)
    OS << "|(1ULL<<MCID::Select)";
  if (Inst.isBarrier)
    OS << "|(1ULL<<MCID::Barrier)";
  if (Inst.hasDelaySlot)
    OS << "|(1ULL<<MCID::DelaySlot)";
  if (Inst.isCall)
    OS << "|(1ULL<<MCID::Call)";
  if (Inst.canFoldAsLoad)
    OS << "|(1ULL<<MCID::FoldableAsLoad)";
  if (Inst.mayLoad)
    OS << "|(1ULL<<MCID::MayLoad)";
  if (Inst.mayStore)
    OS << "|(1ULL<<MCID::MayStore)";
  if (Inst.mayRaiseFPException)
    OS << "|(1ULL<<MCID::MayRaiseFPException)";
  if (Inst.isPredicable)
    OS << "|(1ULL<<MCID::Predicable)";
  if (Inst.isConvertibleToThreeAddress)
    OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
  if (Inst.isCommutable)
    OS << "|(1ULL<<MCID::Commutable)";
  if (Inst.isTerminator)
    OS << "|(1ULL<<MCID::Terminator)";
  if (Inst.isReMaterializable)
    OS << "|(1ULL<<MCID::Rematerializable)";
  if (Inst.isNotDuplicable)
    OS << "|(1ULL<<MCID::NotDuplicable)";
  if (Inst.Operands.hasOptionalDef)
    OS << "|(1ULL<<MCID::HasOptionalDef)";
  if (Inst.usesCustomInserter)
    OS << "|(1ULL<<MCID::UsesCustomInserter)";
  if (Inst.hasPostISelHook)
    OS << "|(1ULL<<MCID::HasPostISelHook)";
  if (Inst.Operands.isVariadic)
    OS << "|(1ULL<<MCID::Variadic)";
  if (Inst.hasSideEffects)
    OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
  if (Inst.isAsCheapAsAMove)
    OS << "|(1ULL<<MCID::CheapAsAMove)";
  if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
    OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
  if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
    OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
  if (Inst.isRegSequence)
    OS << "|(1ULL<<MCID::RegSequence)";
  if (Inst.isExtractSubreg)
    OS << "|(1ULL<<MCID::ExtractSubreg)";
  if (Inst.isInsertSubreg)
    OS << "|(1ULL<<MCID::InsertSubreg)";
  if (Inst.isConvergent)
    OS << "|(1ULL<<MCID::Convergent)";
  if (Inst.variadicOpsAreDefs)
    OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
  if (Inst.isAuthenticated)
    OS << "|(1ULL<<MCID::Authenticated)";

  // Emit all of the target-specific flags...
  const BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
  if (!TSF)
    PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?");
  std::optional<uint64_t> Value = TSF->convertInitializerToInt();
  if (!Value)
    PrintFatalError(Inst.TheDef, "Invalid TSFlags bit in " + Inst.getName());

  OS << ", 0x";
  OS.write_hex(*Value);
  OS << "ULL";

  OS << " },  // " << Inst.getName() << '\n';
}

// emitEnums - Print out enum values for all of the instructions.
void InstrInfoEmitter::emitEnums(
    raw_ostream &OS,
    ArrayRef<const CodeGenInstruction *> NumberedInstructions) {

  const CodeGenTarget &Target = CDP.getTargetInfo();
  StringRef Namespace = Target.getInstNamespace();

  if (Namespace.empty())
    PrintFatalError("No instructions defined!");

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_ENUM");
    NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());

    auto II = llvm::max_element(
        NumberedInstructions,
        [](const CodeGenInstruction *InstA, const CodeGenInstruction *InstB) {
          return InstA->getName().size() < InstB->getName().size();
        });
    size_t MaxNameSize = (*II)->getName().size();

    OS << "  enum {\n";
    for (const CodeGenInstruction *Inst : NumberedInstructions) {
      OS << "    " << left_justify(Inst->getName(), MaxNameSize) << " = "
         << Target.getInstrIntValue(Inst->TheDef) << ", // "
         << SrcMgr.getFormattedLocationNoOffset(Inst->TheDef->getLoc().front())
         << '\n';
    }
    OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << '\n';
    OS << "  };\n";

    ArrayRef<const Record *> RegClassesByHwMode =
        Target.getAllRegClassByHwMode();
    if (!RegClassesByHwMode.empty()) {
      OS << "  enum RegClassByHwModeUses : uint16_t {\n";
      for (const Record *ClassByHwMode : RegClassesByHwMode)
        OS << indent(4) << ClassByHwMode->getName() << ",\n";
      OS << "  };\n";
    }
  }

  {
    IfDefEmitter IfDef(OS, "GET_INSTRINFO_SCHED_ENUM");
    NamespaceEmitter NS(OS, ("llvm::" + Namespace + "::Sched").str());

    OS << "  enum {\n";
    auto ExplictClasses = SchedModels.explicitSchedClasses();
    for (const auto &[Idx, Class] : enumerate(ExplictClasses))
      OS << "    " << Class.Name << "\t= " << Idx << ",\n";
    OS << "    SCHED_LIST_END = " << ExplictClasses.size() << '\n';
    OS << "  };\n";
  }
}

static TableGen::Emitter::OptClass<InstrInfoEmitter>
    X("gen-instr-info", "Generate instruction descriptions");
