[llvm] [NFC][TableGen] Adopt CodeGenHelpers in InstrInfoEmitter (PR #166442)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 4 12:42:13 PST 2025


https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/166442

None

>From 9b5b180eb75c418fea8f19746a1e1a1add1e41d8 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 29 Oct 2025 13:50:56 -0700
Subject: [PATCH] [NFC][TableGen] Adopt CodeGenHelpers in InstrInfoEmitter

---
 llvm/test/TableGen/RegClassByHwMode.td      |   13 +-
 llvm/test/TableGen/get-named-operand-idx.td |   16 +-
 llvm/utils/TableGen/InstrInfoEmitter.cpp    | 1091 +++++++++----------
 3 files changed, 550 insertions(+), 570 deletions(-)

diff --git a/llvm/test/TableGen/RegClassByHwMode.td b/llvm/test/TableGen/RegClassByHwMode.td
index ca72cfbd403bf..a21a396f7fd52 100644
--- a/llvm/test/TableGen/RegClassByHwMode.td
+++ b/llvm/test/TableGen/RegClassByHwMode.td
@@ -6,18 +6,21 @@
 
 include "llvm/Target/Target.td"
 
-// INSTRINFO: #ifdef GET_INSTRINFO_ENUM
+// INSTRINFO:      #ifdef GET_INSTRINFO_ENUM
 // INSTRINFO-NEXT: #undef GET_INSTRINFO_ENUM
+// INSTRINFO-EMPTY:
 // INSTRINFO-NEXT: namespace llvm::MyTarget {
+// INSTRINFO-EMPTY:
 // INSTRINFO-NEXT: enum {
-// INSTRINFO-NEXT: PHI
-// INSTRINFO: };
-// INSTRINFO: enum RegClassByHwModeUses : uint16_t {
+// INSTRINFO-NEXT:   PHI
+// INSTRINFO:      };
+// INSTRINFO:      enum RegClassByHwModeUses : uint16_t {
 // INSTRINFO-NEXT:   MyPtrRC,
 // INSTRINFO-NEXT:   XRegs_EvenIfRequired,
 // INSTRINFO-NEXT:   YRegs_EvenIfRequired,
 // INSTRINFO-NEXT: };
-// INSTRINFO-NEXT: }
+// INSTRINFO-EMPTY:
+// INSTRINFO-NEXT: } // namespace llvm::MyTarget
 
 // INSTRINFO: { MyTarget::XRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },
 // INSTRINFO: { MyTarget::XRegs_EvenRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },
diff --git a/llvm/test/TableGen/get-named-operand-idx.td b/llvm/test/TableGen/get-named-operand-idx.td
index e6f6331cd9c48..4500ad1638c17 100644
--- a/llvm/test/TableGen/get-named-operand-idx.td
+++ b/llvm/test/TableGen/get-named-operand-idx.td
@@ -50,7 +50,9 @@ def InstD : InstBase {
 
 // CHECK-LABEL: #ifdef GET_INSTRINFO_OPERAND_ENUM
 // CHECK-NEXT:  #undef GET_INSTRINFO_OPERAND_ENUM
+// CHECK-EMPTY:
 // CHECK-NEXT:  namespace llvm::MyNamespace {
+// CHECK-EMPTY:
 // CHECK-NEXT:  enum class OpName : uint8_t {
 // CHECK-NEXT:    a = 0,
 // CHECK-NEXT:    b = 1,
@@ -62,12 +64,16 @@ def InstD : InstBase {
 // CHECK-EMPTY:
 // CHECK-NEXT:  LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name);
 // CHECK-NEXT:  LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t Idx);
-// CHECK-NEXT:  } // end namespace llvm::MyNamespace
-// CHECK-NEXT:  #endif //GET_INSTRINFO_OPERAND_ENUM
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm::MyNamespace
+// CHECK-EMPTY:
+// CHECK-NEXT:  #endif // GET_INSTRINFO_OPERAND_ENUM
 
 // CHECK-LABEL: #ifdef GET_INSTRINFO_NAMED_OPS
 // CHECK-NEXT:  #undef GET_INSTRINFO_NAMED_OPS
+// CHECK-EMPTY:
 // CHECK-NEXT:  namespace llvm::MyNamespace {
+// CHECK-EMPTY:
 // CHECK-NEXT:  LLVM_READONLY static uint8_t getInstructionIndexForOpLookup(uint16_t Opcode) {
 // CHECK-NEXT:    static constexpr uint8_t InstructionIndex[] = {
 // CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -113,5 +119,7 @@ def InstD : InstBase {
 // CHECK-NEXT:    unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);
 // CHECK-NEXT:    return OperandMap[InstrIdx][(unsigned)Idx];
 // CHECK-NEXT:  }
-// CHECK-NEXT:  } // end namespace llvm::MyNamespace
-// CHECK-NEXT:  #endif //GET_INSTRINFO_NAMED_OPS
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm::MyNamespace
+// CHECK-EMPTY:
+// CHECK-NEXT:  #endif // GET_INSTRINFO_NAMED_OPS
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 0b90f9104208a..cc61571e26cc2 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -383,38 +383,35 @@ void InstrInfoEmitter::emitOperandNameMappings(
   const size_t NumOperandNames = OperandNameToID.size();
   const unsigned MaxNumOperands = MaxOperandNo + 1;
 
-  OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
-  OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
-  OS << "namespace llvm::" << Namespace << " {\n";
-
-  assert(NumOperandNames <= UINT16_MAX &&
-         "Too many operands for the operand index -> name table");
-  StringRef EnumType = getMinimalTypeForRange(NumOperandNames);
-  OS << "enum class OpName : " << EnumType << " {\n";
-  for (const auto &[Op, I] : OperandNameToID)
-    OS << "  " << Op << " = " << I << ",\n";
-  OS << "  NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
-  OS << "}; // enum class OpName\n\n";
-
-  OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
-        "Name);\n";
-  OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t "
-        "Idx);\n";
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
-  OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
-  OS << "namespace llvm::" << Namespace << " {\n";
-
-  emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
+  const std::string LlvmNamespace = ("llvm::" + Namespace).str();
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_ENUM");
+    NamespaceEmitter NS(OS, LlvmNamespace);
+
+    assert(NumOperandNames <= UINT16_MAX &&
+           "Too many operands for the operand index -> name table");
+    StringRef EnumType = getMinimalTypeForRange(NumOperandNames);
+    OS << "enum class OpName : " << EnumType << " {\n";
+    for (const auto &[Op, I] : OperandNameToID)
+      OS << "  " << Op << " = " << I << ",\n";
+    OS << "  NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
+    OS << "}; // enum class OpName\n\n";
+
+    OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
+          "Name);\n";
+    OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t "
+          "Idx);\n";
+  }
 
-  emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
-  emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
-                        NumOperandNames);
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_NAMED_OPS");
+    NamespaceEmitter NS(OS, LlvmNamespace);
+    emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
 
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
+    emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
+    emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
+                          NumOperandNames);
+  }
 }
 
 /// Generate an enum for all the operand types for this target, under the
