This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: addsi3_mips16 and frame pointer with LRA


On 10/29/2013 09:43 AM, Matthew Fortune wrote:
> Hi Richard/Vladimir,
>
> I believe I finally understand one of the issues with LRA and mips16 but I can't see how to solve it. Take the following instruction:
>
> (insn 5 18 6 2 (set (reg:SI 4 $4)
>         (plus:SI (reg/f:SI 78 $frame)
>             (const_int 16 [0x10]))) test.c:6 13 {*addsi3_mips16}
>      (nil))
>
> $frame will be eliminated to either $sp or the hard frame pointer, which for mips16 is $17. The problem here is that there is no single alternative that accepts either $sp or $17 because the supported immediate range is different for $sp(ks) and $17(d). The "ks" alternative is disregarded (presumably because there is no way to reload into $sp if that ended up being necessary) and instead the "d" alternative is chosen. If the frame pointer is needed then this works well because $17 is used and fits the "d" constraint however when the frame pointer is omitted $sp has to be reloaded into a "d" register even though there is another alternative which it would directly match.
>
> The fragment of the reload dump:
>
>             1 Matching alt: reject+=2
>             1 Non-pseudo reload: reject+=2
>           alt=4,overall=10,losers=1,rld_nregs=1
>             1 Matching alt: reject+=2
>             1 Non-pseudo reload: reject+=2
>           alt=5,overall=10,losers=1,rld_nregs=1
>             1 Non-pseudo reload: reject+=2
>             1 Non-pseudo reload: reject+=2
>           alt=7,overall=8,losers=1,rld_nregs=1
>             1 Non-pseudo reload: reject+=2
>             2 Non-pseudo reload: reject+=2
>             2 Non input pseudo reload: reject++
>             alt=8,overall=17,losers=2 -- refuse
>          Choosing alt 7 in insn 5:  (0) d  (1) d  (2) O {*addsi3_mips16}
>       Creating newreg=198 from oldreg=78, assigning class M16_REGS to r198
>
> And the end result is:
>
> (insn 20 18 5 2 (set (reg/f:SI 2 $2 [198])
>         (reg/f:SI 29 $sp)) test.c:6 290 {*movsi_mips16}
>      (nil))
> (insn 5 20 6 2 (set (reg:SI 4 $4)
>         (plus:SI (reg/f:SI 2 $2 [198])
>             (const_int 16 [0x10]))) test.c:6 13 {*addsi3_mips16}
>      (nil))
>
> The only way I can currently see to get any direct usage of $sp in an add instruction would be to artificially reduce the permitted immediate range by 1 bit so that there is a single alternative that allows either "ks" or "d" with a 15bit immediate. I don't really want to do that though. I initially allowed $frame to be treated as per $sp but that led to an ICE when $frame was eliminated to $17 and the immediate was out of range.
>
> Have I missed anything that would allow me to support the full immediate range in all cases?
Sorry, I can not reproduce this using a test from PR58461 and patch
enabling LRA for mips.

It is hard for me to say what is going on.  Elimination is done when we
match hard reg against constraints.  May be elimination to hfp is
rejected on some sub-pass and LRA don't try all alternatives after this.

Could you send me the test from which you got this dumps and what
options did you use.  I can say more.   As I understand there should be
no such problem.  If reload can do right think, LRA should do the same.


>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]