[llvm] [NFC][TableGen] Add accessors for various instruction subclasses (PR #146615)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 2 06:01:50 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

<details>
<summary>Changes</summary>

- Add various instruction subclass/sub-slice accessors to `CodeGenTarget`.
- Delete unused `inst_begin` and `inst_end` iterators.
- Rename `Instructions` to `InstructionMap` and `getInstructions` to `getInstructionMap` to better represent their meaning.
- Use these new accessors in InstrInfoEmitter

---
Full diff: https://github.com/llvm/llvm-project/pull/146615.diff


4 Files Affected:

- (modified) llvm/utils/TableGen/Common/CodeGenSchedule.cpp (+7-9) 
- (modified) llvm/utils/TableGen/Common/CodeGenTarget.cpp (+12-12) 
- (modified) llvm/utils/TableGen/Common/CodeGenTarget.h (+27-21) 
- (modified) llvm/utils/TableGen/InstrInfoEmitter.cpp (+17-13) 


``````````diff
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index a93b5be01754f..35c1ffb78ce8e 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -77,14 +77,12 @@ struct InstRegexOp : public SetTheory::Operator {
 
   void apply(SetTheory &ST, const DagInit *Expr, SetTheory::RecSet &Elts,
              ArrayRef<SMLoc> Loc) override {
-    ArrayRef<const CodeGenInstruction *> Instructions =
-        Target.getInstructionsByEnumValue();
-
-    unsigned NumGeneric = Target.getNumFixedInstructions();
-    unsigned NumPseudos = Target.getNumPseudoInstructions();
-    auto Generics = Instructions.slice(0, NumGeneric);
-    auto Pseudos = Instructions.slice(NumGeneric, NumPseudos);
-    auto NonPseudos = Instructions.slice(NumGeneric + NumPseudos);
+    ArrayRef<const CodeGenInstruction *> Generics =
+        Target.getGenericInstructionsByEnumValue();
+    ArrayRef<const CodeGenInstruction *> Pseudos =
+        Target.getTargetPseudoInstructionsByEnumValue();
+    ArrayRef<const CodeGenInstruction *> NonPseudos =
+        Target.getTargetNonPseudoInstructionsByEnumValue();
 
     for (const Init *Arg : Expr->getArgs()) {
       const StringInit *SI = dyn_cast<StringInit>(Arg);
@@ -145,7 +143,7 @@ struct InstRegexOp : public SetTheory::Operator {
       }
 
       // Target instructions are split into two ranges: pseudo instructions
-      // first, than non-pseudos. Each range is in lexicographical order
+      // first, then non-pseudos. Each range is in lexicographical order
       // sorted by name. Find the sub-ranges that start with our prefix.
       struct Comp {
         bool operator()(const CodeGenInstruction *LHS, StringRef RHS) {
diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
index f519582387db9..7f39ae17b5c14 100644
--- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
@@ -211,10 +211,9 @@ void CodeGenTarget::ReadInstructions() const {
 
   // Parse the instructions defined in the .td file.
   for (const Record *R : Insts) {
-    auto &Inst = Instructions[R];
+    auto &Inst = InstructionMap[R];
     Inst = std::make_unique<CodeGenInstruction>(R);
-    if (Inst->isVariableLengthEncoding())
-      HasVariableLengthEncodings = true;
+    HasVariableLengthEncodings |= Inst->isVariableLengthEncoding();
   }
 }
 
@@ -242,9 +241,9 @@ unsigned CodeGenTarget::getNumFixedInstructions() {
 /// Return all of the instructions defined by the target, ordered by
 /// their enum value.
 void CodeGenTarget::ComputeInstrsByEnum() const {
-  const auto &Insts = getInstructions();
+  const auto &InstMap = getInstructionMap();
   for (const char *Name : FixedInstrs) {
-    const CodeGenInstruction *Instr = GetInstByName(Name, Insts, Records);
+    const CodeGenInstruction *Instr = GetInstByName(Name, InstMap, Records);
     assert(Instr && "Missing target independent instruction");
     assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
     InstrsByEnum.push_back(Instr);
@@ -253,23 +252,24 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
   assert(EndOfPredefines == getNumFixedInstructions() &&
          "Missing generic opcode");
 
-  for (const auto &I : Insts) {
-    const CodeGenInstruction *CGI = I.second.get();
+  for (const auto &[_, CGIUp] : InstMap) {
+    const CodeGenInstruction *CGI = CGIUp.get();
     if (CGI->Namespace != "TargetOpcode") {
       InstrsByEnum.push_back(CGI);
-      if (CGI->TheDef->getValueAsBit("isPseudo"))
-        ++NumPseudoInstructions;
+      NumPseudoInstructions += CGI->TheDef->getValueAsBit("isPseudo");
     }
   }
 
-  assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
+  assert(InstrsByEnum.size() == InstMap.size() && "Missing predefined instr");
 
   // All of the instructions are now in random order based on the map iteration.
   llvm::sort(
       InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
       [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
-        const auto &D1 = *Rec1->TheDef;
-        const auto &D2 = *Rec2->TheDef;
+        const Record &D1 = *Rec1->TheDef;
+        const Record &D2 = *Rec2->TheDef;
+        // Sort all pseudo instructions before non-pseudo ones, and sort by name
+        // within.
         return std::tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) <
                std::tuple(!D2.getValueAsBit("isPseudo"), D2.getName());
       });
diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.h b/llvm/utils/TableGen/Common/CodeGenTarget.h
index 52871f33a301a..191647c114791 100644
--- a/llvm/utils/TableGen/Common/CodeGenTarget.h
+++ b/llvm/utils/TableGen/Common/CodeGenTarget.h
@@ -59,7 +59,7 @@ class CodeGenTarget {
   const Record *TargetRec;
 
   mutable DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>>
-      Instructions;
+      InstructionMap;
   mutable std::unique_ptr<CodeGenRegBank> RegBank;
   mutable ArrayRef<const Record *> RegAltNameIndices;
   mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
@@ -154,31 +154,22 @@ class CodeGenTarget {
 
 private:
   DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>> &
-  getInstructions() const {
-    if (Instructions.empty())
+  getInstructionMap() const {
+    if (InstructionMap.empty())
       ReadInstructions();
-    return Instructions;
+    return InstructionMap;
   }
 
 public:
   CodeGenInstruction &getInstruction(const Record *InstRec) const {
-    if (Instructions.empty())
-      ReadInstructions();
-    auto I = Instructions.find(InstRec);
-    assert(I != Instructions.end() && "Not an instruction");
+    auto I = getInstructionMap().find(InstRec);
+    assert(I != InstructionMap.end() && "Not an instruction");
     return *I->second;
   }
 
   /// Returns the number of predefined instructions.
   static unsigned getNumFixedInstructions();
 
-  /// Returns the number of pseudo instructions.
-  unsigned getNumPseudoInstructions() const {
-    if (InstrsByEnum.empty())
-      ComputeInstrsByEnum();
-    return NumPseudoInstructions;
-  }
-
   /// Return all of the instructions defined by the target, ordered by their
   /// enum value.
   /// The following order of instructions is also guaranteed:
@@ -191,6 +182,27 @@ class CodeGenTarget {
     return InstrsByEnum;
   }
 
+  // Functions that return various slices of `getInstructionsByEnumValue`.
+  ArrayRef<const CodeGenInstruction *>
+  getGenericInstructionsByEnumValue() const {
+    return getInstructionsByEnumValue().take_front(getNumFixedInstructions());
+  }
+
+  ArrayRef<const CodeGenInstruction *>
+  getTargetInstructionsByEnumValue() const {
+    return getInstructionsByEnumValue().drop_front(getNumFixedInstructions());
+  }
+
+  ArrayRef<const CodeGenInstruction *>
+  getTargetPseudoInstructionsByEnumValue() const {
+    return getTargetInstructionsByEnumValue().take_front(NumPseudoInstructions);
+  }
+
+  ArrayRef<const CodeGenInstruction *>
+  getTargetNonPseudoInstructionsByEnumValue() const {
+    return getTargetInstructionsByEnumValue().drop_front(NumPseudoInstructions);
+  }
+
   /// Return the integer enum value corresponding to this instruction record.
   unsigned getInstrIntValue(const Record *R) const {
     if (InstrsByEnum.empty())
@@ -198,12 +210,6 @@ class CodeGenTarget {
     return getInstruction(R).EnumVal;
   }
 
-  typedef ArrayRef<const CodeGenInstruction *>::const_iterator inst_iterator;
-  inst_iterator inst_begin() const {
-    return getInstructionsByEnumValue().begin();
-  }
-  inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); }
-
   /// Return whether instructions have variable length encodings on this target.
   bool hasVariableLengthEncodings() const { return HasVariableLengthEncodings; }
 
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index e72055b0b5037..fcdc1b7086d24 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -91,10 +91,10 @@ class InstrInfoEmitter {
       ArrayRef<const CodeGenInstruction *> NumberedInstructions);
   void emitOperandNameMappings(
       raw_ostream &OS, const CodeGenTarget &Target,
-      ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+      ArrayRef<const CodeGenInstruction *> TargetInstructions);
   void emitLogicalOperandSizeMappings(
       raw_ostream &OS, StringRef Namespace,
-      ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+      ArrayRef<const CodeGenInstruction *> TargetInstructions);
 
   // Operand information.
   unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
@@ -234,9 +234,13 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
 /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
 ///   for looking up the operand index for an instruction, given a value from
 ///   OpName enum
+///
+/// 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 *> NumberedInstructions) {
+    ArrayRef<const CodeGenInstruction *> TargetInstructions) {
   StringRef Namespace = Target.getInstNamespace();
 
   /// To facilitate assigning OpName enum values in the sorted alphabetical
@@ -260,9 +264,7 @@ void InstrInfoEmitter::emitOperandNameMappings(
 
   // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
   // we can just skip them.
-  const unsigned NumFixedInsts = Target.getNumFixedInstructions();
-  for (const CodeGenInstruction *Inst :
-       NumberedInstructions.drop_front(NumFixedInsts)) {
+  for (const CodeGenInstruction *Inst : TargetInstructions) {
     if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
       continue;
     std::map<unsigned, unsigned> OpList;
@@ -476,19 +478,18 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\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 *> NumberedInstructions) {
+    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;
 
-  // Fixed/Predefined instructions do not have UseLogicalOperandMappings
-  // enabled, so we can just skip them.
-  const unsigned NumFixedInsts = CDP.getTargetInfo().getNumFixedInstructions();
-  for (const auto *Inst : NumberedInstructions.drop_front(NumFixedInsts)) {
+  for (const auto *Inst : TargetInstructions) {
     if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
       continue;
 
@@ -1057,9 +1058,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
 
   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
 
+  ArrayRef<const CodeGenInstruction *> TargetInstructions =
+      Target.getTargetInstructionsByEnumValue();
+
   if (HasUseNamedOperandTable) {
     Timer.startTimer("Emit operand name mappings");
-    emitOperandNameMappings(OS, Target, NumberedInstructions);
+    emitOperandNameMappings(OS, Target, TargetInstructions);
   }
 
   Timer.startTimer("Emit operand type mappings");
@@ -1067,7 +1071,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
 
   if (HasUseLogicalOperandMappings) {
     Timer.startTimer("Emit logical operand size mappings");
-    emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions);
+    emitLogicalOperandSizeMappings(OS, TargetName, TargetInstructions);
   }
 
   Timer.startTimer("Emit helper methods");

``````````

</details>


https://github.com/llvm/llvm-project/pull/146615


More information about the llvm-commits mailing list