> On Tue, May 12, 2015 at 10:17:01PM +0000, James Bowman wrote:
> > It seems that with whenever a function's frame is bigger than 512 bytes,
> > LRA loops.  Likely this causes a problem because there is no actual
> > instruction for subtracting constants more than 512.  However, there is a
> > "link" pattern that allows this. It is puzzling.
>
> That "link" pattern does
>
>         (minus (reg) (imm))
>
> but that is not canonical RTL; it should be written
>
>         (plus (reg) (-imm))
>

OK, thanks. I have corrected this. Seeing the same failure with LRA.

> Compile with -da to get dump files, look at the .reload one (which is
> for LRA if that is enabled), stare long and hard.  I recommend coffee.

OK! Looking more at this, the LRA is not actually looping on the link, but on 
an address calculation
So this code:

  int runtest_bigframe()
  {
    unsigned int i;
    unsigned char buf[900];

    for (i = 0; i < 900; i++)
      buf[i] = (i % 237);

Causes this address calculation, attempting to compute the address of buf[]:

(insn 36 30 37 2 (set (reg:SI 96)
        (const_int -900 [0xfffffffffffffc7c])) /home/james/tmp/x.c:11 25 
{*movsi}
     (expr_list:REG_EQUIV (const_int -900 [0xfffffffffffffc7c])
        (nil)))
(insn 37 36 39 2 (set (reg:SI 97)
        (plus:SI (reg/f:SI 0 $fp)
            (reg:SI 96))) /home/james/tmp/x.c:11 2 {addsi3}
     (expr_list:REG_DEAD (reg:SI 96)
        (expr_list:REG_EQUIV (plus:SI (reg/f:SI 0 $fp)
                (const_int -900 [0xfffffffffffffc7c]))
            (nil))))

And LRA loops on insn 37, repeatedly allocating a register for (reg:SI 97).

However, something like this:

  void foo (void)
  {
    unsigned char buf[900];
    bar(buf);
  }

Happily compiles, even though the address calculation is identical!

  foo: 
          link   $fp,924
          ldk.l  $r0,-900
          add.l  $r0,$fp,$r0
          call   bar
          unlink $r29
          return

Here is the relevant part of the dump, just before reload as above:

(insn 11 6 7 2 (set (reg:SI 43)
        (const_int -900 [0xfffffffffffffc7c])) /home/james/tmp/x.c:31 25 
{*movsi}
     (expr_list:REG_EQUIV (const_int -900 [0xfffffffffffffc7c])
        (nil)))
(insn 7 11 8 2 (set (reg:SI 2 $r0)
        (plus:SI (reg/f:SI 0 $fp)
            (reg:SI 43))) /home/james/tmp/x.c:31 2 {addsi3}
     (expr_list:REG_DEAD (reg:SI 43)
        (nil)))

They look very similar. I am currently baffled. 

> > Do you think it would be easier to make the submission as is, then debug
> > the LRA issues from that point? If so, I have attached the current patch 
> > set.
>
> You should add a -mlra option so other people can easily enable it, too;
> also handy later (when it defaults to on) when LRA blows up (you can
> workaround with -mno-lra then).

Sounds good to me. Would that be an acceptable way to get the FT32 port 
into the tree? I am very happy to go with the general flow towards LRA,
but at this point perhaps it may be a little early?

--
James Bowman
FTDI Open Source Liaison

Reply via email to