@@ -439,121 +436,121 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   ArrayRef<const Record *> RegisterClasses =
       Records.getAllDerivedDefinitions("RegisterClass");
 
-  OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
-  OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
-  OS << "namespace llvm::" << Namespace << "::OpTypes {\n";
-  OS << "enum OperandType {\n";
-
   unsigned EnumVal = 0;
-  for (ArrayRef<const Record *> RecordsToAdd :
-       {Operands, RegisterOperands, RegisterClasses}) {
-    for (const Record *Op : RecordsToAdd) {
-      if (!Op->isAnonymous())
-        OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
-      ++EnumVal;
+
+  {
+    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";
   }
 
-  OS << "  OPERAND_TYPE_LIST_END"
-     << "\n};\n";
-  OS << "} // end namespace llvm::" << Namespace << "::OpTypes\n";
-  OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
-  OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
-  OS << "namespace llvm::" << Namespace << " {\n";
-  OS << "LLVM_READONLY\n";
-  OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
-  auto getInstrName = [&](int I) -> StringRef {
-    return NumberedInstructions[I]->getName();
-  };
-  // TODO: Factor out duplicate operand lists to compress the tables.
-  std::vector<size_t> OperandOffsets;
-  std::vector<const Record *> OperandRecords;
-  size_t CurrentOffset = 0;
-  for (const CodeGenInstruction *Inst : NumberedInstructions) {
-    OperandOffsets.push_back(CurrentOffset);
-    for (const auto &Op : Inst->Operands) {
-      const DagInit *MIOI = Op.MIOperandInfo;
-      if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
-        // Single, anonymous, operand.
-        OperandRecords.push_back(Op.Rec);
-        ++CurrentOffset;
-      } else {
-        for (const Init *Arg : MIOI->getArgs()) {
-          OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_TYPE");
+    NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
+    OS << "LLVM_READONLY\n";
+    OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
+    auto getInstrName = [&](int I) -> StringRef {
+      return NumberedInstructions[I]->getName();
+    };
+    // TODO: Factor out duplicate operand lists to compress the tables.
+    std::vector<size_t> OperandOffsets;
+    std::vector<const Record *> OperandRecords;
+    size_t CurrentOffset = 0;
+    for (const CodeGenInstruction *Inst : NumberedInstructions) {
+      OperandOffsets.push_back(CurrentOffset);
+      for (const auto &Op : Inst->Operands) {
+        const DagInit *MIOI = Op.MIOperandInfo;
+        if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
+          // Single, anonymous, operand.
+          OperandRecords.push_back(Op.Rec);
           ++CurrentOffset;
+        } else {
+          for (const Init *Arg : MIOI->getArgs()) {
+            OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
+            ++CurrentOffset;
+          }
         }
       }
     }
-  }
 
-  // Emit the table of offsets (indexes) into the operand type table.
-  // Size the unsigned integer offset to save space.
-  assert(OperandRecords.size() <= UINT32_MAX &&
-         "Too many operands for offset table");
-  OS << "  static constexpr " << getMinimalTypeForRange(OperandRecords.size());
-  OS << " Offsets[] = {\n";
-  for (const auto &[Idx, Offset] : enumerate(OperandOffsets))
-    OS << "    " << Offset << ", // " << getInstrName(Idx) << '\n';
-  OS << "  };\n";
+    // 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    ";
+    // 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 << ", ";
     }
-    if ((OpR->isSubClassOf("Operand") || OpR->isSubClassOf("RegisterOperand") ||
-         OpR->isSubClassOf("RegisterClass")) &&
-        !OpR->isAnonymous())
-      OS << OpR->getName();
-    else
-      OS << -1;
-    OS << ", ";
-  }
-  OS << "\n  };\n";
+    OS << "\n  };\n";
 
-  OS << "  return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
-  OS << "}\n";
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
-  OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
-  OS << "namespace llvm::" << Namespace << " {\n";
-  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 << "  return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
+    OS << "}\n";
   }
