-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[LLVM][MC] Introduce OrFail
variants of MCD ops
#138614
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
base: main
Are you sure you want to change the base?
Conversation
848d288
to
fb64757
Compare
fb64757
to
d9ec6d3
Compare
d9ec6d3
to
e99f469
Compare
@llvm/pr-subscribers-tablegen @llvm/pr-subscribers-backend-aarch64 Author: Rahul Joshi (jurahul) ChangesIntroduce The total reduction in the size of the decoder tables for different targets is as follows (computed using the following command:
Patch is 34.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138614.diff 9 Files Affected:
diff --git a/llvm/include/llvm/MC/MCDecoderOps.h b/llvm/include/llvm/MC/MCDecoderOps.h
index 3c0b68101e346..29d62988e888e 100644
--- a/llvm/include/llvm/MC/MCDecoderOps.h
+++ b/llvm/include/llvm/MC/MCDecoderOps.h
@@ -10,24 +10,29 @@
#ifndef LLVM_MC_MCDECODEROPS_H
#define LLVM_MC_MCDECODEROPS_H
-namespace llvm {
+namespace llvm::MCD {
-namespace MCD {
// Disassembler state machine opcodes.
+// nts_t is either uint16_t or uint24_t based on whether large decoder table is
+// enabled.
enum DecoderOps {
- OPC_ExtractField = 1, // OPC_ExtractField(uleb128 Start, uint8_t Len)
- OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
- OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len,
- // uleb128 Val, uint16_t NumToSkip)
- OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
- OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
- OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
- // uint16_t NumToSkip)
- OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
- OPC_Fail // OPC_Fail()
+ OPC_ExtractField = 1, // OPC_ExtractField(uleb128 Start, uint8_t Len)
+ OPC_FilterValue, // OPC_FilterValue(uleb128 Val, nts_t NumToSkip)
+ OPC_FilterValueOrFail, // OPC_FilterValueOrFail(uleb128 Val)
+ OPC_CheckField, // OPC_CheckField(uleb128 Start, uint8_t Len,
+ // uleb128 Val, nts_t NumToSkip)
+ OPC_CheckFieldOrFail, // OPC_ChecFieldOrFail(uleb128 Start, uint8_t Len,
+ // uleb128 Val)
+ OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, nts_t NumToSkip)
+ OPC_CheckPredicateOrFail, // OPC_CheckPredicateOrFail(uleb128 PIdx)
+ OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+ OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
+ // nts_t NumToSkip)
+ OPC_TryDecodeOrFail, // OPC_TryDecodeOrFail(uleb128 Opcode, uleb128 DIdx)
+ OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+ OPC_Fail // OPC_Fail()
};
-} // namespace MCD
-} // namespace llvm
+} // namespace llvm::MCD
#endif
diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index 583003f2f46e6..2300e479bc110 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -7,8 +7,7 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler
- --large-decoder-table)
+tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
diff --git a/llvm/test/TableGen/VarLenDecoder.td b/llvm/test/TableGen/VarLenDecoder.td
index db7a520533e85..06ff62294a196 100644
--- a/llvm/test/TableGen/VarLenDecoder.td
+++ b/llvm/test/TableGen/VarLenDecoder.td
@@ -47,19 +47,19 @@ def FOO32 : MyVarInst<MemOp32> {
);
}
-// CHECK-SMALL: MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
-// CHECK-SMALL-NEXT: MCD::OPC_FilterValue, 8, 4, 0, // Skip to: 11
-// CHECK-SMALL-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-SMALL-NEXT: MCD::OPC_FilterValue, 9, 4, 0, // Skip to: 19
-// CHECK-SMALL-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
-// CHECK-SMALL-NEXT: MCD::OPC_Fail,
+// CHECK-SMALL: /* 0 */ MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
+// CHECK-SMALL-NEXT: /* 3 */ MCD::OPC_FilterValue, 8, 4, 0, // Skip to: 11
+// CHECK-SMALL-NEXT: /* 7 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
+// CHECK-SMALL-NEXT: /* 11 */ MCD::OPC_FilterValueOrFail, 9,
+// CHECK-SMALL-NEXT: /* 13 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
+// CHECK-SMALL-NEXT: /* 17 */ MCD::OPC_Fail,
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12
// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
-// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_FilterValue, 9, 4, 0, 0, // Skip to: 21
-// CHECK-LARGE-NEXT: /* 17 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
-// CHECK-LARGE-NEXT: /* 21 */ MCD::OPC_Fail,
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_FilterValueOrFail, 9,
+// CHECK-LARGE-NEXT: /* 14 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
+// CHECK-LARGE-NEXT: /* 18 */ MCD::OPC_Fail,
// Instruction length table
// CHECK: 27,
@@ -88,7 +88,8 @@ def FOO32 : MyVarInst<MemOp32> {
// CHECK-LABEL: case MCD::OPC_ExtractField: {
// CHECK: makeUp(insn, Start + Len);
-// CHECK-LABEL: case MCD::OPC_CheckField: {
+// CHECK-LABEL: case MCD::OPC_CheckField:
+// CHECK-NEXT: case MCD::OPC_CheckFieldOrFail: {
// CHECK: makeUp(insn, Start + Len);
// CHECK-LABEL: case MCD::OPC_Decode: {
diff --git a/llvm/test/TableGen/trydecode-emission.td b/llvm/test/TableGen/trydecode-emission.td
index db77d94b2aa52..47d47c9c96183 100644
--- a/llvm/test/TableGen/trydecode-emission.td
+++ b/llvm/test/TableGen/trydecode-emission.td
@@ -35,11 +35,11 @@ def InstB : TestInstruction {
}
// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
-// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 16, 0, // Skip to: 23
-// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 19
-// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 19
-// CHECK-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-NEXT: /* 23 */ MCD::OPC_Fail,
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-NEXT: /* 5 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 17
+// CHECK-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 17
+// CHECK-NEXT: /* 17 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-NEXT: /* 21 */ MCD::OPC_Fail,
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
@@ -48,11 +48,11 @@ def InstB : TestInstruction {
// CHECK-NEXT: return NumToSkip;
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
-// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 18, 0, 0, // Skip to: 26
-// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 22
-// CHECK-LARGE-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 22
-// CHECK-LARGE-NEXT: /* 22 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-LARGE-NEXT: /* 26 */ MCD::OPC_Fail,
+// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-LARGE-NEXT: /* 5 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 19
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 19
+// CHECK-LARGE-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 23 */ MCD::OPC_Fail,
// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission2.td b/llvm/test/TableGen/trydecode-emission2.td
index 914e17c6f820c..593da63cd7616 100644
--- a/llvm/test/TableGen/trydecode-emission2.td
+++ b/llvm/test/TableGen/trydecode-emission2.td
@@ -32,27 +32,27 @@ def InstB : TestInstruction {
}
// CHECK: /* 0 */ MCD::OPC_ExtractField, 2, 1, // Inst{2} ...
-// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 31, 0, // Skip to: 38
-// CHECK-NEXT: /* 7 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
-// CHECK-NEXT: /* 10 */ MCD::OPC_FilterValue, 0, 24, 0, // Skip to: 38
-// CHECK-NEXT: /* 14 */ MCD::OPC_CheckField, 0, 2, 3, 6, 0, // Skip to: 26
-// CHECK-NEXT: /* 20 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 26
-// CHECK-NEXT: /* 26 */ MCD::OPC_CheckField, 3, 2, 0, 6, 0, // Skip to: 38
-// CHECK-NEXT: /* 32 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1, 0, 0, // Opcode: InstA, skip to: 38
-// CHECK-NEXT: /* 38 */ MCD::OPC_Fail,
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-NEXT: /* 5 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
+// CHECK-NEXT: /* 8 */ MCD::OPC_FilterValueOrFail, 0
+// CHECK-NEXT: /* 10 */ MCD::OPC_CheckField, 0, 2, 3, 6, 0, // Skip to: 22
+// CHECK-NEXT: /* 16 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 22
+// CHECK-NEXT: /* 22 */ MCD::OPC_CheckFieldOrFail, 3, 2, 0,
+// CHECK-NEXT: /* 26 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
+// CHECK-NEXT: /* 30 */ MCD::OPC_Fail,
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 2, 1, // Inst{2} ...
-// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 36, 0, 0, // Skip to: 44
-// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
-// CHECK-LARGE-NEXT: /* 11 */ MCD::OPC_FilterValue, 0, 28, 0, 0, // Skip to: 44
-// CHECK-LARGE-NEXT: /* 16 */ MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 30
-// CHECK-LARGE-NEXT: /* 23 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 30
-// CHECK-LARGE-NEXT: /* 30 */ MCD::OPC_CheckField, 3, 2, 0, 7, 0, 0, // Skip to: 44
-// CHECK-LARGE-NEXT: /* 37 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1, 0, 0, 0, // Opcode: InstA, skip to: 44
-// CHECK-LARGE-NEXT: /* 44 */ MCD::OPC_Fail,
+// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-LARGE-NEXT: /* 5 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
+// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-LARGE-NEXT: /* 10 */ MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 24
+// CHECK-LARGE-NEXT: /* 17 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 24
+// CHECK-LARGE-NEXT: /* 24 */ MCD::OPC_CheckFieldOrFail, 3, 2, 0,
+// CHECK-LARGE-NEXT: /* 28 */ MCD::OPC_TryDecodeOrFail, {{[0-9]+}}, {{[0-9]+}}, 1,
+// CHECK-LARGE-NEXT: /* 32 */ MCD::OPC_Fail,
// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission3.td b/llvm/test/TableGen/trydecode-emission3.td
index 141dc5439ca13..e2b739d8338de 100644
--- a/llvm/test/TableGen/trydecode-emission3.td
+++ b/llvm/test/TableGen/trydecode-emission3.td
@@ -36,19 +36,19 @@ def InstB : TestInstruction {
}
// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
-// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 16, 0, // Skip to: 23
-// CHECK-NEXT: /* 7 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 19
-// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 19
-// CHECK-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-NEXT: /* 23 */ MCD::OPC_Fail,
+// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-NEXT: /* 5 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, // Skip to: 17
+// CHECK-NEXT: /* 11 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 17
+// CHECK-NEXT: /* 17 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-NEXT: /* 21 */ MCD::OPC_Fail,
// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
-// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 18, 0, 0, // Skip to: 26
-// CHECK-LARGE-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 22
-// CHECK-LARGE-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 22
-// CHECK-LARGE-NEXT: /* 22 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-LARGE-NEXT: /* 26 */ MCD::OPC_Fail,
+// CHECK-LARGE-NEXT: /* 3 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-LARGE-NEXT: /* 5 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 19
+// CHECK-LARGE-NEXT: /* 12 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 19
+// CHECK-LARGE-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 23 */ MCD::OPC_Fail,
// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/trydecode-emission4.td b/llvm/test/TableGen/trydecode-emission4.td
index bb44876e77f02..39a3187c38bda 100644
--- a/llvm/test/TableGen/trydecode-emission4.td
+++ b/llvm/test/TableGen/trydecode-emission4.td
@@ -34,21 +34,21 @@ def InstB : TestInstruction {
}
// CHECK: /* 0 */ MCD::OPC_ExtractField, 250, 3, 4, // Inst{509-506} ...
-// CHECK-NEXT: /* 4 */ MCD::OPC_FilterValue, 0, 17, 0, // Skip to: 25
-// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 248, 3, 2, 0, 6, 0, // Skip to: 21
-// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, skip to: 21
-// CHECK-NEXT: /* 21 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-NEXT: /* 25 */ MCD::OPC_Fail,
+// CHECK-NEXT: /* 4 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-NEXT: /* 6 */ MCD::OPC_CheckField, 248, 3, 2, 0, 6, 0, // Skip to: 19
+// CHECK-NEXT: /* 13 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, // Opcode: InstB, Skip to: 19
+// CHECK-NEXT: /* 19 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-NEXT: /* 23 */ MCD::OPC_Fail,
// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ MCD::OPC_ExtractField, 250, 3, 4, // Inst{509-506} ...
-// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_FilterValue, 0, 19, 0, 0, // Skip to: 28
-// CHECK-LARGE-NEXT: /* 9 */ MCD::OPC_CheckField, 248, 3, 2, 0, 7, 0, 0, // Skip to: 24
-// CHECK-LARGE-NEXT: /* 17 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 24
-// CHECK-LARGE-NEXT: /* 24 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
-// CHECK-LARGE-NEXT: /* 28 */ MCD::OPC_Fail,
+// CHECK-LARGE-NEXT: /* 4 */ MCD::OPC_FilterValueOrFail, 0,
+// CHECK-LARGE-NEXT: /* 6 */ MCD::OPC_CheckField, 248, 3, 2, 0, 7, 0, 0, // Skip to: 21
+// CHECK-LARGE-NEXT: /* 14 */ MCD::OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, Skip to: 21
+// CHECK-LARGE-NEXT: /* 21 */ MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA
+// CHECK-LARGE-NEXT: /* 25 */ MCD::OPC_Fail,
// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 82ba93534cbda..3990836e9077f 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -90,9 +90,9 @@ STATISTIC(NumInstructions, "Number of instructions considered");
STATISTIC(NumEncodingsSupported, "Number of encodings supported");
STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
-namespace {
+static unsigned getNumToSkipInBytes() { return LargeTable ? 3 : 2; }
-unsigned getNumToSkipInBytes() { return LargeTable ? 3 : 2; }
+namespace {
struct EncodingField {
unsigned Base, Width, Offset;
@@ -182,6 +182,8 @@ struct DecoderTableInfo {
FixupScopeList FixupStack;
PredicateSet Predicates;
DecoderSet Decoders;
+
+ bool isOutermostScope() const { return FixupStack.size() == 1; }
};
struct EncodingAndInst {
@@ -777,11 +779,21 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
PrevFilter = 0; // Don't re-process the filter's fallthrough.
} else {
- Table.push_back(MCD::OPC_FilterValue);
+ // The last filtervalue emitted can be OPC_FilterValue if we are at
+ // outermost scope.
+ const uint8_t DecoderOp =
+ FilterVal == LastFilter && TableInfo.isOutermostScope()
+ ? MCD::OPC_FilterValueOrFail
+ : MCD::OPC_FilterValue;
+ Table.push_back(DecoderOp);
Table.insertULEB128(FilterVal);
- // Reserve space for the NumToSkip entry. We'll backpatch the value
- // later.
- PrevFilter = Table.insertNumToSkip();
+ if (DecoderOp == MCD::OPC_FilterValue) {
+ // Reserve space for the NumToSkip entry. We'll backpatch the value
+ // later.
+ PrevFilter = Table.insertNumToSkip();
+ } else {
+ PrevFilter = 0;
+ }
}
// We arrive at a category of instructions with the same segment value.
@@ -796,9 +808,10 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
Table.patchNumToSkip(PrevFilter, Table.size());
}
- // If there is no fallthrough, then the final filter should get fixed
- // up according to the enclosing scope rather than the current position.
- if (!HasFallthrough)
+ // If there is no fallthrough and the final filter was not in the outermost
+ // scope, then it must be fixed up according to the enclosing scope rather
+ // than the current position.
+ if (PrevFilter)
TableInfo.FixupStack.back().push_back(PrevFilter);
}
@@ -863,6 +876,15 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
DecoderTable::const_iterator I = Table.begin();
DecoderTable::const_iterator E = Table.end();
const uint8_t *const EndPtr = Table.data() + Table.size();
+
+ auto emitNumToSkipComment = [&](uint32_t NumToSkip, bool InComment = false) {
+ uint32_t Index = ((I - Table.begin()) + NumToSkip);
+ OS << (InComment ? ", " : "// ");
+ OS << "Skip to: " << Index;
+ if (*(I + NumToSkip) == MCD::OPC_Fail)
+ OS << " (Fail)";
+ };
+
while (I != E) {
assert(I < E && "incomplete decode table entry!");
@@ -873,7 +895,8 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
const uint8_t DecoderOp = *I++;
switch (DecoderOp) {
default:
- PrintFatalError("Invalid decode table opcode: " + Twine(DecoderOp));
+ PrintFatalError("Invalid decode table opcode: " + Twine((int)DecoderOp) +
+ " at index " + Twine(Pos));
case MCD::OPC_ExtractField: {
OS << Indent << "MCD::OPC_ExtractField, ";
@@ -890,17 +913,24 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
OS << Start << "} ...\n";
break;
}
- case MCD::OPC_FilterValue: {
- OS << Indent << "MCD::OPC_FilterValue, ";
+ case MCD::OPC_FilterValue:
+ case MCD::OPC_FilterValueOrFail: {
+ bool IsFail = DecoderOp == MCD::OPC_FilterValueOrFail;
+ OS << Indent << "MCD::OPC_FilterValue" << (IsFail ? "OrFail, " : ", ");
// The filter value is ULEB128 encoded.
emi...
[truncated]
|
I also found another minor improvement here: Most targets don't generate TryDecode (only AArch64 seems to be generating it), so we could not emit the TryDecode cases for other targets (by tracking whether any TryDecode ops are generated) and eliminate some dead code. |
Introduce
OrFail
variants for all MCD Decoder Ops that haveNumToSKip
encoded with them. This is intended to capture the common case of jumps to the end of the decoder table which has aOP_Fail
at the end. Using theOrFail
variants of these ops avoid encoding theNumToSkip
jump offset for these cases, resulting in a reduction in the size of the decoder tables (from 5 - 17%). Additionally, for the AArch64 target, the table size reduces enough to switch to using 2-byteNumToSkip
encoding instead of existing 3-bytes, resulting in a net 30% reduction in the size of the decoder table.The total reduction in the size of the decoder tables for different targets is as follows (computed using the following command:
for i in *.inc; do echo -n ``basename $i: ``; grep "MCD::OPC_Fail," $i | awk '{sum += $2} END { print sum}'; done
)