The `insertBits` templated function generated by DecoderEmitter is
called with variable `tmp` of type `TmpType` which is:
```
using TmpType = std::conditional_t<std::is_integral<InsnType>::value, InsnType, uint64_t>;
```
That is, `TmpType` is always an integral type. Change the generated
`insertBits` to be valid only for integer types, and eliminate the
unused `insertBits` function from `DecoderUInt128` in
AMDGPUDisassembler.h
Additionally, drop some of the requirements `InsnType` must support as
they no longer seem to be required.
Add a convenience wrapper struct for the `bit_value_t` enum type to host
various constructors, query, and printing support. Also refactor related
code in several places. In `getBitsField`, use `llvm::append_range` and
`SmallVector::append()` and eliminate manual loops. Eliminate
`emitNameWithID` and instead use the `operator <<` that does the same
thing as this function. Have `BitValue::getValue()` (replacement for
`Value`) return std::optional<> instead of -1 for unset bits. Terminate
with a fatal error when a decoding conflict is encountered.
Add option `use-fn-table-in-decode-to-mcinst` to use a table of function
pointers instead of a switch case in the generated `decodeToMCInst`
function.
When the number of switch cases in this function is large, the generated
code takes a long time to compile in release builds. Using a table of
function pointers instead improves the compile time significantly (~3x
speedup in compiling the code in a downstream target). This option will
allow targets to opt into this mode if they desire for better build
times.
Tested with `check-llvm-mc` with the option enabled by default.
Also assign variable names to different elements of `OpMap` for better
readibility, and eliminate `NumberedEncodingsRef` as `std::vector` will
automatically get converted to an `ArrayRef`.
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
```
Print DecodeIdx associated with Decode MCD ops in the generated decoder
tables. This can help in debugging decode failures by first mapping the
Op -> DecodeIdx and then inspecting the code in `decodeToMCInst`
associated with that DecodeIdx.
Introduce `OrFail` variants for all MCD Decoder Ops that have
`NumToSKip` encoded with them. This is intended to capture the common
case of jumps to the end of the decoder table which has a `OP_Fail` at
the end. Using the `OrFail` variants of these ops avoid encoding the
`NumToSkip` 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-byte
`NumToSkip` 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`)
```
Target Old Size New Size % Reduction
================================================
AArch64 153268 106987 30.20
AMDGPU 412056 340856 17.28
ARC 5061 4605 9.01
ARM 73831 60847 17.59
AVR 1306 1158 11.33
BPF 1927 1795 6.85
CSKY 8692 6922 20.36
Hexagon 41965 34759 17.17
Lanai 982 924 5.91
LoongArch 21629 20035 7.37
M68k 13461 11689 13.16
MSP430 3716 3384 8.93
Mips 31415 25771 17.97
PPC 28931 24771 14.38
RISCV 34800 28352 18.53
Sparc 7432 6236 16.09
SystemZ 32248 29716 7.85
VE 42873 36923 13.88
XCore 2316 2196 5.18
Xtensa 3443 2793 18.88
```
These are identified by misc-include-cleaner. I've filtered out those
that break builds. Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
- Change `Name`, `SubopNames`, `PrinterMethodName`, and
`EncoderMethodNames` to be stored as StringRef.
- Also changed `CheckComplexPatMatcher::Name` to StringRef as a fallout
from the above.
Verified that all the tablegen generated files within LLVM are
unchanged.
- Add command line option `num-to-skip-size` to parameterize the size of
`NumToSkip` bytes in the decoder table. Default value will be 2, and
targets that need larger size can use 3.
- Keep all existing targets, except AArch64, to use size 2, and change
AArch64 to use size 3 since it run into the "disassembler decoding table
too large" error with size 2.
- Additional fixes on top of earlier revert: mark `decodeNumToSkip` as
static (not necessary anymore as the generated code is now in anonymous
namespace, but doing it for consistency) and incorporate Bazel build
changes from https://github.com/llvm/llvm-project/pull/136212
- Following is a rough reduction in size for the decoder tables by
switching to size 2.
```
Target Old Size New Size % Reduction
================================================
AArch64 153254 153254 0.00
AMDGPU 471566 412805 12.46
ARC 5724 5061 11.58
ARM 84936 73831 13.07
AVR 1497 1306 12.76
BPF 2172 1927 11.28
CSKY 10064 8692 13.63
Hexagon 47967 41965 12.51
Lanai 1108 982 11.37
LoongArch 24446 21621 11.56
MSP430 4200 3716 11.52
Mips 36330 31415 13.53
PPC 31897 28098 11.91
RISCV 37979 32790 13.66
Sparc 8331 7252 12.95
SystemZ 36722 32248 12.18
VE 48296 42873 11.23
XCore 2590 2316 10.58
Xtensa 3827 3316 13.35
```
- In both `emitTable` and the generated `decodeInstruction` function
increment the pointer to the decoder op as a part of the switch
statement instead of later on in each case.
- Avoid dereferencing the end() iterator to get the end pointer, instead
calculate it explicitly
- Fixes a regression introduced in
https://github.com/llvm/llvm-project/pull/136220.
- The windows build failure shows the following call stack:
```
| Exception Code: 0x80000003
| #0 0x00007ff74bc05897 std::_Vector_const_iterator<class std::_Vector_val<struct std::_Simple_types<unsigned char>>>::operator*(void) const C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.37.32822\include\vector:52:0
| #1 0x00007ff74bbd3d64 `anonymous namespace'::DecoderEmitter::emitTable D:\buildbot\llvm-worker\clang-cmake-x86_64-avx512-win\llvm\llvm\utils\TableGen\DecoderEmitter.cpp:852:0
```
- Move the code generated by DecoderEmitter to anonymous namespace.
- Move AMDGPU's usage of this code from header file to .cpp file.
Note, we get build errors like "call to function 'decodeInstruction'
that is neither visible in the template definition nor found by
argument-dependent lookup" if we do not change AMDGPU.
- Add command line option `num-to-skip-size` to parameterize the size of
`NumToSkip` bytes in the decoder table. Default value will be 2, and
targets that need larger size can use 3.
- Keep all existing targets, except AArch64, to use size 2, and change
AArch64 to use size 3 since it run into the "disassembler decoding table
too large" error with size 2.
- Following is a rough reduction in size for the decoder tables by
switching to size 2.
```
Target Old Size New Size % Reduction
================================================
AArch64 153254 153254 0.00
AMDGPU 471566 412805 12.46
ARC 5724 5061 11.58
ARM 84936 73831 13.07
AVR 1497 1306 12.76
BPF 2172 1927 11.28
CSKY 10064 8692 13.63
Hexagon 47967 41965 12.51
Lanai 1108 982 11.37
LoongArch 24446 21621 11.56
MSP430 4200 3716 11.52
Mips 36330 31415 13.53
PPC 31897 28098 11.91
RISCV 37979 32790 13.66
Sparc 8331 7252 12.95
SystemZ 36722 32248 12.18
VE 48296 42873 11.23
XCore 2590 2316 10.58
Xtensa 3827 3316 13.35
```
- Create a new stack scope only in the fallthrough case.
- For the non-fallthrough cases, any fixup entries will naturally be
added to the existing scope without needing to copy them manually.
- Verified that the generated `GenDisassembler` files are identical with
and without this change.
- Add helper functions to insert ULEB128 encoded value and NumToSkip.
- Use ArrayRef<> instead of const vector references as function
arguments.
- Return `OpHasCompleteDecoder` by value instead of by reference.
- Use range for loops.
- Remove {} around single line if/else bodies.
- In `emitSoftFailTableEntry`, unconditionally emit the Positive and
Negative mask values, instead of explicitly emitting a 0 byte when
the mask is not needed.
Combine the StartBits, EndBits, and FieldVals vectors into a single
vector of a struct that contains all 3 pieces of information.
Instead of storing EndBits, we store NumBits since that's what the users
want.
I've removed the BitNo variable as it was easy to construct calculate
from StartBit. I've also removed Num in favor of Islands.size().
This reduces the amount of space needed for vectors of bit_value_t
and allows the user of memset.
Also reorder the enum values so BIT_FALSE is 0 and BIT_TRUE is 1.
Instead of returning the number of bytes emitted, just take the iterator
by reference so the increments in emitULEB128 will update the copy in
the caller.
Also pass the iterator by reference to emitNumToSkip so we don't need a
separate I += 3 in the caller.
Rename `indent` to `Indent` and `o` to `OS`.
Rename `Indentation` to `Indent`.
Remove unused argument from `emitPredicateMatch`.
Change `Indent` argument to `emitBinaryParser` to by value.