Instead of using the Record from the instruction definition, use the
Record specified in the CompressPat DAG. This will allow us to use
Records that are subsets of both the source and destination.
I want to use this to merge the C_*_HINT instructions back into their
regular non-HINT versions, but prevent those encodings from being part
of compress/uncompress. For example, we will use GPRNoX0 for the C_ADDI
CompressPat while both C_ADDI and ADDI will use GPR in their instruction
definitions.
To do this I've recorded the original DAG Record in the OperandMap using
a struct in the union to represent the 3 fields needed for an Operand.
Previously we stored TiedOpIdx outside the union, but only used it for
Operand.
There is a verification hole here where we don't have any way to check
that an immediate predicate is a subset of an instruction predicate at
tablegen time. Prior to #148660 we had this hole in one direction, but
that patch made it in two directions. I'm not sure if this patch makes
it any worse. Now we're using what is in the CompressPat where before we
were using whatever was in the instructions and ignoring the predicate
in the CompressPat.
Tied operands in the destination are not supposed to be listed. This
didn't cause a functional issue because none of the code noticed that
extra operand was even there.
Simplify verifyDagOpCount to catch this case.
Also replace the current static DenseMap of preserved symbol
names in the Symtab hack with this. That was broken statefulness
across compiles, so this at least fixes that. However this is
still broken, llvm-as shouldn't really depend on the triple.
Additionally, add sentinel values <Enum>::First_ and <Enum>::Last_ to
each one of those enums.
This will allow using `enum_seq_inclusive` to generate the list of
enum-typed values of any generated scoped (non-bitmask) enum.
We have some 48-bit instructions in the `Xqci` spec that currently
cannot be compressed to their 32-bit variants due to the constraint in
`CompressInstEmitter` on destination instruction operands not being
allowed to mismatch with the DAG operands.
For eg. the` QC_E_ADDI` instruction can be compressed to the `ADDI`
instruction when the immediate is signed-12 bit but this is currently
not possible since the `QC_E_ADDI` instruction has `GPRNoX0` register
operands while the `ADDI` instruction has `GPR` register operands
leading to an operand type validation error.
I think we can remove the check that only source instruction operands
can mismatch with the corresponding DAG operands and rely on the fact
that we check if the DAG register operand type is a subclass of the
instruction register operand type.
- Add braces around if/else bodies per LLVM coding standards.
- Use range for loops and structured bindings.
- use auto for variables initialized with `dyn_cast`.
- Refactor `compareBy` to also use early return in the comparison loop
by extracting the comparison into lambdas.
Change `GenericEnum` to not heap allocate its entries. Instead stash
them directly in the `Entries` vector. Change `EntryMap` to hold an
index as opposed to a pointer to the entry (the original reason why they
were unique_ptr).
Make `AppendZero` a class member instead of an argument to
`GetOrAddStringOffset` to reflect the intended usage that for a given
`StringToOffsetTable`, all strings must use the same value of
`AppendZero`.
Modify `EmitStringTableDef` to drop the `Indent` argument as its always
set to `""`, and to fail if it's called for a table with
non-null-terminated strings.
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.
TableGen's RegUnitIterator is a strange contraption that iterates over a
range of registers as well as the regunits of each register. Since it is
only used in one place in a `for` loop, it is much simpler to use two
nested loops instead.
Allow associating a non-default CallingConv with a set of library
functions, and applying a default for a SystemLibrary.
I also wanted to be able to apply a default calling conv
to a RuntimeLibcallImpl, but that turned out to be annoying
so leave it for later.
Add a way to define a SystemLibrary for a complete set of
libcalls, subdivided by a predicate based on the triple.
Libraries can be defined using dag set operations, and the
prior default set can be subtracted from and added to (though
I think eventually all targets should move to explicit opt-ins.
We're still doing things like reporting ppcf128 libcalls as
available dy default on all targets).
Start migrating some of the easier targets to only use the new
system. Targets that don't define a SystemLibrary are still
manually mutating a table set to the old defaults.
Move the creation of OperandMap from createDagOperandMapping to the loop
in addDagOperandMapping. Expand it to store the DAG operand number and
the MI operand number which will be different when there are tied
operands.
Rename createDagOperandMapping to checkDagOperandMapping to better
describe the remaining code.
I didn't lift the restriction that a source instruction can only have
one tied operand, but we should be able to if we have a use case.
There's a slight difference in the generate output. We now check that
operand 0 and 2 of QC_MVEQI are equal instead of operand 1 and 2. This
should be equivalent since operand 0 and 1 have a tied constraint.
- Add various instruction subclass/sub-slice accessors to
`CodeGenTarget`.
- Delete unused `inst_begin` and `inst_end` iterators.
- Rename `Instructions` to `InstructionMap` and `getInstructions` to
`getInstructionMap` to better represent their meaning.
- Use these new accessors in InstrInfoEmitter
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.
so that subclasses can provide the appropriate MCAsmInfo to print
MCExpr objects.
At present, llvm/utils/TableGen/AsmMatcherEmitter.cpp constucts a
generic MCAsmInfo.
Work towards separating the ABI existence of libcalls vs. the
lowering selection. Set libcall selection through enums, rather
than through raw string names.
Replace RuntimeLibcalls.def with a tablegenerated version. This
is in preparation for splitting RuntimeLibcalls into two components.
For now match the existing functionality.
Dynamic relocations are expensive on ELF/Linux platforms because they
are applied in userspace on process startup. Therefore, it is worth
optimizing them to make PIE and PIC dylib builds faster. In +asserts
builds (non-NDEBUG), nikic identified these schedule class name string
pointers as the leading source of dynamic relocations. [1]
This change uses llvm::StringTable and the StringToOffsetTable TableGen
helper to turn the string pointers into 32-bit offsets into a separate
character array.
The number of dynamic relocations is reduced by ~60%:
❯ llvm-readelf --dyn-relocations lib/libLLVM.so | wc -l
381376 # before
155156 # after
The test suite time is modestly affected, but I'm running on a shared
noisy workstation VM with a ton of cores:
https://gist.github.com/rnk/f38882c2fe2e63d0eb58b8fffeab69de
Testing Time: 100.88s # before
Testing Time: 78.50s. # after
Testing Time: 96.25s. # before again
I haven't used any fancy hyperfine/denoising tools, but I think the
result is clearly visible and we should ship it.
[1] https://gist.github.com/nikic/554f0a544ca15d5219788f1030f78c5a
Tied Operands change is required for adding codegen patterns for
Qualcomm uC Xqcicm instructions
which will be done in a follow-up PR. This change leads to one of
instructions getting compressed even
when it shouldn't be. This case was not covered in #143660. Added
changes to correctly handle this case.
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.
- Change `hadOperandNamed` to return index as std::optional and rename
it to `findOperandNamed`.
- Change `SubOperandAlias` to return std::optional and rename it to
`findSubOperandAlias`.