On Sat, Apr 28, 2012 at 5:31 PM, Bernd Schmidt <ber...@codesourcery.com> wrote: > This patch allows us to recognize that even if the argument to memcpy lives > across the call, we can allocate it to a call-used register by reusing the > return value of the function. > > First, the patch sets the existing "fn spec" attribute for memcpy/memmove. > This is translated to a new form of CALL_INSN_FUNCTION_USAGE, a (set > (returnreg) (argreg)). This is recognized by IRA to adjust costs, and for > communicating to caller-save that the register can be restored cheaply. > > The optimization only triggers if the argument is passed in a register, > which should be the case in the majority of sane ABIs. The effect on the new > testcase: > > pushq %rbx | subq $8, %rsp > movslq %edx, %rdx movslq %edx, %rdx > movq %rdi, %rbx < > call memcpy call memcpy > movq %rbx, %rax | addq $8, %rsp > popq %rbx < > ret ret > > Bootstrapped with all languages on i686-linux, and bootstrapped and tested > minus Ada on x86_64-linux. There's one Go test which seems to fail randomly > both with and without the patch: > FAIL: go.test/test/stack.go execution, -O2 -g > > Ok?
Heh, interesting idea. I suppose you chose memcpy/memmove because the middle-end emits those for block moves? I see you've gone all the way generalizing support for this instead of a special hack (an RTL flag on the call, directly set by the expander?) for this case? I've chickened out at adding fnspec annotations to builtins because of the explosion of various strings that would need ;) That said, I like it but will leave the RTL / IRA parts to someone else to look at. Thanks, Richard. > > Bernd