[llvm] [NFC][TableGen] Use `BitsInit::convertInitializerToInt` in a few places (PR #156973)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 4 18:59:29 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tablegen

Author: Rahul Joshi (jurahul)

<details>
<summary>Changes</summary>

- Replace manual code to convert a `BitsInit` to a uint64_t by using `convertInitializerToInt` where applicable. 
- Add `BitsInit::convertKnownBitsToInt` to handle existing patterns in DFAEmitter.cpp and RegisterInfoEmitter.cpp.
- Consolidate 3 copies of the same function in X86 emitters into a single function.

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


9 Files Affected:

- (modified) llvm/include/llvm/TableGen/Record.h (+3) 
- (modified) llvm/lib/TableGen/Record.cpp (+8) 
- (modified) llvm/utils/TableGen/DFAEmitter.cpp (+1-8) 
- (modified) llvm/utils/TableGen/InstrInfoEmitter.cpp (+5-9) 
- (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+1-5) 
- (modified) llvm/utils/TableGen/X86FoldTablesEmitter.cpp (-12) 
- (modified) llvm/utils/TableGen/X86InstrMappingEmitter.cpp (-12) 
- (modified) llvm/utils/TableGen/X86RecognizableInstr.cpp (+1-25) 
- (modified) llvm/utils/TableGen/X86RecognizableInstr.h (+12) 


``````````diff
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 9d67d8b3b9293..d4fa1e5d65749 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -616,6 +616,9 @@ class BitsInit final : public TypedInit,
   convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
   std::optional<int64_t> convertInitializerToInt() const;
 
+  // Returns the set of known bits as a 64-bit integer.
+  uint64_t convertKnownBitsToInt() const;
+
   bool isComplete() const override;
   bool allInComplete() const;
   bool isConcrete() const override;
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 3657a15ab1989..051a896cfd1b4 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -525,6 +525,14 @@ std::optional<int64_t> BitsInit::convertInitializerToInt() const {
   return Result;
 }
 
+uint64_t BitsInit::convertKnownBitsToInt() const {
+  uint64_t Result = 0;
+  for (auto [Idx, InitV] : enumerate(getBits()))
+    if (auto *Bit = dyn_cast<BitInit>(InitV))
+      Result |= static_cast<int64_t>(Bit->getValue()) << Idx;
+  return Result;
+}
+
 const Init *
 BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
   SmallVector<const Init *, 16> NewBits(Bits.size());
diff --git a/llvm/utils/TableGen/DFAEmitter.cpp b/llvm/utils/TableGen/DFAEmitter.cpp
index 0b90af2ea99fc..65052e7881e1b 100644
--- a/llvm/utils/TableGen/DFAEmitter.cpp
+++ b/llvm/utils/TableGen/DFAEmitter.cpp
@@ -303,16 +303,9 @@ StringRef Automaton::getActionSymbolType(StringRef A) {
 
 Transition::Transition(const Record *R, Automaton *Parent) {
   const BitsInit *NewStateInit = R->getValueAsBitsInit("NewState");
-  NewState = 0;
   assert(NewStateInit->getNumBits() <= sizeof(uint64_t) * 8 &&
          "State cannot be represented in 64 bits!");
-  for (unsigned I = 0; I < NewStateInit->getNumBits(); ++I) {
-    if (auto *Bit = dyn_cast<BitInit>(NewStateInit->getBit(I))) {
-      if (Bit->getValue())
-        NewState |= 1ULL << I;
-    }
-  }
-
+  NewState = NewStateInit->convertKnownBitsToInt();
   for (StringRef A : Parent->getActionSymbolFields()) {
     const RecordVal *SymbolV = R->getValue(A);
     if (const auto *Ty = dyn_cast<RecordRecTy>(SymbolV->getType())) {
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 0fc421682c897..9e03e28a26d8d 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -1273,16 +1273,12 @@ void InstrInfoEmitter::emitRecord(
   const BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
   if (!TSF)
     PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?");
-  uint64_t Value = 0;
-  for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
-    if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
-      Value |= uint64_t(Bit->getValue()) << i;
-    else
-      PrintFatalError(Inst.TheDef->getLoc(),
-                      "Invalid TSFlags bit in " + Inst.getName());
-  }
+  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.write_hex(*Value);
   OS << "ULL";
 
   OS << " },  // " << Inst.getName() << '\n';
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 2a311b7ff96b8..c4b1c5f5a6d9d 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1107,11 +1107,7 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS) {
   for (const auto &RE : Regs) {
     const Record *Reg = RE.TheDef;
     const BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
-    uint64_t Value = 0;
-    for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
-      if (const BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
-        Value |= (uint64_t)B->getValue() << b;
-    }
+    uint64_t Value = BI->convertKnownBitsToInt();
     OS << "  " << Value << ",\n";
   }
   OS << "};\n"; // End of HW encoding table
diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index 762fae608bd19..b1f7b9a6b4ad9 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -245,18 +245,6 @@ static bool hasPtrTailcallRegClass(const CodeGenInstruction *Inst) {
   });
 }
 
-static uint8_t byteFromBitsInit(const BitsInit *B) {
-  unsigned N = B->getNumBits();
-  assert(N <= 8 && "Field is too large for uint8_t!");
-
-  uint8_t Value = 0;
-  for (unsigned I = 0; I != N; ++I) {
-    const BitInit *Bit = cast<BitInit>(B->getBit(I));
-    Value |= Bit->getValue() << I;
-  }
-  return Value;
-}
-
 static bool mayFoldFromForm(uint8_t Form) {
   switch (Form) {
   default:
diff --git a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
index 9f7e679edeeaa..be5e2a73e8d43 100644
--- a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
+++ b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
@@ -106,18 +106,6 @@ void X86InstrMappingEmitter::printTable(ArrayRef<Entry> Table, StringRef Name,
   printMacroEnd(Macro, OS);
 }
 
-static uint8_t byteFromBitsInit(const BitsInit *B) {
-  unsigned N = B->getNumBits();
-  assert(N <= 8 && "Field is too large for uint8_t!");
-
-  uint8_t Value = 0;
-  for (unsigned I = 0; I != N; ++I) {
-    const BitInit *Bit = cast<BitInit>(B->getBit(I));
-    Value |= Bit->getValue() << I;
-  }
-  return Value;
-}
-
 class IsMatch {
   const CodeGenInstruction *OldInst;
 
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index a56e07a8939e7..e87a1c9aa928e 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -72,30 +72,6 @@ unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) {
   llvm_unreachable("Memory operand's size not known!");
 }
 
-/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
-///   Useful for switch statements and the like.
-///
-/// @param init - A reference to the BitsInit to be decoded.
-/// @return     - The field, with the first bit in the BitsInit as the lowest
-///               order bit.
-static uint8_t byteFromBitsInit(const BitsInit &init) {
-  int width = init.getNumBits();
-
-  assert(width <= 8 && "Field is too large for uint8_t!");
-
-  uint8_t mask = 0x01;
-  uint8_t ret = 0;
-
-  for (int index = 0; index < width; index++) {
-    if (cast<BitInit>(init.getBit(index))->getValue())
-      ret |= mask;
-
-    mask <<= 1;
-  }
-
-  return ret;
-}
-
 /// byteFromRec - Extract a value at most 8 bits in with from a Record given the
 ///   name of the field.
 ///
@@ -104,7 +80,7 @@ static uint8_t byteFromBitsInit(const BitsInit &init) {
 /// @return     - The field, as translated by byteFromBitsInit().
 static uint8_t byteFromRec(const Record *rec, StringRef name) {
   const BitsInit *bits = rec->getValueAsBitsInit(name);
-  return byteFromBitsInit(*bits);
+  return byteFromBitsInit(bits);
 }
 
 RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h
index 2f60b99154796..b74e74dd3f6e7 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -383,6 +383,18 @@ bool isMemoryOperand(const Record *Rec);
 bool isImmediateOperand(const Record *Rec);
 unsigned getRegOperandSize(const Record *RegRec);
 unsigned getMemOperandSize(const Record *MemRec);
+
+/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
+///   Useful for switch statements and the like.
+///
+/// @param B - A pointer to the BitsInit to be decoded.
+/// @return  - The field, with the first bit in the BitsInit as the lowest
+///            order bit.
+inline uint8_t byteFromBitsInit(const BitsInit *B) {
+  assert(B->getNumBits() <= 8 && "Field is too large for uint8_t!");
+  return static_cast<uint8_t>(*B->convertInitializerToInt());
+}
+
 } // namespace X86Disassembler
 } // namespace llvm
 #endif

``````````

</details>


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


More information about the llvm-commits mailing list