From ef71226fcd0bbfe62f4ef71f72005fa98ea9ca24 Mon Sep 17 00:00:00 2001 From: Rahul Joshi Date: Wed, 18 Sep 2024 05:37:54 -0700 Subject: [PATCH] [LLVM][TableGen] Change WebAsm Emitter to use const RecordKeeper (#109051) Change WebAssemblyDisassemblerEmitter to use const RecordKeeper. This is a part of effort to have better const correctness in TableGen backends: https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089 --- llvm/include/llvm/TableGen/Record.h | 1 + llvm/lib/TableGen/Record.cpp | 20 ++++++---- .../WebAssemblyDisassemblerEmitter.cpp | 39 +++++++------------ .../TableGen/WebAssemblyDisassemblerEmitter.h | 3 +- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index c9e01e3f221b..f1420731d690 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -603,6 +603,7 @@ public: Init *convertInitializerTo(RecTy *Ty) const override; Init *convertInitializerBitRange(ArrayRef Bits) const override; + std::optional convertInitializerToInt() const; bool isComplete() const override { for (unsigned i = 0; i != getNumBits(); ++i) diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 97ae0b092b81..567545ec02f6 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -497,18 +497,24 @@ Init *BitsInit::convertInitializerTo(RecTy *Ty) const { } if (isa(Ty)) { - int64_t Result = 0; - for (unsigned i = 0, e = getNumBits(); i != e; ++i) - if (auto *Bit = dyn_cast(getBit(i))) - Result |= static_cast(Bit->getValue()) << i; - else - return nullptr; - return IntInit::get(getRecordKeeper(), Result); + std::optional Result = convertInitializerToInt(); + if (Result) + return IntInit::get(getRecordKeeper(), *Result); } return nullptr; } +std::optional BitsInit::convertInitializerToInt() const { + int64_t Result = 0; + for (unsigned i = 0, e = getNumBits(); i != e; ++i) + if (auto *Bit = dyn_cast(getBit(i))) + Result |= static_cast(Bit->getValue()) << i; + else + return std::nullopt; + return Result; +} + Init * BitsInit::convertInitializerBitRange(ArrayRef Bits) const { SmallVector NewBits(Bits.size()); diff --git a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp index e9436ab16e44..7373494e8b12 100644 --- a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp +++ b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp @@ -19,28 +19,23 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Record.h" -namespace llvm { - static constexpr int WebAssemblyInstructionTableSize = 256; -void emitWebAssemblyDisassemblerTables( +void llvm::emitWebAssemblyDisassemblerTables( raw_ostream &OS, - const ArrayRef &NumberedInstructions) { + ArrayRef NumberedInstructions) { // First lets organize all opcodes by (prefix) byte. Prefix 0 is the // starting table. std::map>> OpcodeTable; for (unsigned I = 0; I != NumberedInstructions.size(); ++I) { - auto &CGI = *NumberedInstructions[I]; - auto &Def = *CGI.TheDef; + const CodeGenInstruction &CGI = *NumberedInstructions[I]; + const Record &Def = *CGI.TheDef; if (!Def.getValue("Inst")) continue; - auto &Inst = *Def.getValueAsBitsInit("Inst"); - RecordKeeper &RK = Inst.getRecordKeeper(); - unsigned Opc = static_cast( - cast(Inst.convertInitializerTo(IntRecTy::get(RK))) - ->getValue()); + const BitsInit &Inst = *Def.getValueAsBitsInit("Inst"); + unsigned Opc = static_cast(*Inst.convertInitializerToInt()); if (Opc == 0xFFFFFFFF) continue; // No opcode defined. assert(Opc <= 0xFFFFFF); @@ -97,14 +92,14 @@ void emitWebAssemblyDisassemblerTables( OS << "};\n\n"; std::vector OperandTable, CurOperandList; // Output one table per prefix. - for (auto &PrefixPair : OpcodeTable) { - if (PrefixPair.second.empty()) + for (const auto &[Prefix, Table] : OpcodeTable) { + if (Table.empty()) continue; - OS << "WebAssemblyInstruction InstructionTable" << PrefixPair.first; + OS << "WebAssemblyInstruction InstructionTable" << Prefix; OS << "[] = {\n"; for (unsigned I = 0; I < WebAssemblyInstructionTableSize; I++) { - auto InstIt = PrefixPair.second.find(I); - if (InstIt != PrefixPair.second.end()) { + auto InstIt = Table.find(I); + if (InstIt != Table.end()) { // Regular instruction. assert(InstIt->second.second); auto &CGI = *InstIt->second.second; @@ -144,7 +139,7 @@ void emitWebAssemblyDisassemblerTables( } else { auto PrefixIt = OpcodeTable.find(I); // If we have a non-empty table for it that's not 0, this is a prefix. - if (PrefixIt != OpcodeTable.end() && I && !PrefixPair.first) { + if (PrefixIt != OpcodeTable.end() && I && !Prefix) { OS << " { 0, ET_Prefix, 0, 0"; } else { OS << " { 0, ET_Unused, 0, 0"; @@ -163,15 +158,11 @@ void emitWebAssemblyDisassemblerTables( // Create a table of all extension tables: OS << "struct { uint8_t Prefix; const WebAssemblyInstruction *Table; }\n"; OS << "PrefixTable[] = {\n"; - for (auto &PrefixPair : OpcodeTable) { - if (PrefixPair.second.empty() || !PrefixPair.first) + for (const auto &[Prefix, Table] : OpcodeTable) { + if (Table.empty() || !Prefix) continue; - OS << " { " << PrefixPair.first << ", InstructionTable" - << PrefixPair.first; - OS << " },\n"; + OS << " { " << Prefix << ", InstructionTable" << Prefix << " },\n"; } OS << " { 0, nullptr }\n};\n\n"; OS << "} // end namespace llvm\n"; } - -} // namespace llvm diff --git a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.h b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.h index aba3a4bfd302..2d814cf0675a 100644 --- a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.h +++ b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.h @@ -22,8 +22,7 @@ class CodeGenInstruction; class raw_ostream; void emitWebAssemblyDisassemblerTables( - raw_ostream &OS, - const ArrayRef &NumberedInstructions); + raw_ostream &OS, ArrayRef NumberedInstructions); } // namespace llvm