-  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";
+
+  {
+    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";
   }
-  OS << "  }\n}\n";
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n";
 }
 
 // Fixed/Predefined instructions do not have UseLogicalOperandMappings
@@ -587,9 +584,8 @@ void InstrInfoEmitter::emitLogicalOperandSizeMappings(
     InstMap[I->second].push_back((Namespace + "::" + Inst->getName()).str());
   }
 
-  OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
-  OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
-  OS << "namespace llvm::" << Namespace << " {\n";
+  IfDefEmitter IfDef(OS, "GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP");
+  NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
   OS << "LLVM_READONLY static unsigned\n";
   OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
   if (!InstMap.empty()) {
@@ -637,9 +633,6 @@ void InstrInfoEmitter::emitLogicalOperandSizeMappings(
   OS << "    S += getLogicalOperandSize(Opcode, i);\n";
   OS << "  return S;\n";
   OS << "}\n";
-
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
 }
 
 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
@@ -647,48 +640,38 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
   ArrayRef<const Record *> TIIPredicates =
       Records.getAllDerivedDefinitions("TIIPredicate");
 
-  OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
-  OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
-
-  OS << "namespace llvm {\n";
-  OS << "class MCInst;\n";
-  OS << "class FeatureBitset;\n\n";
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPER_DECLS");
+    NamespaceEmitter LlvmNS(OS, "llvm");
+    OS << "class MCInst;\n";
+    OS << "class FeatureBitset;\n\n";
 
-  OS << "namespace " << TargetName << "_MC {\n\n";
+    NamespaceEmitter TargetNS(OS, (TargetName + "_MC").str());
+    for (const Record *Rec : TIIPredicates)
+      OS << "bool " << Rec->getValueAsString("FunctionName")
+         << "(const MCInst &MI);\n";
 
-  for (const Record *Rec : TIIPredicates) {
-    OS << "bool " << Rec->getValueAsString("FunctionName")
-       << "(const MCInst &MI);\n";
+    OS << "void verifyInstructionPredicates(unsigned Opcode, const "
+          "FeatureBitset "
+          "&Features);\n";
   }
 
-  OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
-        "&Features);\n";
-
-  OS << "\n} // end namespace " << TargetName << "_MC\n";
-  OS << "} // end namespace llvm\n\n";
-
-  OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
-  OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
-
-  OS << "namespace llvm::" << TargetName << "_MC {\n";
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPERS");
+    NamespaceEmitter NS(OS, ("llvm::" + TargetName + "_MC").str());
 
-  PredicateExpander PE(TargetName);
-  PE.setExpandForMC(true);
+    PredicateExpander PE(TargetName);
+    PE.setExpandForMC(true);
 
-  for (const Record *Rec : TIIPredicates) {
-    OS << "bool " << Rec->getValueAsString("FunctionName");
-    OS << "(const MCInst &MI) {\n";
+    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";
+      OS << PE.getIndent();
+      PE.expandStatement(OS, Rec->getValueAsDef("Body"));
+      OS << "\n}\n\n";
+    }
   }
