> -----Original Message-----
> From: Eric Botcazou [mailto:ebotca...@adacore.com]
> Sent: Saturday, June 15, 2013 5:37 PM
> To: Bin Cheng
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH GCC]Fix PR57540, try to choose scaled_offset address
mode
> when expanding array reference
> 
> > As reported in pr57540, gcc chooses bad address mode, resulting in A)
> > invariant part of address expression is not kept or hoisted; b)
> > additional computation which should be encoded in address expression.
> > The reason is when gcc runs into "addr+offset" (which is invalid)
> > during expanding, it pre-computes the entire address and accesses memory
> unit using "MEM[reg]".
> > Yet we can force addr into register and try to generate "reg+offset"
> > which is valid for targets like ARM.  By doing this, we can:
> > 1) keep addr in loop invariant form and hoist it later;
> > 2) saving additional computation by taking advantage of scaled
> > addressing mode;
> 
> Does the invalid address not go through arm_legitimize_address from here?
> 
>       /* Perform machine-dependent transformations on X
>        in certain cases.  This is not necessary since the code
>        below can handle all possible cases, but machine-dependent
>        transformations can make better code.  */
>       {
>       rtx orig_x = x;
>       x = targetm.addr_space.legitimize_address (x, oldx, mode, as);
>       if (orig_x != x && memory_address_addr_space_p (mode, x, as))
>         goto done;
>       }
> 

Hi Eric,

The problem occurs when accessing local array element. For example,
# VUSE <.MEM_27>
k_8 = parent[k_29];

GCC calculates the address in three steps:
1) addr is calculated as "r105 + (-2064)".
2) offset is calculated as "r165*4".
3) calls offset_address to combine the address into "r105+ r165*4 +
(-2064)".

Since ADDR is valid and there is no call to memory_address_addr_space in
offset_address, the invalid address expression has no chance to go through
target dependent legitimization function.  Even there is a chance, the
current implementation of memory_address_addr_space prevents the scaled
address expression from being generated because of below code:
      if (! cse_not_expected && !REG_P (x))
          x = break_out_memory_refs (x);

Thanks.
bin



Reply via email to