On 9/6/23 10:07, Christoph Muellner wrote:
From: Christoph Müllner <christoph.muell...@vrull.eu>

This patch implements the expansion of the strlen builtin for RV32/RV64
for xlen-aligned aligned strings if Zbb or XTheadBb instructions are available.
The inserted sequences are:

rv32gc_zbb (RV64 is similar):
       add     a3,a0,4
       li      a4,-1
.L1:  lw      a5,0(a0)
       add     a0,a0,4
       orc.b   a5,a5
       beq     a5,a4,.L1
       not     a5,a5
       ctz     a5,a5
       srl     a5,a5,0x3
       add     a0,a0,a5
       sub     a0,a0,a3

rv64gc_xtheadbb (RV32 is similar):
       add       a4,a0,8
.L2:  ld        a5,0(a0)
       add       a0,a0,8
       th.tstnbz a5,a5
       beqz      a5,.L2
       th.rev    a5,a5
       th.ff1    a5,a5
       srl       a5,a5,0x3
       add       a0,a0,a5
       sub       a0,a0,a4

This allows to inline calls to strlen(), with optimized code for
xlen-aligned strings, resulting in the following benefits over
a call to libc:
* no call/ret instructions
* no stack frame allocation
* no register saving/restoring
* no alignment test

The inlining mechanism is gated by a new switch ('-minline-strlen')
and by the variable 'optimize_size'.

Tested using the glibc string tests.

Signed-off-by: Christoph Müllner <christoph.muell...@vrull.eu>

gcc/ChangeLog:

        * config.gcc: Add new object riscv-string.o.
        riscv-string.cc.
        * config/riscv/riscv-protos.h (riscv_expand_strlen):
        New function.
        * config/riscv/riscv.md (strlen<mode>): New expand INSN.
        * config/riscv/riscv.opt: New flag 'minline-strlen'.
        * config/riscv/t-riscv: Add new object riscv-string.o.
        * config/riscv/thead.md (th_rev<mode>2): Export INSN name.
        (th_rev<mode>2): Likewise.
        (th_tstnbz<mode>2): New INSN.
        * doc/invoke.texi: Document '-minline-strlen'.
        * emit-rtl.cc (emit_likely_jump_insn): New helper function.
        (emit_unlikely_jump_insn): Likewise.
        * rtl.h (emit_likely_jump_insn): New prototype.
        (emit_unlikely_jump_insn): Likewise.
        * config/riscv/riscv-string.cc: New file.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/xtheadbb-strlen-unaligned.c: New test.
        * gcc.target/riscv/xtheadbb-strlen.c: New test.
        * gcc.target/riscv/zbb-strlen-disabled-2.c: New test.
        * gcc.target/riscv/zbb-strlen-disabled.c: New test.
        * gcc.target/riscv/zbb-strlen-unaligned.c: New test.
        * gcc.target/riscv/zbb-strlen.c: New test.
Note that I don't think we need the new UNSPEC_STRLEN since its only used in the expander and doesn't survive into RTL. Your call on whether or not to remove it now or as a separate patch (or keep it if I'm wrong about it not being needed.

OK for the trunk.  Sorry this got lost in the shuffle last year.

jeff
.

Reply via email to