From a09eb707d334b07bbcd8c2d47ed6729a4e288f6a Mon Sep 17 00:00:00 2001 From: Rahul Joshi Date: Thu, 4 Sep 2025 14:58:35 -0700 Subject: [PATCH] [NFC][TableGen] Use `BitsInit::convertInitializerToInt` in a few places Replace manual code to convert a `BitsInit` to a uint64_t by using `convertInitializerToInt`. --- llvm/include/llvm/TableGen/Record.h | 3 +++ llvm/lib/TableGen/Record.cpp | 8 ++++++ llvm/utils/TableGen/DFAEmitter.cpp | 9 +------ llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 ++++------ llvm/utils/TableGen/RegisterInfoEmitter.cpp | 6 +---- llvm/utils/TableGen/X86FoldTablesEmitter.cpp | 12 --------- .../utils/TableGen/X86InstrMappingEmitter.cpp | 12 --------- llvm/utils/TableGen/X86RecognizableInstr.cpp | 26 +------------------ llvm/utils/TableGen/X86RecognizableInstr.h | 12 +++++++++ 9 files changed, 31 insertions(+), 71 deletions(-) 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 Bits) const override; std::optional 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 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(InitV)) + Result |= static_cast(Bit->getValue()) << Idx; + return Result; +} + const Init * BitsInit::convertInitializerBitRange(ArrayRef Bits) const { SmallVector 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(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(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(TSF->getBit(i))) - Value |= uint64_t(Bit->getValue()) << i; - else - PrintFatalError(Inst.TheDef->getLoc(), - "Invalid TSFlags bit in " + Inst.getName()); - } + std::optional 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(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(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 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(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(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(*B->convertInitializerToInt()); +} + } // namespace X86Disassembler } // namespace llvm #endif