[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:
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user