Comment 2 for bug 637882

Revision history for this message
Julian Brown (julian-codesourcery) wrote : Re: [Bug 637882] [NEW] [size, thumb2] Combine ldr/mov to ldr

On Tue, 14 Sep 2010 08:36:58 -0000
Yao Qi <email address hidden> wrote:

> Public bug reported:
>
> Test case is reduced from CINT2000/175.vpr/util.c:free_chunk_memory(),
> and compile it with GCC FSF trunk,
>
> $ arm-none-linux-gnueabi-gcc --version
> arm-none-linux-gnueabi-gcc (GCC) 4.6.0 20100902 (experimental)
> Copyright (C) 2010 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions. There
> is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
> PARTICULAR PURPOSE. $ arm-none-linux-gnueabi-gcc -march=armv7-a
> -mthumb -Os -O3 -mcpu=cortex-a9 -S extra_ldr_mov.c
>
> GCC generates code like this,
> free_chunk_memory:
> @ args = 0, pretend = 0, frame = 0
> @ frame_needed = 0, uses_anonymous_args = 0
> push {r3, r4, r5, lr}
> cbz r0, .L1
> mov r4, r0
> b .L3
> .L4:
> mov r4, r5 // <---[2]
> .L3:
> ldr r0, [r4, #0]
> bl free
> ldr r5, [r4, #4] // <---[1]
> mov r0, r4 // <--- [3]
> bl free
> cmp r5, #0
> bne .L4
>
> We can exchange instruction [1] and [3], and change instruction [1] to
> 'ldr r4, [r4, #4]', then instruction [2] can be removed.

So we'd have:

.L4:
        // mov r4, r5 // <---[2]
.L3:
        ldr r0, [r4, #0]
        bl free
        mov r0, r4 <-- [3]
        ldr r4, [r4, #4] <-- [1], modified
        bl free
        cmp r4, #0 // we'd need to change this too!
        bne .L4

This is kind of about reducing register pressure by shuffling
instructions around -- by removing the interference between r4 & r5, we
can get away with using one fewer register (and hence removing copies
between those two registers, since they're now the same). It's not
purely about reducing live ranges though, since r0 is now live for
longer (over [1]).

That seems like a useful capability in general, though I have no idea
how we'd tackle it in practice.

Julian