Skip to content

Conversation

@jurahul
Copy link
Contributor

@jurahul jurahul commented Nov 4, 2025

Adopt IfDefEmitter and NamespaceEmitter in InstrInfoEmitter

@jurahul jurahul marked this pull request as ready for review November 4, 2025 23:58
@jurahul jurahul requested a review from arsenm November 4, 2025 23:58
@llvmbot
Copy link
Member

llvmbot commented Nov 4, 2025

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

Changes

Patch is 51.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/166442.diff

3 Files Affected:

  • (modified) llvm/test/TableGen/RegClassByHwMode.td (+8-5)
  • (modified) llvm/test/TableGen/get-named-operand-idx.td (+12-4)
  • (modified) llvm/utils/TableGen/InstrInfoEmitter.cpp (+530-561)
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);
+
+    s...
[truncated]

@jurahul
Copy link
Contributor Author

jurahul commented Nov 5, 2025

Would help if you see the diff with whitespace diffs disabled, as there are several indentation changes.

@jurahul jurahul requested a review from arsenm November 5, 2025 00:41
@jurahul jurahul merged commit a1640c1 into llvm:main Nov 6, 2025
10 checks passed
@jurahul jurahul deleted the nfc_adropt_cghelpers_instrinfoemitter branch November 6, 2025 15:49
vinay-deshmukh pushed a commit to vinay-deshmukh/llvm-project that referenced this pull request Nov 8, 2025
Adopt `IfDefEmitter` and `NamespaceEmitter` in InstrInfoEmitter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants