]> git.ipfire.org Git - thirdparty/gcc.git/commit
AVR: rtl-optimization/121340 - New mini-pass to undo superfluous moves from insn...
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 30 Jul 2025 10:34:56 +0000 (12:34 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Thu, 31 Jul 2025 18:31:30 +0000 (20:31 +0200)
commit7d75e87f3051fa29d48e923016f04a8042a8ec53
treebfa89b59bc0c3bb29a4a4624c21b80fef32b5ceb
parentf6462f664725844faa97ae7e8690e4fedee65788
AVR: rtl-optimization/121340 - New mini-pass to undo superfluous moves from insn combine.

Insn combine may come up with superfluous reg-reg moves, where the combine
people say that these are no problem since reg-alloc is supposed to optimize
them.  The issue is that the lower-subreg pass sitting between combine and
reg-alloc may split such moves, coming up with a zoo of subregs which are
only handled poorly by the register allocator.

This patch adds a new avr mini-pass that handles such cases.

As an example, take

int f_ffssi (long x)
{
    return __builtin_ffsl (x);
}

where the two functions have the same interface, i.e. there are no extra
moves required for the argument or for the return value. However,

$ avr-gcc -S -Os -dp -mno-fuse-move ...

f_ffssi:
mov r20,r22  ;  29 [c=4 l=1]  movqi_insn/0
mov r21,r23  ;  30 [c=4 l=1]  movqi_insn/0
mov r22,r24  ;  31 [c=4 l=1]  movqi_insn/0
mov r23,r25  ;  32 [c=4 l=1]  movqi_insn/0
mov r25,r23  ;  33 [c=4 l=4]  *movsi/0
mov r24,r22
mov r23,r21
mov r22,r20
rcall __ffssi2  ;  34 [c=16 l=1]  *ffssihi2.libgcc
ret  ;  37 [c=0 l=1]  return

where all the moves add up to a no-op.  The -mno-fuse-move option
stops any attempts by the avr backend to clean up that mess.

PR rtl-optimization/121340
gcc/
* config/avr/avr.opt (-mfuse-move2): New option.
* config/avr/avr-passes.def (avr_pass_2moves): Insert after combine.
* config/avr/avr-passes.cc (make_avr_pass_2moves): New function.
(pass_data avr_pass_data_2moves): New static variable.
(avr_pass_2moves): New rtl_opt_pass.
* config/avr/avr-protos.h (make_avr_pass_2moves): New proto.
* common/config/avr/avr-common.cc
(default_options avr_option_optimization_table) <-mfuse-move2>:
Set for -O1 and higher.
* doc/invoke.texi (AVR Options) <-mfuse-move2>: Document.
gcc/common/config/avr/avr-common.cc
gcc/config/avr/avr-passes.cc
gcc/config/avr/avr-passes.def
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.opt
gcc/doc/invoke.texi