-
-  OS << "} // end namespace llvm::" << TargetName << "_MC\n";
-
-  OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
 }
 
 static std::string
@@ -710,148 +693,143 @@ void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
      << "    defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
      << "#define GET_COMPUTE_FEATURES\n"
      << "#endif\n";
-  OS << "#ifdef GET_COMPUTE_FEATURES\n"
-     << "#undef GET_COMPUTE_FEATURES\n"
-     << "namespace llvm::" << Target.getName() << "_MC {\n";
-
-  // 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);
+  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())
+    llvm::sort(FeatureBitsets, [&](ArrayRef<const Record *> A,
+                                   ArrayRef<const Record *> B) {
+      if (A.size() < B.size())
         return true;
-      if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
+      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";
     }
-    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\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";
-  }
-  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++;
+    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';
     }
-    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";
   }
-  OS << "  };\n\n"
-     << "  assert(Opcode < " << NumberedInstructions.size() << ");\n"
-     << "  return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
-     << "}\n\n";
-
-  OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
-     << "#endif // GET_COMPUTE_FEATURES\n\n";
-
-  OS << "#ifdef GET_AVAILABLE_OPCODE_CHECKER\n"
-     << "#undef GET_AVAILABLE_OPCODE_CHECKER\n"
-     << "namespace llvm::" << Target.getName() << "_MC {\n";
-  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";
-  OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
-     << "#endif // GET_AVAILABLE_OPCODE_CHECKER\n\n";
-
-  OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
-     << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
-     << "#include <sstream>\n\n";
-
-  OS << "namespace llvm::" << Target.getName() << "_MC {\n";
-
-  // 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";
-  OS << "} // end namespace llvm::" << Target.getName() << "_MC\n";
-  OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
 }
 
 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
