diff options
author | Christoph Müllner <christoph.muellner@vrull.eu> | 2022-09-28 11:19:06 +0200 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2023-09-12 11:36:16 +0200 |
commit | df48285b2484eb4f8e0570c566677114eb0e553a (patch) | |
tree | 18c042643132e1cc1774217eaf062698256ce20d /gcc/rtl.h | |
parent | fb5d27be272b71fb9026224535fc73f125ce3be7 (diff) | |
download | gcc-df48285b2484eb4f8e0570c566677114eb0e553a.zip gcc-df48285b2484eb4f8e0570c566677114eb0e553a.tar.gz gcc-df48285b2484eb4f8e0570c566677114eb0e553a.tar.bz2 |
riscv: Add support for strlen inline expansion
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.muellner@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.
Diffstat (limited to 'gcc/rtl.h')
-rw-r--r-- | gcc/rtl.h | 2 |
1 files changed, 2 insertions, 0 deletions
@@ -3347,6 +3347,8 @@ extern rtx_note *emit_note_after (enum insn_note, rtx_insn *); extern rtx_insn *emit_insn (rtx); extern rtx_insn *emit_debug_insn (rtx); extern rtx_insn *emit_jump_insn (rtx); +extern rtx_insn *emit_likely_jump_insn (rtx); +extern rtx_insn *emit_unlikely_jump_insn (rtx); extern rtx_insn *emit_call_insn (rtx); extern rtx_code_label *emit_label (rtx); extern rtx_jump_table_data *emit_jump_table_data (rtx); |