//===- 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 << "bool " << TargetName << "InstrComplexDeprecationInfo("
         << "MCInst &Inst, const MCSubtargetInfo &STI, std::string &Info) {\n"
         << "  switch (Inst.getOpcode()) {\n";
      for (const CodeGenInstruction *Inst : NumberedInstructions) {
        if (!Inst->HasComplexDeprecationPredicate)
          continue;
        OS << "  case " << getQualifiedName(Inst->TheDef) << ": return get"
           << Inst->DeprecatedReason << "DeprecationInfo(Inst, STI, Info);\n";
      }
      OS << "  }\n  return false;\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 << "InstrComplexDeprecationInfo, ";
    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 << "bool " << TargetName << "InstrComplexDeprecationInfo("
         << "MCInst &Inst, const MCSubtargetInfo &STI, std::string &Info);\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 << "InstrComplexDeprecationInfo, ";
    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");
