]> git.ipfire.org Git - thirdparty/gcc.git/commit
[RISC-V] Detect new fusions for RISC-V
authorDaniel Barboza <dbarboza@ventanamicro.com>
Thu, 10 Jul 2025 13:28:38 +0000 (07:28 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Thu, 10 Jul 2025 13:30:15 +0000 (07:30 -0600)
commit742f55622690d35c6cc95f2b8722307699731571
tree008e74602ffd85213c3c52c22d24a3648cc992d0
parent2ff8da46152cbade579700823cc7b1460ddd91b8
[RISC-V] Detect new fusions for RISC-V

This is primarily Daniel's work...  He's chasing things in QEMU & LLVM right
now so I'm doing a bit of clean-up and shepherding this patch forward.

--

Instruction fusion is a reasonably common way to improve the performance of
code on many architectures/designs.  A few years ago we submitted (via VRULL I
suspect) fusion support for a number of cases in the RISC-V space.

We made each type of fusion selectable independently in the tuning structure so
that designs which implemented some particular set of fusions could select just
the ones their design implemented.  This patch adds to that generic
infrastructure.

In particular we're introducing additional load fusions, store pair fusions,
bitfield extractions and a few B extension related fusions.

Conceptually for the new load fusions we're adding the ability to fuse most
add/shNadd instructions with a subsequent load.  There's a couple of
exceptions, but in general the expectation is that if we have add/shNadd for
address computation, then they can potentially use with the load where the
address gets used.

We've had limited forms of store pair fusion for a while.  Essentially we
required both stores to be 64 bits wide and land on opposite sides of a 128 bit
cache line.  That was enough to help prologues and a few other things, but was
fairly restrictive.  The new cases capture store pairs where the two stores
have the same size and hit consecutive memory locations.  For example, storing
consecutive bytes with sb+sb is fusible.

For bitfield extractions we can fuse together a shift left followed by a shift
right for arbitrary shift counts where as previously we restricted the shift
counts to those implementing sign/zero extensions of 8, and 16 bit objects.

Finally some B extension fusions.  orc.b+not which shows up in string
comparisons, ctz+andi (deepsjeng?), neg+max (synthesized abs).

I hope these prove to be useful to other RISC-V designs.  I wouldn't be
surprised if we have to break down the new load fusions further for some
designs.  If we need to do that it wouldn't be hard.

FWIW, our data indicates the generalized store fusions followed by the expanded
load fusions are the most important cases for the new code.

These have been tested with crosses and bootstrapped on the BPI.

Waiting on pre-commit CI before moving forward (though it has been failing to
pick up some patches recently...)

gcc/
* config/riscv/riscv.cc (riscv_fusion_pairs): Add new cases.
(riscv_set_is_add): New function.
(riscv_set_is_addi, riscv_set_is_adduw, riscv_set_is_shNadd): Likewise.
(riscv_set_is_shNadduw): Likewise.
(riscv_macro_fusion_pair_p): Add new fusion cases.

Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
gcc/config/riscv/riscv.cc