Skip to content

[TableGen] Fixes for per-HwMode decoding problem. #82201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions llvm/test/TableGen/HwModeEncodeDecode.td
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ def baz : Instruction {
// DECODER-DAG: Opcode: fooTypeEncA:foo
// DECODER-DAG: Opcode: bar
// DECODER-LABEL: DecoderTable_ModeB32[] =
// Note that the comment says fooTypeEncA but this is actually fooTypeEncB; plumbing
// the correct comment text through the decoder is nontrivial.
// DECODER-DAG: Opcode: fooTypeEncA:foo
// DECODER-DAG: Opcode: fooTypeEncB:foo
// DECODER-DAG: Opcode: fooTypeEncA:baz
// DECODER-DAG: Opcode: bar

// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = {
Expand Down
35 changes: 23 additions & 12 deletions llvm/utils/TableGen/DecoderEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ struct EncodingIDAndOpcode {
: EncodingID(EncodingID), Opcode(Opcode) {}
};

using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;

raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
if (Value.EncodingDef != Value.Inst->TheDef)
OS << Value.EncodingDef->getName() << ":";
Expand All @@ -135,8 +137,8 @@ class DecoderEmitter {

// Emit the decoder state machine table.
void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
unsigned Indentation, unsigned BitWidth,
StringRef Namespace) const;
unsigned Indentation, unsigned BitWidth, StringRef Namespace,
const EncodingIDsVec &EncodingIDs) const;
void emitInstrLenTable(formatted_raw_ostream &OS,
std::vector<unsigned> &InstrLen) const;
void emitPredicateFunction(formatted_raw_ostream &OS,
Expand Down Expand Up @@ -766,7 +768,16 @@ unsigned Filter::usefulness() const {
// Emit the decoder state machine table.
void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
unsigned Indentation, unsigned BitWidth,
StringRef Namespace) const {
StringRef Namespace,
const EncodingIDsVec &EncodingIDs) const {
// We'll need to be able to map from a decoded opcode into the corresponding
// EncodingID for this specific combination of BitWidth and Namespace. This
// is used below to index into NumberedEncodings.
DenseMap<unsigned, unsigned> OpcodeToEncodingID;
OpcodeToEncodingID.reserve(EncodingIDs.size());
for (auto &EI : EncodingIDs)
OpcodeToEncodingID[EI.Opcode] = EI.EncodingID;

OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
<< BitWidth << "[] = {\n";

Expand Down Expand Up @@ -888,8 +899,12 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
// Decoder index.
I += emitULEB128(I, OS);

auto EncI = OpcodeToEncodingID.find(Opc);
assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
auto EncodingID = EncI->second;

if (!IsTry) {
OS << "// Opcode: " << NumberedEncodings[Opc] << "\n";
OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n";
break;
}

Expand All @@ -899,7 +914,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
uint32_t NumToSkip = emitNumToSkip(I, OS);
I += 3;

OS << "// Opcode: " << NumberedEncodings[Opc]
OS << "// Opcode: " << NumberedEncodings[EncodingID]
<< ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
break;
}
Expand Down Expand Up @@ -2449,11 +2464,8 @@ void DecoderEmitter::run(raw_ostream &o) {
std::set<StringRef> HwModeNames;
const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
NumberedEncodings.reserve(NumberedInstructions.size());
DenseMap<Record *, unsigned> IndexOfInstruction;
// First, collect all HwModes referenced by the target.
for (const auto &NumberedInstruction : NumberedInstructions) {
IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();

if (const RecordVal *RV =
NumberedInstruction->TheDef->getValue("EncodingInfos")) {
if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
Expand All @@ -2470,8 +2482,6 @@ void DecoderEmitter::run(raw_ostream &o) {
HwModeNames.insert("");

for (const auto &NumberedInstruction : NumberedInstructions) {
IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();

if (const RecordVal *RV =
NumberedInstruction->TheDef->getValue("EncodingInfos")) {
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
Expand Down Expand Up @@ -2544,7 +2554,7 @@ void DecoderEmitter::run(raw_ostream &o) {
DecoderNamespace +=
std::string("_") + NumberedEncodings[i].HwModeName.str();
OpcMap[std::pair(DecoderNamespace, Size)].emplace_back(
i, IndexOfInstruction.find(Def)->second);
i, Target.getInstrIntValue(Def));
} else {
NumEncodingsOmitted++;
}
Expand Down Expand Up @@ -2577,7 +2587,8 @@ void DecoderEmitter::run(raw_ostream &o) {
TableInfo.Table.push_back(MCD::OPC_Fail);

// Print the table to the output stream.
emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first);
emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first,
Opc.second);
}

// For variable instruction, we emit a instruction length table
Expand Down