@@ -954,270 +932,263 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
         "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
 
-  OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
-  OS << "#undef GET_INSTRINFO_MC_DESC\n";
-  OS << "namespace llvm {\n\n";
-
-  // Emit all of the MCInstrDesc records in reverse ENUM ordering.
-  Timer.startTimer("Emit InstrDesc records");
-  OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
-  OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
-     << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
-
-  OS << "extern const " << TargetName << "InstrTable " << TargetName
-     << "Descs = {\n  {\n";
-  SequenceToOffsetTable<StringRef> InstrNames;
-  unsigned Num = NumberedInstructions.size();
-  for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
-    // Keep a list of the instruction names.
-    InstrNames.add(Inst->getName());
-    // Emit the record into the table.
-    emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
-  }
-
-  OS << "  }, {\n";
-
-  // Emit all of the operand info records.
-  Timer.startTimer("Emit operand info");
-  EmitOperandInfo(OS, OperandInfoList);
-
-  OS << "  }, {\n";
-
-  // Emit all of the instruction's implicit uses and defs.
-  Timer.startTimer("Emit uses/defs");
-  for (auto &List : ImplicitLists) {
-    OS << "    /* " << EmittedLists[List] << " */";
-    for (auto &Reg : List)
-      OS << ' ' << getQualifiedName(Reg) << ',';
-    OS << '\n';
-  }
-
-  OS << "  }\n};\n\n";
-
-  // Emit the array of instruction names.
-  Timer.startTimer("Emit instruction names");
-  InstrNames.layout();
-  InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
-                                          "InstrNameData[]");
   const CodeGenRegBank &RegBank = Target.getRegBank();
   const CodeGenHwModes &CGH = Target.getHwModes();
   unsigned NumModes = CGH.getNumModeIds();
   ArrayRef<const Record *> RegClassByHwMode = Target.getAllRegClassByHwMode();
   unsigned NumClassesByHwMode = RegClassByHwMode.size();
 
-  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";
-
   bool HasDeprecationFeatures =
       llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
         return !Inst->HasComplexDeprecationPredicate &&
                !Inst->DeprecatedReason.empty();
       });
-  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";
-  }
-
   bool HasComplexDeprecationInfos =
       llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
         return Inst->HasComplexDeprecationPredicate;
       });
-  if (HasComplexDeprecationInfos) {
-    OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
-       << "InstrComplexDeprecationInfos[] = {";
+
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_DESC");
+    NamespaceEmitter LlvmNS(OS, "llvm");
+
+    // Emit all of the MCInstrDesc records in reverse ENUM ordering.
+    Timer.startTimer("Emit InstrDesc records");
+    OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
+    OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
+       << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
+
+    OS << "extern const " << TargetName << "InstrTable " << TargetName
+       << "Descs = {\n  {\n";
+    SequenceToOffsetTable<StringRef> InstrNames;
+    unsigned Num = NumberedInstructions.size();
+    for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
+      // Keep a list of the instruction names.
+      InstrNames.add(Inst->getName());
+      // Emit the record into the table.
+      emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
+    }
+
+    OS << "  }, {\n";
+
+    // Emit all of the operand info records.
+    Timer.startTimer("Emit operand info");
+    EmitOperandInfo(OS, OperandInfoList);
+
+    OS << "  }, {\n";
+
+    // Emit all of the instruction's implicit uses and defs.
+    Timer.startTimer("Emit uses/defs");
+    for (auto &List : ImplicitLists) {
+      OS << "    /* " << EmittedLists[List] << " */";
+      for (auto &Reg : List)
+        OS << ' ' << getQualifiedName(Reg) << ',';
+      OS << '\n';
+    }
+
+    OS << "  }\n};\n\n";
+
+    // Emit the array of instruction names.
+    Timer.startTimer("Emit instruction names");
+    InstrNames.layout();
+    InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") +
+                                            TargetName + "InstrNameData[]");
+    OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
     Num = 0;
     for (const CodeGenInstruction *Inst : NumberedInstructions) {
+      // Newline every eight entries.
       if (Num % 8 == 0)
         OS << "\n    ";
-      if (Inst->HasComplexDeprecationPredicate)
-        // Emit a function pointer to the complex predicate method.
-        OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
-      else
-        OS << "nullptr, ";
+      OS << InstrNames.get(Inst->getName()) << "U, ";
       ++Num;
     }
     OS << "\n};\n\n";
