[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