[Patch, AVR]: Fix PR46779

Denis Chertykov chertykov@gmail.com
Sun Jun 12 10:34:00 GMT 2011

2011/6/10 Georg-Johann Lay <avr@gjlay.de>:
> Then I have a question on spill failures:
> There is PR46278, an optimization flaw that goes as follows:
> The avr BE defines fake addressing mode X+const that has to be written
> down in asm as
>  X += const
>  a = *X
>  X -= const
> The comment says that this is just to cover a corner case, however the
> new register allocator uses this case more often or even greedily.
> There is no way to describe the cost for such an access, and as X has
> lower prologue/epilogue cost than Y, X is preferred over Y often.
> In 4.7, I see that flaw less often than in 4.5.  However, I think the
> best way is not to lie at the register allocator and not to supply a
> fake instruction like that.
> So I started to work on a fix. The changes in avr.h are:
>        * config/avr/avr.h (BASE_REG_CLASS): Remove.
>        (REG_OK_FOR_BASE_NOSTRICT_P): Remove.
>        (REG_OK_FOR_BASE_STRICT_P): Remove.
>        (MODE_CODE_BASE_REG_CLASS): New Define.
>        (REGNO_MODE_CODE_OK_FOR_BASE_P): New Define.
> allow a better, fine grained control over addressing modes for each
> hard register and allow to support X without fake instructions. The
> code quality actually improves, but I see a new spill failure for the
> test case
> * gcc.c-torture/compile/950612-1.c
> On the one hand, that test case has heavy long long use and is no
> "real world code" to run on AVR. On the other hand, I don't think
> trading code quality here against ICE there is a good idea.
> What do you think about that? As I have no idea how to fix a spill
> failure in the backend, I stopped working on a patch.

Ohhh. It's a most complicated case for GCC for AVR.
Look carefully at `out_movqi_r_mr'.
There are even two fake addressing modes:
1. [Y + infinite-dslacement];
2. [X + (0...63)].
I have spent a many hours (days, months) to debug GCC (especially avr port
and reload) for right addressing modes.
I have stopped on this code.
AVR have a limited memory addressing and GCC can't handle it in native form.
Because of that I have supported a fake adddressing modes.
(Richard Henderson have a different oppinion: GCC can, AVR port can't)
IMHO that three limited pointer registers is not enough for C compiler.
Even more with frame pointer it's only two and X is a very limited.

1. [Y + infinite-dslacement] it's helper for reload addressing.
For addressing too long local/spilled variable. (Y + more-than-63)

2. [X + (0...63)] for another one "normal" pointer address.

> Then I observed trouble with DI patterns during libgcc build and had
> to remove
> * "zero_extendqidi2"
> * "zero_extendhidi2"
> * "zero_extendsidi2"
> These are "orphan" insns: they deal with DI without having movdi
> support so I removed them.

This seems strange for me.


More information about the Gcc-patches mailing list