-  }
-
-  // MCInstrInfo initialization routine.
-  Timer.startTimer("Emit initialization routine");
-
-  if (NumClassesByHwMode != 0) {
-    OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
-       << NumModes << "][" << NumClassesByHwMode << "] = {\n";
-
-    for (unsigned M = 0; M < NumModes; ++M) {
-      OS << "  { // " << CGH.getModeName(M, /*IncludeDefault=*/true) << '\n';
-      for (unsigned I = 0; I != NumClassesByHwMode; ++I) {
-        const Record *Class = RegClassByHwMode[I];
-        const HwModeSelect &ModeSelect = CGH.getHwModeSelect(Class);
 
-        auto FoundMode =
-            find_if(ModeSelect.Items, [=](const HwModeSelect::PairType P) {
-              return P.first == M;
-            });
-
-        if (FoundMode == ModeSelect.Items.end()) {
-          // If a RegClassByHwMode doesn't have an entry corresponding to a
-          // mode, pad with default register class.
-          OS << indent(4) << "-1, // Missing mode entry\n";
-        } else {
-          const CodeGenRegisterClass *RegClass =
-              RegBank.getRegClass(FoundMode->second);
-          OS << indent(4) << RegClass->getQualifiedIdName() << ",\n";
-        }
+    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";
+      OS << "\n};\n\n";
     }
 
-    OS << "};\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";
+    }
 
-  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";
+    // MCInstrInfo initialization routine.
+    Timer.startTimer("Emit initialization routine");
+
+    if (NumClassesByHwMode != 0) {
+      OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
+         << NumModes << "][" << NumClassesByHwMode << "] = {\n";
+
+      for (unsigned M = 0; M < NumModes; ++M) {
+        OS << "  { // " << CGH.getModeName(M, /*IncludeDefault=*/true) << '\n';
+        for (unsigned I = 0; I != NumClassesByHwMode; ++I) {
+          const Record *Class = RegClassByHwMode[I];
+          const HwModeSelect &ModeSelect = CGH.getHwModeSelect(Class);
+
+          auto FoundMode =
+              find_if(ModeSelect.Items, [=](const HwModeSelect::PairType P) {
+                return P.first == M;
+              });
+
+          if (FoundMode == ModeSelect.Items.end()) {
+            // If a RegClassByHwMode doesn't have an entry corresponding to a
+            // mode, pad with default register class.
+            OS << indent(4) << "-1, // Missing mode entry\n";
+          } else {
+            const CodeGenRegisterClass *RegClass =
+                RegBank.getRegClass(FoundMode->second);
+            OS << indent(4) << RegClass->getQualifiedIdName() << ",\n";
+          }
+        }
 
-  OS << "} // end namespace llvm\n";
+        OS << "  },\n";
+      }
 
-  OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
+      OS << "};\n\n";
+    }
 
-  // Create a TargetInstrInfo subclass to hide the MC layer initialization.
-  OS << "#ifdef GET_INSTRINFO_HEADER\n";
-  OS << "#undef GET_INSTRINFO_HEADER\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() << ", ";
 
-  Twine ClassName = TargetName + "GenInstrInfo";
-  OS << "namespace llvm {\n";
-  OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
-     << "  explicit " << ClassName
-     << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, "
-        "unsigned CFDestroyOpcode = ~0u, "
-        "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
-     << "  ~" << ClassName << "() override = default;\n";
+    if (NumClassesByHwMode != 0) {
+      OS << '&' << TargetName << "RegClassByHwModeTables[0][0], "
+         << NumClassesByHwMode;
+    } else
+      OS << "nullptr, 0";
 
-  OS << "\n};\n} // end namespace llvm\n";
+    OS << ");\n}\n\n";
+  } // end GET_INSTRINFO_MC_DESC scope.
 
   {
-    NamespaceEmitter LlvmNS(OS, "llvm");
-    NamespaceEmitter TargetNS(OS, Target.getInstNamespace());
+    // Create a TargetInstrInfo subclass to hide the MC layer initialization.
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HEADER");
+    {
+      NamespaceEmitter LlvmNS(OS, "llvm");
+      Twine ClassName = TargetName + "GenInstrInfo";
+      OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
+         << "  explicit " << ClassName
+         << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, "
+            "unsigned CFDestroyOpcode = ~0u, "
+            "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
+         << "  ~" << ClassName << "() override = default;\n"
+         << "};\n";
+    } // end llvm namespace.
+
+    OS << "\n";
+    NamespaceEmitter InstNS(OS, ("llvm::" + Target.getInstNamespace()).str());
     for (const Record *R : Records.getAllDerivedDefinitions("Operand")) {
       if (R->isAnonymous())
         continue;
-      if (const DagInit *D = R->getValueAsDag("MIOperandInfo")) {
-        for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i) {
-          if (const StringInit *Name = D->getArgName(i))
-            OS << "constexpr unsigned SUBOP_" << R->getName() << "_"
-               << Name->getValue() << " = " << i << ";\n";
-        }
+      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";
       }
     }
