-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[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:
|
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? |
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
…#142974) 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 `decodeInstruction` function. This results in the following reduction in the size of the Disassembler .so files with a release x86_64 release build on Linux: ``` Target Old Size New Size % reduction build/lib/libLLVMAArch64Disassembler.so.21.0git 256656 256656 0.00 build/lib/libLLVMAMDGPUDisassembler.so.21.0git 813000 808168 0.59 build/lib/libLLVMARCDisassembler.so.21.0git 44816 43536 2.86 build/lib/libLLVMARMDisassembler.so.21.0git 281744 278808 1.04 build/lib/libLLVMAVRDisassembler.so.21.0git 36040 34496 4.28 build/lib/libLLVMBPFDisassembler.so.21.0git 26248 23168 11.73 build/lib/libLLVMCSKYDisassembler.so.21.0git 55960 53632 4.16 build/lib/libLLVMHexagonDisassembler.so.21.0git 115952 113416 2.19 build/lib/libLLVMLanaiDisassembler.so.21.0git 24360 21008 13.76 build/lib/libLLVMLoongArchDisassembler.so.21.0git 58584 56168 4.12 build/lib/libLLVMM68kDisassembler.so.21.0git 57264 53880 5.91 build/lib/libLLVMMSP430Disassembler.so.21.0git 28896 28440 1.58 build/lib/libLLVMMipsDisassembler.so.21.0git 123128 120568 2.08 build/lib/libLLVMPowerPCDisassembler.so.21.0git 80656 78096 3.17 build/lib/libLLVMRISCVDisassembler.so.21.0git 154080 150200 2.52 build/lib/libLLVMSparcDisassembler.so.21.0git 42040 39568 5.88 build/lib/libLLVMSystemZDisassembler.so.21.0git 97056 94552 2.58 build/lib/libLLVMVEDisassembler.so.21.0git 83944 81352 3.09 build/lib/libLLVMWebAssemblyDisassembler.so.21.0git 25280 25280 0.00 build/lib/libLLVMX86Disassembler.so.21.0git 2920624 2920624 0.00 build/lib/libLLVMXCoreDisassembler.so.21.0git 48320 44288 8.34 build/lib/libLLVMXtensaDisassembler.so.21.0git 42248 35840 15.17 ```
…#142974) 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 `decodeInstruction` function. This results in the following reduction in the size of the Disassembler .so files with a release x86_64 release build on Linux: ``` Target Old Size New Size % reduction build/lib/libLLVMAArch64Disassembler.so.21.0git 256656 256656 0.00 build/lib/libLLVMAMDGPUDisassembler.so.21.0git 813000 808168 0.59 build/lib/libLLVMARCDisassembler.so.21.0git 44816 43536 2.86 build/lib/libLLVMARMDisassembler.so.21.0git 281744 278808 1.04 build/lib/libLLVMAVRDisassembler.so.21.0git 36040 34496 4.28 build/lib/libLLVMBPFDisassembler.so.21.0git 26248 23168 11.73 build/lib/libLLVMCSKYDisassembler.so.21.0git 55960 53632 4.16 build/lib/libLLVMHexagonDisassembler.so.21.0git 115952 113416 2.19 build/lib/libLLVMLanaiDisassembler.so.21.0git 24360 21008 13.76 build/lib/libLLVMLoongArchDisassembler.so.21.0git 58584 56168 4.12 build/lib/libLLVMM68kDisassembler.so.21.0git 57264 53880 5.91 build/lib/libLLVMMSP430Disassembler.so.21.0git 28896 28440 1.58 build/lib/libLLVMMipsDisassembler.so.21.0git 123128 120568 2.08 build/lib/libLLVMPowerPCDisassembler.so.21.0git 80656 78096 3.17 build/lib/libLLVMRISCVDisassembler.so.21.0git 154080 150200 2.52 build/lib/libLLVMSparcDisassembler.so.21.0git 42040 39568 5.88 build/lib/libLLVMSystemZDisassembler.so.21.0git 97056 94552 2.58 build/lib/libLLVMVEDisassembler.so.21.0git 83944 81352 3.09 build/lib/libLLVMWebAssemblyDisassembler.so.21.0git 25280 25280 0.00 build/lib/libLLVMX86Disassembler.so.21.0git 2920624 2920624 0.00 build/lib/libLLVMXCoreDisassembler.so.21.0git 48320 44288 8.34 build/lib/libLLVMXtensaDisassembler.so.21.0git 42248 35840 15.17 ```
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
decodeInstruction
function.This results in the following reduction in the size of the Disassembler .so files with a release x86_64 release build on Linux: