[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
This commit is contained in:
Rahul Joshi
2024-09-18 05:37:54 -07:00
committed by GitHub
parent 2bb3621faa
commit ef71226fcd
4 changed files with 30 additions and 33 deletions

View File

@@ -603,6 +603,7 @@ public:
Init *convertInitializerTo(RecTy *Ty) const override;
Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
std::optional<int64_t> convertInitializerToInt() const;
bool isComplete() const override {
for (unsigned i = 0; i != getNumBits(); ++i)

View File

@@ -497,18 +497,24 @@ Init *BitsInit::convertInitializerTo(RecTy *Ty) const {
}
if (isa<IntRecTy>(Ty)) {
int64_t Result = 0;
for (unsigned i = 0, e = getNumBits(); i != e; ++i)
if (auto *Bit = dyn_cast<BitInit>(getBit(i)))
Result |= static_cast<int64_t>(Bit->getValue()) << i;
else
return nullptr;
return IntInit::get(getRecordKeeper(), Result);
std::optional<int64_t> Result = convertInitializerToInt();
if (Result)
return IntInit::get(getRecordKeeper(), *Result);
}
return nullptr;
}
std::optional<int64_t> BitsInit::convertInitializerToInt() const {
int64_t Result = 0;
for (unsigned i = 0, e = getNumBits(); i != e; ++i)
if (auto *Bit = dyn_cast<BitInit>(getBit(i)))
Result |= static_cast<int64_t>(Bit->getValue()) << i;
else
return std::nullopt;
return Result;
}
Init *
BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
SmallVector<Init *, 16> NewBits(Bits.size());

View File

@@ -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<const CodeGenInstruction *> &NumberedInstructions) {
ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
// First lets organize all opcodes by (prefix) byte. Prefix 0 is the
// starting table.
std::map<unsigned,
std::map<unsigned, std::pair<unsigned, const CodeGenInstruction *>>>
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<unsigned>(
cast<IntInit>(Inst.convertInitializerTo(IntRecTy::get(RK)))
->getValue());
const BitsInit &Inst = *Def.getValueAsBitsInit("Inst");
unsigned Opc = static_cast<unsigned>(*Inst.convertInitializerToInt());
if (Opc == 0xFFFFFFFF)
continue; // No opcode defined.
assert(Opc <= 0xFFFFFF);
@@ -97,14 +92,14 @@ void emitWebAssemblyDisassemblerTables(
OS << "};\n\n";
std::vector<std::string> 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

View File

@@ -22,8 +22,7 @@ class CodeGenInstruction;
class raw_ostream;
void emitWebAssemblyDisassemblerTables(
raw_ostream &OS,
const ArrayRef<const CodeGenInstruction *> &NumberedInstructions);
raw_ostream &OS, ArrayRef<const CodeGenInstruction *> NumberedInstructions);
} // namespace llvm