-  }
-
-  OS << "#endif // GET_INSTRINFO_HEADER\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
-  OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
-  emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
-  OS << '\n';
-  OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_HELPERS\n";
-  OS << "#undef GET_INSTRINFO_HELPERS\n\n";
-  emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
-  OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
+  } // end GET_INSTRINFO_HEADER scope.
 
-  OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
-  OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
-
-  OS << "namespace llvm {\n";
-  OS << "extern const " << TargetName << "InstrTable " << TargetName
-     << "Descs;\n";
-  OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
-  OS << "extern const char " << TargetName << "InstrNameData[];\n";
-
-  if (NumClassesByHwMode != 0) {
-    OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
-       << NumModes << "][" << NumClassesByHwMode << "];\n";
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPER_DECLS");
+    emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
   }
 
-  if (HasDeprecationFeatures)
-    OS << "extern const uint8_t " << TargetName
-       << "InstrDeprecationFeatures[];\n";
-  if (HasComplexDeprecationInfos)
-    OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
-       << "InstrComplexDeprecationInfos[];\n";
-  OS << ClassName << "::" << ClassName
-     << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned "
-        "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
-     << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
-        "ReturnOpcode";
-  if (NumClassesByHwMode != 0)
-    OS << ", " << TargetName
-       << "RegClassByHwModeTables[STI.getHwMode(MCSubtargetInfo::HwMode_"
-          "RegInfo)]";
-
-  OS << ") {\n"
-     << "  InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
-     << "InstrNameIndices, " << TargetName << "InstrNameData, ";
-  if (HasDeprecationFeatures)
-    OS << TargetName << "InstrDeprecationFeatures, ";
-  else
-    OS << "nullptr, ";
-  if (HasComplexDeprecationInfos)
-    OS << TargetName << "InstrComplexDeprecationInfos, ";
-  else
-    OS << "nullptr, ";
-  OS << NumberedInstructions.size();
-
-  if (NumClassesByHwMode != 0) {
-    OS << ", &" << TargetName << "RegClassByHwModeTables[0][0], "
-       << NumClassesByHwMode;
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPERS");
+    emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
   }
 
-  OS << ");\n"
-        "}\n"
-        "} // end namespace llvm\n";
+  {
+    IfDefEmitter IfDef(OS, "GET_INSTRINFO_CTOR_DTOR");
+    NamespaceEmitter LlvmNS(OS, "llvm");
+    OS << "extern const " << TargetName << "InstrTable " << TargetName
+       << "Descs;\n";
+    OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
+    OS << "extern const char " << TargetName << "InstrNameData[];\n";
+
+    if (NumClassesByHwMode != 0) {
+      OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
+         << NumModes << "][" << NumClassesByHwMode << "];\n";
+    }
+
+    if (HasDeprecationFeatures)
+      OS << "extern const uint8_t " << TargetName
+         << "InstrDeprecationFeatures[];\n";
+    if (HasComplexDeprecationInfos)
+      OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
+         << TargetName << "InstrComplexDeprecationInfos[];\n";
+    Twine ClassName = TargetName + "GenInstrInfo";
+    OS << ClassName << "::" << ClassName
+       << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned "
+          "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
+       << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
+          "ReturnOpcode";
+    if (NumClassesByHwMode != 0)
+      OS << ", " << TargetName
+         << "RegClassByHwModeTables[STI.getHwMode(MCSubtargetInfo::HwMode_"
+            "RegInfo)]";
+
+    OS << ") {\n"
+       << "  InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
+       << "InstrNameIndices, " << TargetName << "InstrNameData, ";
+    if (HasDeprecationFeatures)
+      OS << TargetName << "InstrDeprecationFeatures, ";
+    else
+      OS << "nullptr, ";
+    if (HasComplexDeprecationInfos)
+      OS << TargetName << "InstrComplexDeprecationInfos, ";
+    else
+      OS << "nullptr, ";
+    OS << NumberedInstructions.size();
+
+    if (NumClassesByHwMode != 0) {
+      OS << ", &" << TargetName << "RegClassByHwModeTables[0][0], "
+         << NumClassesByHwMode;
+    }
 
-  OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
+    OS << ");\n"
+          "}\n";
+  } // end GET_INSTRINFO_CTOR_DTOR scope.
 
   ArrayRef<const CodeGenInstruction *> TargetInstructions =
       Target.getTargetInstructions();
@@ -1384,8 +1355,6 @@ void InstrInfoEmitter::emitRecord(
 void InstrInfoEmitter::emitEnums(
     raw_ostream &OS,
     ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
-  OS << "#ifdef GET_INSTRINFO_ENUM\n";
-  OS << "#undef GET_INSTRINFO_ENUM\n";
 
   const CodeGenTarget &Target = CDP.getTargetInfo();
   StringRef Namespace = Target.getInstNamespace();
@@ -1393,48 +1362,48 @@ void InstrInfoEmitter::emitEnums(
   if (Namespace.empty())
     PrintFatalError("No instructions defined!");
 
-  OS << "namespace llvm::" << Namespace << " {\n";
+  {
+    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();
+    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 << "  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";
+    }
   }
-  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";
+  {
+    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";
   }
-
-  OS << "} // end namespace llvm::" << Namespace << '\n';
-  OS << "#endif // GET_INSTRINFO_ENUM\n\n";
-
-  OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
-  OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
-  OS << "namespace llvm::" << Namespace << "::Sched {\n";
-  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";
-  OS << "} // end namespace llvm::" << Namespace << "::Sched\n";
-
-  OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
 }
 
 static TableGen::Emitter::OptClass<InstrInfoEmitter>



More information about the llvm-commits mailing list