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
This changs the way the assembly matcher works for Aarch32 parsing.
Previously there was a pile of hacks which dictated whether the CC,
CCOut, and VCC operands should be present which de-facto chose if the
wide/narrow (or thumb1/thumb2/arm) instruction version were chosen.
This meant much of the TableGen machinery present for the assembly
matching was effectively being bypassed and worked around.
This patch makes the CC and CCOut operands optional which allows the ASM
matcher operate as it was designed and means we can avoid doing some of
the hacks done previously. This also adds the option for the target to
allow the prioritizing the smaller instruction encodings as is required
for Aarch32.
This option means that in assembly matching instructions with smaller
encodings will be preferred.
This will be used for the ARM instruction set where this is the correct
behavior after some other refactoring.
At some point in the past, optional operands have become allowed in the
middle of an instruction. However, `checkAsmTiedOperandConstrains`
hasn't been modified to support this. This patch adds the support by
pulling operand offsets counting out of `convertToMCInst` and reusing it
in `checkAsmTiedOperandConstrains`.
Historically TableGen has used `A.swap(B)` to move containers without
the expense of copying them. Perhaps this predated rvalue references. In
any case `A = std::move(B)` seems like a more direct way to implement
this when only A is required after the operation.
In a few places we test whether sets (i.e. sorted ranges) intersect by
computing the set_intersection and then testing whether it is empty. For
this purpose it should be more efficient to use a std:vector instead of
a std::set to hold the result of the set_intersection, since insertion
is simpler.
- When selecting the minimal type for 'MatchClassKind' during the
emission of 'MatchEntry' and 'OperandMatchEntry', two pre-defined
kinds 'InvalidMatchClass' and 'OptionalMatchClass' are not taken into
account.
ParseStatus is slightly more convenient to use due to implicit
conversion from bool, which allows to do something like:
```
return Error(L, "msg");
```
when with MatchOperandResultTy it had to be:
```
Error(L, "msg");
return MatchOperand_ParseFail;
```
It also has more appropriate name since parse* methods are not only for
parsing operands.
Reviewed By: kosarev
Differential Revision: https://reviews.llvm.org/D154303
llvm-clang-x86_64-expensive-checks-debian will fail after D150436 merged.
The fail occurred in X86, I changed the sort rule in AsmMatcher in Patch D150436, so x86 code will arrive line 633 first(will not affect other targets).
The logic here want to use the order record written in source file to make AsmMatcher to first use AVX instructions, it used field HasPositionOrder.
But the condition here just makes sure one of the compared record is subclass of Instruction and has field HasPositionOrder true, and didn't check another.
(Committing on behalf of @XinWang10 to unblock broken expensive-cjhecks builds)
Differential Revision: https://reviews.llvm.org/D150651
The logic from line 633 to 640 is specific for ARM as the comments said, it will make all the targets will prefer to using instruction with more predicates when compiler do AsmMatching.
And for code from line 642 to 649, X86 want to use the order records written in source file to sort the instructions. So X86 could be affected by this logic. (These code could be arrived only by X86)
After change this, seems AVX instructions have not be affected but it exposed some other errors for instruction push and call.
CALLpcrel16 could not be used in 64 bit mode, we need add Predicate for it. And for push instruction, previously because pushi32 has predicates = [Not64bitmode], so it precede pushi16, which is incorrect here, we should get pushw here and it also align with gcc.
Reviewed By: skan
Differential Revision: https://reviews.llvm.org/D150436
This patch replaces the uses of PointerUnion.is function by llvm::isa,
PointerUnion.get function by llvm::cast, and PointerUnion.dyn_cast by
llvm::dyn_cast_if_present. This is according to the FIXME in
the definition of the class PointerUnion.
This patch does not remove them as they are being used in other
subprojects.
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D148449
Eliminates the need for working around optional and token operands being
mistakenly parsed as expressions.
Reviewed By: dp
Differential Revision: https://reviews.llvm.org/D138492
Currently, the asm parser stops matching instruction operands as soon as
the first optional operand is encountered. This leads to the need for
custom checks on missing mandatory operands that come after optional
operands.
The patch changes the parser to always match all optional and mandatory
instruction operands, thus making the custom checks unnecessary. This is
particularly useful for the AMDGPU backend where we have numerous
optional instruction modifiers.
Differential Revision: https://reviews.llvm.org/D137549
Currently, the asm parser stops matching instruction operands as soon as the first optional operand is encountered. This leads to the need for custom checks on missing mandatory operands that come after optional operands.
The patch changes the parser to always match all optional and mandatory instruction operands, thus making the custom checks unnecessary. This is particularly useful for the AMDGPU backend where we have numerous optional instruction modifiers.
Reviewed By: dp
Differential Revision: https://reviews.llvm.org/D137549
This patch adds the assembly/disassembly for the following instructions:
ADD (to vector): Add replicated single vector to multi-vector with multi-vector result.
SQDMULH (multiple and single vector): Multi-vector signed saturating doubling multiply high by vector.
for 2 and 4 ZA SVE registers.
The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09
It also adds more size for the multiple register tuple:
ZZ_b_mul_r, ZZ_h_mul_r,
ZZZZ_b_mul_r, ZZZZ_h_mul_r,
for 8 bits and 16 bits with 2 and 4 ZA registers.
Depends on: D135468
With a fix for Mips for this test:
llvm/test/MC/Mips/mips64r6/valid.s
Differential Revision: https://reviews.llvm.org/D135563
This reverts commit 4c4909703d74883e5cc49edcbd22b783135d2897.
This patch was breaking this test:
llvm/test/MC/Mips/mips64r6/valid.s
I will push again when fixed
This patch adds the assembly/disassembly for the following instructions:
ADD (to vector): Add replicated single vector to multi-vector with multi-vector result.
SQDMULH (multiple and single vector): Multi-vector signed saturating doubling multiply high by vector.
for 2 and 4 ZA SVE registers.
The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2022-09
It also adds more size for the multiple register tuple:
ZZ_b_mul_r, ZZ_h_mul_r,
ZZZZ_b_mul_r, ZZZZ_h_mul_r,
for 8 bits and 16 bits with 2 and 4 ZA registers.
Depends on: D135468
Differential Revision: https://reviews.llvm.org/D135563
This patch is to order the AVX instructions ahead of AVX512 instructions
in the matching table so that the AVX instructions can be matched first.
Thanks Craig and Shengchen for the idea.
Differential Revision: https://reviews.llvm.org/D111538
My use case for this is illustrated in the test case: I want to define
the same instruction twice with different (disjoint) predicates, because
the instruction has different operands on different subtargets. It's
convenient to do this with a multiclass that also defines an alias for
the instruction.
Previously tablegen would complain if this alias was defined twice with
no predicate. One way to fix this would be to add a predicate on each
definition of the alias, matching the predicate on the instruction. But
this (a) is slightly awkward to do in the real world use case I had, and
(b) leads to an inefficient matcher that will do something like this:
if (Mnemonic == "foo_alias") {
if (Features.test(Feature_Subtarget1Bit))
Mnemonic == "foo";
else if (Features.test(Feature_Subtarget2Bit))
Mnemonic == "foo";
return;
}
It would be more efficient to skip the feature tests and return "foo"
unconditionally.
Overall it seems better to allow multiple definitions of the identical
alias with no predicate.
Differential Revision: https://reviews.llvm.org/D105033
This is a mechanical change. This actually also renames the
similarly named methods in the SmallString class, however these
methods don't seem to be used outside of the llvm subproject, so
this doesn't break building of the rest of the monorepo.