The only caller of this function (`PeepholeOptimizer::optimizeSelect`)
did not use most of the parameters, was broadly equivalent to
`MI->isSelect()`, and the `optimizeSelect` hook can return `nullptr`
anyway.
Update `optimizeSelect` to return `nullptr` by default rather than
asserting when not implemented.
Such that we can now have something like:
```
PseudoVFMACC_VV_M2_E64 %1, %28, %28, 7 /* frm=dyn */, %21 /* vl */, 6 /* e64 */, 0 /* tu, mu */
```
or
```
PseudoVFMACC_VV_M2_E64 %1, %28, %28, 7 /* frm=dyn */, -1 /* vl=VLMAX */, 6 /* e64 */, 0 /* tu, mu */
```
Hopefully this could make reading RISC-V MIR (a little) less painful.
When analyzing outliner candidates, there is no check that the tail-call
expansion register is live across the candidate call site. That can
result in a situation where the original function sets the volatile
register and uses it in the section that gets outlined. This of course
results in the use of the register receiving the incorrect value. Namely
the address of the outlined function since that is what the tail-call
sequence placed in the register.
Use a common tablegen class instead of duplicating all the data and add a
new case macro to handle the isShiftedUInt<>() call. This refactoring was
motivated by adding RVY support since I needed to add uimm{9,10}_lsb0000.
Pull Request: https://github.com/llvm/llvm-project/pull/177743
This Change makes `RegState` into an enum class, with bitwise operators.
It also:
- Updates declarations of flag variables/arguments/returns from
`unsigned` to `RegState`.
- Updates empty RegState initializers from 0 to `{}`.
If this is causing problems in downstream code:
- Adopt the `RegState getXXXRegState(bool)` functions instead of using a
ternary operator such as `bool ? RegState::XXX : 0`.
- Adopt the `bool hasRegState(RegState, RegState)` function instead of
using a bitwise check of the flags.
This Change is to prepare to make RegState into an enum class. It:
- Updates documentation to match the order in the code.
- Brings the `get<>RegState` functions together and makes them
`constexpr`.
- Adopts the `get<>RegState` where RegStates were being chosen with
ternary operators in backend code.
- Introduces `hasRegState` to make querying RegState easier once it is
an enum class.
- Adopts `hasRegState` where equivalent was done with bitwise
arithmetic.
- Introduces `RegState::NoFlags`, which will be used for the lack of
flags.
- Documents that `0x1` is a reserved flag value used to detect if
someone is passing `true` instead of flags (due to implicit bool to
unsigned conversions).
- Updates two calls to `MachineInstrBuilder::addReg` which were passing
`false` to the flags operand, to no longer pass a value.
- Documents that `getRegState` seems to have forgotten a call to
`getEarlyClobberRegState`.
This PR relands llvm/llvm-project#176091 (commit
1d616cdca3aba9d22f120888bb6b09b75ca90b92) which was reverted in
llvm/llvm-project#176190 (commit
6309cd8668fc2ae589f156b23f86821f4ce5b7ea).
Reverts llvm/llvm-project#176091
Reverting because some compilers were erroring on the call to
`Reg.isReg()` (which is not `constexpr`) in a `constexpr` function.
This Change is to prepare to make RegState into an enum class. It:
- Updates documentation to match the order in the code.
- Brings the `get<>RegState` functions together and makes them
`constexpr`.
- Adopts the `get<>RegState` where RegStates were being chosen with
ternary operators in backend code.
- Introduces `hasRegState` to make querying RegState easier once it is
an enum class.
- Adopts `hasRegState` where equivalent was done with bitwise
arithmetic.
- Introduces `RegState::NoFlags`, which will be used for the lack of
flags.
- Documents that `0x1` is a reserved flag value used to detect if
someone is passing `true` instead of flags (due to implicit bool to
unsigned conversions).
- Updates two calls to `MachineInstrBuilder::addReg` which were passing
`false` to the flags operand, to no longer pass a value.
- Documents that `getRegState` seems to have forgotten a call to
`getEarlyClobberRegState`.
This preparatory patch introduces an additional argument to the target hook
loadRegFromStackSlot. Ths is essential for targets to handle subregister-specific
reload in the future. See how this is used for AMDGPU target with PR #175002.
We are currently only using `PseudoRV32ZdinxSD/LD` for spills and
reloads when the register class is `GPRPairRegClass` . However, we can
use `LD_RV32/SD_RV32` when the `Zilsd` extension is enabled and certain
alignment requirements are met.
Currently, we assign the same scheduling info to COPY regardless of
whether it's a scalar or vector one. But this might cause vector COPY
from physical registers to schedule too closed to its consumer,
prolonging the physical register live range and running out of registers
during RA as seen in #167008 .
This patch addresses this issue by creating schedule variants for COPY
instructions of vector register classes so that they can have the same
latency as simple vector arithmetics (WriteVIALUV). It is worth noting
that we _only_ need latency in this case -- keeping processor resources
in (vector) COPYs still causes the aforementioned register shortage
issue, because these COPY might then be blocked by structural hazards
and again, got sunk further down than we want.
Use the same twiden format for PseudoSF_VSETTM and PseudoSF_VSETTK
as other XSfmm pseudos. Though I don't think we use the operand from
these instructions.
`BranchRelxation` uses `RISCVInstrInfo::insertIndirectBranch` to insert
an indirect branch if the jump target is out of range. Currently it uses
register scavenging to find a free register to use for the indirect
target. If Zicfilp is enabled, we need to use X7 so that the jump will
be treated as a software guarded branch.
Co-authored-by: Yeting Kuo <46629943+yetingk@users.noreply.github.com>
Most of the immediate operands can only be an immediate, but we were
allowing any non-register operand.
Split the immediate-only from the immediate or non-register operands.
The non-register cases could be made even stricter, but I'll leave that
as a TODO.
New SFB subsets are being added with the scheduler class name as a
suffix, so now is the time to go back to the base extension and add IALU
to its name.
This also:
- Drops a hyphen from the other SFB features for mul and minmax, to more
closely match their scheduling classes.
- Updates the predicates on specific SFB pseudos so we get verifier
errors if we introduce the pseudos when we don't have the right
subtarget feature.
- Updates the SFB Documentation comment to make it no longer
SiFive-specific.
This is noted by the specification, and should save a dynamic
instruction.
Code size should be no worse than before, as the pairs of moves can
usually be turned into two 16-bit moves, but `fmv.d` is always a 32-bit
instruction.
LLVM can look through a `FSGNJ_D_IN32X`, in
`RISCVInstrInfo::isCopyInstrImpl` which helps copy propagation.
This is the initial support of P extension codegen, it only includes
small part of instructions:
PADD_H, PADD_B,
PSADD_H, PSADD_B,
PAADD_H, PAADD_B,
PSADDU_H, PSADDU_B,
PAADDU_H, PAADDU_B,
PSUB_H, PSUB_B,
PDIF_H, PDIF_B,
PSSUB_H, PSSUB_B,
PASUB_H, PASUB_B,
PDIFU_H, PDIFU_B,
PSSUBU_H, PSSUBU_B,
PASUBU_H, PASUBU_B
Both conceptually belong to the same subtarget, so it should not
be necessary to pass in the context TargetRegisterInfo to any
TargetInstrInfo member. Add this reference so those superfluous
arguments can be removed.
Most targets placed their TargetRegisterInfo as a member
in TargetInstrInfo. A few had this owned by the TargetSubtargetInfo,
so unify all targets to look the same.
Add support for outlining CFI instructions if
a) the outlined function is being tail called
b) all of the CFI instructions in the function are being outlined
This is similar to what is being done on AArch64 and X86.
---------
Co-authored-by: Craig Topper <craig.topper@sifive.com>
We have two mechanisms used in inline spilled for folding a load into a
consuming instruction. One is used for stack reloads, the other for
other load instructions (usually argument loads). We currently only
implement optimizations for the first case, but stackmaps have generic
support in target independent code for the other. We can go ahead and
set the flag to enable that optimization.
The primary motivation for this is that if we enable load
rematerialization without it, we run into crashes where we can't make
progress through rematerialization.
We probably should enable the other foldMemoryOperand hook for RISCV
specific instructions, but that's a separate optimization.
- [RISCV][llvm] Support Zvfbfa codegen and vsetvli insertion
- [RISCV][clang] Support Zvfbfa C intrinsics
The original PR is split into 2 PRs, this is codegen PR and other is
here: https://github.com/llvm/llvm-project/pull/164094
Co-authored-by: Craig Topper <craig.topper@sifive.com>
This patch supports the naive vset* insertion. If the state(tm, tn, tk,
sew, widen) changes, it emits all of the vset* instructions that are
needed, partial compatibility is not supported yet.
This is follow up patch for:
https://github.com/llvm/llvm-project/pull/133031
Co-authored-by: Piyou Chen <piyou.chen@sifive.com>
Co-authored-by: Craig Topper <craig.topper@sifive.com>
.. to isReMaterializableImpl. The "Really" naming has always been
awkward, and we're working towards removing the "Trivial" part now,
so go ehead and remove both pieces in a single rename.
Note that this doesn't change any aspect of the current
implementation; we still "mostly" only return instructions which
are trivial (meaning no virtual register uses), but some targets
do lie about that today.
After https://github.com/llvm/llvm-project/pull/139993, the
RISCVIndirectBranchTracking pass is also ran before the Machine Outliner
pass, this yield a possibility that the outliner could also outline the
LPAD instruction that should be placed at the target of an indirect
branch. This patch excludes LPAD instruction from the candidate of
machine outliner.
This will make it possible for tablegen to make subtarget
dependent decisions without adding new arguments to every
target.
---------
Co-authored-by: Sergei Barannikov <barannikov88@gmail.com>
TIL that MachineFunction actually stores a reference to
MachineRegisterInfo, so use that instead of plumbing it through. This
helps avoid the need to plumb MRI through static functions in #151285
If a VL operand is > 31 then it will be materialized into an ADDI $x0,
imm. We can reason about it by peeking at the virtual register
definition which allows RISCVVectorPeephole and RISCVVLOptimizer to
catch more cases.
There's a separate issue with RISCVVLOptimizer where the materialized
immediate may not always dominate the instruction we want to reduce the
VL of, but this is left to another patch.
The simplest way is:
1. Save `vtype` to a scalar register.
2. Insert a `vsetvli`.
3. Use segment load/store.
4. Restore `vtype` via `vsetvl`.
But `vsetvl` is usually slow, so this PR is not in this way.
Instead, we use wider whole load/store instructions if the register
encoding is aligned. We have done the same optimization for COPY in
https://github.com/llvm/llvm-project/pull/84455.
We found this suboptimal implementation when porting some video codec
kernels via RVV intrinsics.