-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[NFCI][TableGen][DecoderEmitter] Cull Op handling when possible #142974
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
Conversation
TryDecode when possibleTryDecode handling when possible
|
@llvm/pr-subscribers-tablegen Author: Rahul Joshi (jurahul) Changes
Full diff: https://github.com/llvm/llvm-project/pull/142974.diff 1 Files Affected:
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 3990836e9077f..ec12eab8ac4ca 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -223,8 +223,9 @@ class DecoderEmitter {
DecoderEmitter(const RecordKeeper &R, StringRef PredicateNamespace)
: RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}
- // Emit the decoder state machine table.
- void emitTable(formatted_raw_ostream &OS, DecoderTable &Table, indent Indent,
+ // Emit the decoder state machine table. Return true if any `TryDecode` ops
+ // were generated.
+ bool emitTable(formatted_raw_ostream &OS, DecoderTable &Table, indent Indent,
unsigned BitWidth, StringRef Namespace,
const EncodingIDsVec &EncodingIDs) const;
void emitInstrLenTable(formatted_raw_ostream &OS,
@@ -828,7 +829,7 @@ unsigned Filter::usefulness() const {
//////////////////////////////////
// Emit the decoder state machine table.
-void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
+bool DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
indent Indent, unsigned BitWidth,
StringRef Namespace,
const EncodingIDsVec &EncodingIDs) const {
@@ -885,6 +886,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
OS << " (Fail)";
};
+ bool HasTryDecode = false;
+
while (I != E) {
assert(I < E && "incomplete decode table entry!");
@@ -965,6 +968,7 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
case MCD::OPC_TryDecodeOrFail: {
bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
bool IsTry = DecoderOp == MCD::OPC_TryDecode || IsFail;
+ HasTryDecode |= IsTry;
// Decode the Opcode value.
const char *ErrMsg = nullptr;
unsigned Opc = decodeULEB128(&*I, nullptr, EndPtr, &ErrMsg);
@@ -1027,6 +1031,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
Indent -= 2;
OS << Indent << "};\n\n";
+
+ return HasTryDecode;
}
void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
@@ -2217,8 +2223,8 @@ static void insertBits(InsnType &field, InsnType bits, unsigned startBit,
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
-static void emitDecodeInstruction(formatted_raw_ostream &OS,
- bool IsVarLenInst) {
+static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
+ bool HasTryDecode) {
OS << R"(
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
unsigned NumToSkip = *Ptr++;
@@ -2363,7 +2369,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
<< ", using decoder " << DecodeIdx << ": "
<< (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
return S;
- }
+ })";
+ if (HasTryDecode) {
+ OS << R"(
case MCD::OPC_TryDecode:
case MCD::OPC_TryDecodeOrFail: {
bool IsFail = DecoderOp == MCD::OPC_TryDecodeOrFail;
@@ -2398,7 +2406,9 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
// set before the decode attempt.
S = MCDisassembler::Success;
break;
- }
+ })";
+ }
+ OS << R"(
case MCD::OPC_SoftFail: {
// Decode the mask values.
uint64_t PositiveMask = decodeULEB128AndIncUnsafe(Ptr);
@@ -2608,6 +2618,7 @@ namespace {
}
DecoderTableInfo TableInfo;
+ bool HasTryDecode = false;
for (const auto &Opc : OpcMap) {
// Emit the decoder for this namespace+width combination.
ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
@@ -2633,8 +2644,8 @@ namespace {
TableInfo.Table.push_back(MCD::OPC_Fail);
// Print the table to the output stream.
- emitTable(OS, TableInfo.Table, indent(0), FC.getBitWidth(), Opc.first.first,
- Opc.second);
+ HasTryDecode |= emitTable(OS, TableInfo.Table, indent(0), FC.getBitWidth(),
+ Opc.first.first, Opc.second);
}
// For variable instruction, we emit a instruction length table
@@ -2649,7 +2660,7 @@ namespace {
emitDecoderFunction(OS, TableInfo.Decoders, indent(0));
// Emit the main entry point for the decoder, decodeInstruction().
- emitDecodeInstruction(OS, IsVarLenInst);
+ emitDecodeInstruction(OS, IsVarLenInst, HasTryDecode);
OS << "\n} // namespace\n";
}
|
|
Is there a measurable benefit to this? |
|
I did not do any measurements as it seemed simple to implement. The only benefit will be a minor reduction in code size as this eliminates dead code from each target's disassembler code. I suppose |
`TryDecode` MCD ops are not used by many targets (only AArch64 seems to generate it). Track whether any `TryDecode` or `TryDecodeOrFail` ops are generated and emit the code for handling them only in that case.
|
Here are the code size reductions based on a modified version of this: |
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Thanks. I have a new version that culls more with which I got the above results. Will ask for another review once that passes checks. |
TryDecode handling when possible|
I've now uploaded the new changes that does more aggressive culling (as a separate commit). @topperc this is what I used to get the results above. Can you PTAL again? |
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
TryDecode/CheckPredicate/SoftFail MCD ops are not used by many targets. Track the set of opcodes that were emitted and emit code for handling TryDecode/CheckPredicate/SoftFail ops when decoding only if there were emitted. This is purely eliminating dead code in the generated
decodeInstructionfunction.This results in the following reduction in the size of the Disassembler .so files with a release x86_64 release build on Linux: