//===- 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>;

  DenseMap<const CodeGenInstruction *, const CodeGenInstruction *>
      TargetSpecializedPseudoInsts;

  /// Compute mapping of opcodes which should have their definitions overridden
  /// by a target version.
  void buildTargetSpecializedPseudoInstsMap();

  /// 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")) {
        if (Inst.isPseudo) {
          // TODO: Verify this is a fixed pseudo
          PrintError(Inst.TheDef,
                     "missing target override for pseudoinstruction "
                     "using PointerLikeRegClass");
          PrintNote(OpR->getLoc(),
                    "target should define equivalent instruction "
                    "with RegisterClassLike replacement; (use "
                    "RemapAllTargetPseudoPointerOperands?)");
        } else {
          PrintError(Inst.TheDef,
                     "non-pseudoinstruction user of PointerLikeRegClass");
        }
      } 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)";

      // 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()) {
    auto OverrideEntry = TargetSpecializedPseudoInsts.find(Inst);
    if (OverrideEntry != TargetSpecializedPseudoInsts.end())
      Inst = OverrideEntry->second;

    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(uint32_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(uint32_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(uint32_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(uint32_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(uint32_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(uint32_t Opcode, OpName "
          "Name);\n";
    OS << "LLVM_READONLY OpName getOperandIdxName(uint32_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(uint32_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(uint32_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(uint32_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";
  }
}

void InstrInfoEmitter::buildTargetSpecializedPseudoInstsMap() {
  ArrayRef<const Record *> SpecializedInsts = Records.getAllDerivedDefinitions(
      "TargetSpecializedStandardPseudoInstruction");
  const CodeGenTarget &Target = CDP.getTargetInfo();

  for (const Record *SpecializedRec : SpecializedInsts) {
    const CodeGenInstruction &SpecializedInst =
        Target.getInstruction(SpecializedRec);
    const Record *BaseInstRec = SpecializedRec->getValueAsDef("Instruction");

    const CodeGenInstruction &BaseInst = Target.getInstruction(BaseInstRec);

    if (!TargetSpecializedPseudoInsts.insert({&BaseInst, &SpecializedInst})
             .second)
      PrintFatalError(SpecializedRec, "multiple overrides of '" +
                                          BaseInst.getName() + "' defined");
  }
}

//===----------------------------------------------------------------------===//
// 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");
  buildTargetSpecializedPseudoInstsMap();

  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();
    }
  }

  {
    IfGuardEmitter IfGuard(
        OS,
        "defined(GET_INSTRINFO_MC_DESC) || defined(GET_INSTRINFO_CTOR_DTOR)");
    NamespaceEmitter NS(OS, "llvm");

    OS << "struct " << TargetName << "InstrTable {\n";
    OS << "  MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
    OS << "  static_assert(alignof(MCInstrDesc) >= alignof(MCPhysReg), "
          "\"Unwanted padding between Insts and ImplicitOps\");\n";
    OS << "  MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U)
       << "];\n";
    // Emit enough padding to make ImplicitOps plus Padding add up to the size
    // of a whole number of MCOperandInfo structs. This allows us to index into
    // the OperandInfo array starting from the end of the Insts array, by
    // biasing the indices by the OpInfoBase value calculated below.
    OS << "  char Padding[sizeof(MCOperandInfo) - sizeof ImplicitOps % "
          "sizeof(MCOperandInfo)];\n";
    OS << "  static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
          "\"Unwanted padding between Insts and OperandInfo\");\n";
    OS << "  MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
    OS << "};";
  }

  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 " << TargetName
       << "InstrTable::ImplicitOps + sizeof " << TargetName
       << "InstrTable::Padding) % sizeof(MCOperandInfo) == 0);\n";
    OS << "static constexpr unsigned " << TargetName << "OpInfoBase = (sizeof "
       << TargetName << "InstrTable::ImplicitOps + sizeof " << TargetName
       << "InstrTable::Padding) / sizeof(MCOperandInfo);\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());

      auto OverrideEntry = TargetSpecializedPseudoInsts.find(Inst);
      if (OverrideEntry != TargetSpecializedPseudoInsts.end())
        Inst = OverrideEntry->second;

      // Emit the record into the table.
      emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
    }

    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";

    // Emit the padding.
    OS << "    0\n";

    OS << "  }, {\n";

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

    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 for "
               << Class->getName() << "\n";
          } else {
            const CodeGenRegisterClass *RegClass =
                RegBank.getRegClass(FoundMode->second);
            OS << indent(4) << RegClass->getQualifiedIdName() << ", // "
               << Class->getName() << "\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, const TargetRegisterInfo &TRI, "
            "unsigned CFSetupOpcode = ~0u, "
            "unsigned CFDestroyOpcode = ~0u, "
            "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
         << "  ~" << ClassName << "() override = default;\n"
         << "};\n";

      // Declare RegClassByHwModeTables, so that other files can use this
      // without having to indirect via MCInstInfo.
      if (NumClassesByHwMode != 0) {
        OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
           << NumModes << "][" << NumClassesByHwMode << "];\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 (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, const TargetRegisterInfo &TRI, "
          "unsigned CFSetupOpcode, unsigned "
          "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
       << "  : TargetInstrInfo(TRI, 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 << Target.getName() << "OpInfoBase + "
     << OperandInfoMap.find(OperandInfo)->second << ",\t";

  // Emit implicit operand base.
  OS << 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");
