- Change InstrInfoEmitter to emit OpName as an enum class
instead of an anonymous enum in the OpName namespace.
- This will help clearly distinguish between values that are
OpNames vs just operand indices and should help avoid
bugs due to confusion between the two.
- Rename OpName::OPERAND_LAST to NUM_OPERAND_NAMES.
- Emit declaration of getOperandIdx() along with the OpName
enum so it doesn't have to be repeated in various headers.
- Also updated AMDGPU, RISCV, and WebAssembly backends
to conform to the new definition of OpName (mostly
mechanical changes).
- Use range for loops and `enumerate` in a few places.
- Use `StringRef` for `TargetName` in `InstrInfoEmitter::run`.
- Use `\n` character for new line instead of string.
- Use StringRef in `InstrNames` (instead of std::string) and
avoid string copies.
- Detect whether logical operand mapping/named operand mappings have
been enabled in a previous pass over instructions and execute the
relevant emission code only if those mappings are enabled.
- For these mappings, skip the fixed set of predefined instructions as
they won't have these mappings enabled.
- Emit operand type mappings only for X86 target, as they are only used
by X86 and look for X86 specific `X86MemOperand`.
- Cleanup `emitOperandTypeMappings` code: remove code to handle empty
instruction list and use range for loops.
- Looks like this sentinel value is used in some downstream backends, so
restore emitting it.
- It now also has the correct value (earlier code may have emitted an
incorrect value for OPERAND_LAST and hence it was removed in
https://github.com/llvm/llvm-project/pull/124960)
- Assign `OpName` enum values in the same alphabetical order in which
they are emitted.
- Get rid of OPERAND_LAST which is not used anywhere.
- Inline `initOperandMapData` into `emitOperandNameMappings` to help see
clearly how various maps are computed.
- Emit the static `OperandMap` table as int8_t when possible. This
should help reduce the static size by 50% in the common case.
- Change maps/vectors to use StringRef instead of std::string to avoid
unnecessary copies.
Adopt scaled indent in PredicateExpander.
Added pre/post inc/dec operators to `indent` and related unit tests.
Verified by comparing *.inc files generated by LLVM build with/without
the change.
- If a def operand includes multiple sub-operands, count them when
generating instr info.
- Found issues in x86 and sparc backends, where memory operands of
store or store-like instructions are wrongly placed in the output
list.
Reviewers: jayfoad, arsenm, Pierre-vh
Reviewed By: arsenm
Pull Request: https://github.com/llvm/llvm-project/pull/88972
Refactor of the llvm-tblgen source into:
- a "Basic" library, which contains the bare minimum utilities to build
`llvm-min-tablegen`
- a "Common" library which contains all of the helpers for TableGen
backends. Such helpers can be shared by more than one backend, and even
unit tested (e.g. CodeExpander is, maybe we can add more over time)
Fixes#80647
When generating snippets for AArch64 with --opcode-index=-1, the code
generator asserts on opcodes that are not supported according to CPU
features.
The same assertion can be triggered even when generating a serial
snippet for a supported opcode if SERIAL_VIA_NON_MEMORY_INSTR execution
mode is used and an unsupported instruction is chosen as the "other
instruction". Unlike the first case, this one may result in flaky
failures because the other instruction is randomly chosen from the
instructions suitable for serializing execution.
This patch adjusts TableGen emitter for *GenInstrInfo.inc to make
possible to query for opcode availability instead of just asserting on
unsupported ones.
~~
Huawei RRI, OS Lab
Reviewed By: courbet
Differential Revision: https://reviews.llvm.org/D146303
A function is already emitted in *GenInstrInfo.inc that takes Opcode
number and a set of supported Features and reports fatal error if some
of the required features are missing.
The information about features required by the particular opcode can be
reused by llvm-exegesis, so move its computation info a separate
computeRequiredFeatures() function. Then verifyInstructionPredicates()
can just compare the sets of available and required features computed by
the other functions.
This commit moves the definition of FeatureBitsets[] as well as CEFBS_*
enumerator values (that are indices into FeatureBitsets[] array) inside
the computeRequiredFeatures() function because these are implementation
details of that function. The inclusion of potentially huge
computeRequiredFeatures() function is now controlled by a dedicated
macro that is set for simplicity by TableGen-erated code itself if
`defined(ENABLE_INSTR_PREDICATE_VERIFIER) && !defined(NDEBUG)`.
~~
Huawei RRI, OS Lab
Reviewed By: courbet
Differential Revision: https://reviews.llvm.org/D148516
This shrinks MCInstrDesc (and hence the whole TargetInsts table) because
we can store a 16-bit offset value to access the operands info, instead
of a pointer. This also reduces the number of relocs that need to be
applied when LLVM is compiled as position-independent code.
Differential Revision: https://reviews.llvm.org/D142219
This shrinks MCInstrDesc (and hence the whole TargetInsts table) because
we can store a 16-bit offset value to access the implicit operands,
instead of a pointer. This also reduces the number of relocs that need
to be applied when LLVM is compiled as position-independent code.
Differential Revision: https://reviews.llvm.org/D142218
This will allow an entry in the table to access data that is stored
immediately after the end of the table, by adding its opcode value
to its address.
Differential Revision: https://reviews.llvm.org/D142217
Combine the implicit uses and defs lists into a single list of uses
followed by defs. Instead of 0-terminating the list, store the number
of uses and defs. This avoids having to scan the whole list to find the
length and removes one pointer from MCInstrDesc (although it does not
get any smaller due to alignment issues).
Remove the old accessor methods getImplicitUses, getNumImplicitUses,
getImplicitDefs and getNumImplicitDefs as all clients are using the new
implicit_uses and implicit_defs.
Differential Revision: https://reviews.llvm.org/D142216
The opcode field in most places uses unsigned type.
InstrInfoEmitter still uses signed int for the
custom opcodes like CFSetupOpcode.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D135140
D25618 added a method to verify the instruction predicates for an
emitted instruction, through verifyInstructionPredicates added into
<Target>MCCodeEmitter::encodeInstruction. This is a very useful idea,
but the implementation inside MCCodeEmitter made it only fire for object
files, not assembly which most of the llvm test suite uses.
This patch moves the code into the <Target>_MC::verifyInstructionPredicates
method, inside the InstrInfo. The allows it to be called from other
places, such as in this patch where it is called from the
<Target>AsmPrinter::emitInstruction methods which should trigger for
both assembly and object files. It can also be called from other places
such as verifyInstruction, but that is not done here (it tends to catch
errors earlier, but in reality just shows all the mir tests that have
incorrect feature predicates). The interface was also simplified
slightly, moving computeAvailableFeatures into the function so that it
does not need to be called externally.
The ARM, AMDGPU (but not R600), AVR, Mips and X86 backends all currently
show errors in the test-suite, so have been disabled with FIXME
comments.
Recommitted with some fixes for the leftover MCII variables in release
builds.
Differential Revision: https://reviews.llvm.org/D129506
This reverts commit e2fb8c0f4b940e0285ee36c112469fa75d4b60ff as it does
not build for Release builds, and some buildbots are giving more warning
than I saw locally. Reverting to fix those issues.
D25618 added a method to verify the instruction predicates for an
emitted instruction, through verifyInstructionPredicates added into
<Target>MCCodeEmitter::encodeInstruction. This is a very useful idea,
but the implementation inside MCCodeEmitter made it only fire for object
files, not assembly which most of the llvm test suite uses.
This patch moves the code into the <Target>_MC::verifyInstructionPredicates
method, inside the InstrInfo. The allows it to be called from other
places, such as in this patch where it is called from the
<Target>AsmPrinter::emitInstruction methods which should trigger for
both assembly and object files. It can also be called from other places
such as verifyInstruction, but that is not done here (it tends to catch
errors earlier, but in reality just shows all the mir tests that have
incorrect feature predicates). The interface was also simplified
slightly, moving computeAvailableFeatures into the function so that it
does not need to be called externally.
The ARM, AMDGPU (but not R600), AVR, Mips and X86 backends all currently
show errors in the test-suite, so have been disabled with FIXME
comments.
Differential Revision: https://reviews.llvm.org/D129506
Control the MCOperandInfo expansion with `-instr-info-expand-mi-operand-info`.
For X86, this would make it possible to see memory operand type e.g.:
```
/* MOV8rm */
GR8, i8mem,
/* MOV8rm_NOREX */
GR8_NOREX, i8mem_NOREX,
```
The intended use is a follow-up diff D126116 (`getMemOperandSize`).
Reviewed By: skan
Differential Revision: https://reviews.llvm.org/D127932
Make Offsets and OpcodeOperandTypes tables human-readable by printing the
instruction name before the operand list.
In effect, this makes debugging generated `getOperandType` possible.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D127931
Make Offsets and OpcodeOperandTypes tables human-readable by printing the
instruction name before the operand list.
In effect, this makes debugging generated `getOperandType` possible.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D127931
Set Size appropriately in operand definitions and query it for dumping memory
operand size table `getMemOperandSize` (follow-up use D126116) and
`X86Disassembler::getMemOperandSize`.
Excerpt from a produced `getMemOperandSize` table for X86:
```
static int getMemOperandSize(int OpType) {
switch (OpType) {
default: return 0;
case OpTypes::i8mem:
case OpTypes::i8mem_NOREX:
return 8;
case OpTypes::f16mem:
case OpTypes::i16mem:
return 16;
case OpTypes::f32mem:
case OpTypes::i32mem:
return 32;
...
```
Reviewed By: skan, pengfei
Differential Revision: https://reviews.llvm.org/D127787
An instruction is a meta-instruction if it doesn't produce any output
in the form of executable instructions. So in the concept, a
meta-instruction does not have to be target independent.
Before this patch, `isMetaInstruction` is implemented by checking the
opcode of the instruction, add we have no way to add target dependent
opcode to the list, which does not make sense.
After this patch, a bit `isMeta` is added for class `Instruction` in
tablegen, which is used to indicate whether it's a meta instruction.
Reviewed By: pengfei
Differential Revision: https://reviews.llvm.org/D121600
- Add a new TableGen backend: CodeBeads
- Add support to generate logical operand information
For the first item, it is currently a workaround of M68k's (complex)
instruction encoding. A typical architecture, especially CISC one like
X86, normally uses `MCInstrDesc::TSFlags` to carry instruction encoding
info. However, at the early days of M68k backend development, we found
it difficult to fit every possible encoding into the 64-bit
`MCInstrDesc::TSFlags`. Therefore CodeBeads was invented to provide
an alternative, arbitrary length container for instruciton encoding
info. However, in the long term we incline not to use a new TG
backend for less common pattern like what we encountered in M68k. A bug
has been created to host to discussion on migrating from CodeBeads to
more concise solution: https://bugs.llvm.org/show_bug.cgi?id=48792
The second item was also served for similar purpose. It created utility
functions that tell you the index of a `MachineOperand` in a
`MachineInst` given a logical operand index. In normal cases a logical
operand is the same as `MachineOperand`, but for operands using complex
addressing mode a logical operand might be consisting of multiple
`MachineOperand`. The TableGen-ed `getLogicalOperandIdx`, for instance,
can give you the mapping between these two concepts. Nevertheless, we
hope to remove this feature in the future if possible. Since it's not
really useful for the targets supported by LLVM now either.
Authors: myhsu, m4yers, glaubitz
Differential Revision: https://reviews.llvm.org/D88385