This is useful for `InstAlias` where a fixed register may depend on the
HwMode. The motivating use case for this is the RISC-V RVY ISA where
certain instructions mnemonics are remapped to take a different
register class depending on the HwMode and can be used as follows:
```
def NullReg : RegisterByHwMode<PtrRC, [RV32I, RV64I, RV64Y, RV64Y],
[X0, X0, X0_Y, X0_Y]>;
```
Pull Request: https://github.com/llvm/llvm-project/pull/175227
This does not yet handle all cases but at least for the simple
cases such as:
```
def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
(PTR_MOV_SMALL PtrRC:$dst, PtrRC:$src)>;
```
tablegen generates sensible code instead of emitting confusing errors.
Reviewed By: arsenm
Pull Request: https://github.com/llvm/llvm-project/pull/171061
I was hitting this error and the error location was pointing to the
register class definition instead of the incorrect InstAlias. Pass in
the InstAlias location to make it easier to debug.
Happens with `def : InstAlias<"foo", (Inst X0)>`, where `Inst` takes
a RegClassByHwMode operand that is not necessarily satisfied by
register X0. Similar problem with the CompressPat backend.
Reviewed By: arsenm
Pull Request: https://github.com/llvm/llvm-project/pull/170790
The previous code was subtly incorrect, as it indexed the RegistersByName map using the tblgen Def name of the register, rather than the AsmName with which the table was initialized. But all of this indirection via the name was unnecessary.
This avoids needing to remove the leading indentation and trailing '
&&\n' when we are done with all conditions.
While there remove a few extra parentheses and fix a case where 6
spaces of indentation was used instead of 8.
In addition to checking the predicate from the CompressPat, also check
the destination instruction. This prevents creating bad instructions if
CompressPat isn't a proper subset of the destination instruction. This
prevents mistakes that we can't catch at compile time.
We are able to verify RegisterClass hierarchy at compile time so don't
have to check the destination register class.
I've added comments for the operand names to make auditing easier.
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.
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.
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.
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.
This update enables compress patterns to handle one tied operand in
source instructions, which was previously unsupported. Qualcomm's uC
extension Xqci includes several instructions with tied operands that can
be compressed into smaller forms. This change adds the necessary support
to enable such compression. Additionally, a compress pattern for the
qc.muliadd instruction has been implemented.
I'm looking into using sub-operands for memory operands. This would use
MIOperandInfo to create a single operand that contains a register and
immediate as sub-operands. We can treat this as a single operand for
parsing and matching in the assembler. I believe this will provide some
simplifications like removing the InstAliases we need to support "(rs1)"
without an immediate.
Doing this requires making CompressInstEmitter aware of sub-operands.
I've chosen to use a flat list of operands in the CompressPats so each
sub-operand is represented individually.
Calling MCRegisterClass::contains with a Register does an implicit
conversion from Register to MCRegister. I think MCRegister is only
intended to be used for physical registers. We should protect this
implicit conversion by checking for physical registers first.
While I was here I removed some unnecessary parentheses from the output.
Since `raw_string_ostream` doesn't own the string buffer, it is
desirable (in terms of memory safety) for users to directly reference
the string buffer rather than use `raw_string_ostream::str()`.
Work towards TODO item to remove `raw_string_ostream::str()`.
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
So that we won't get redefinition errors if we use compressInst
and uncompressInst in the same file.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D141896
RISCVSubtarget should be a superclass of MCSubtargetInfo so should
have all the same information. Now we pass RISCVSubtarget by
reference and name it STI.
Confusingly, we seem to have been using an MCSubtargetInfo from
the TargetMachine rather than the one associated with the function
we are operating. I'm going to assume that was a mistake and not
intentional.
Reviewed By: kito-cheng
Differential Revision: https://reviews.llvm.org/D141966
This was being used to lookup the register class for a register number,
but those live in a tablegened array. We can index that array directly
just like RISCVAsmParser does.
Differential Revision: https://reviews.llvm.org/D141951
Marking rs1 (memory offset base) as memory operand provides additional
semantic value to this operand that can be used by different tools
(e.g. llvm-exegesis).
This change does not affect neigther Isel nor assembler. However it
required some tweaks in tablegen compressed inst emmiter.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D136847
If a MachineInstr's operand should be Reg in compiler's output but is
currently FrameIndex, `isCompressibleInst()` will terminate at
`MachineOperandType::getReg()`.
This patch adds `.isReg()` checks to make `isCompressibleInst()` return
false for these MachineInstr, allowing `getInstSizeInBytes()` to return
a value and `EstimateFunctionSizeInBytes()` to work as intended.
See https://reviews.llvm.org/D129999#3694222 for details.
Reviewed By: luismarques
Differential Revision: https://reviews.llvm.org/D129999
Based on the output of include-what-you-use.
It's an utility directory, so no much impact on other code areas.
clang++ -E -Iinclude -I../llvm/include ../llvm/utils/TableGen/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l
before: 4327274
after: 4316190
Related discourse thread: https://llvm.discourse.group/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D118466
Not only RISCV but also other target such as CSKY, there are compressed instructions mixed with normal instructions.
To reuse the basic infra to compress/uncompress and predict instruction, we need reconstruct the RISCVCompressInstEmitter
and make it more general and suitable for other target.
Differential Revision: https://reviews.llvm.org/D113475