[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] Bug 31786 spill in class 'BASE_POINTER_REGS'
From: |
Weddington, Eric |
Subject: |
RE: [avr-gcc-list] Bug 31786 spill in class 'BASE_POINTER_REGS' |
Date: |
Tue, 1 Jan 2008 13:45:13 -0700 |
> -----Original Message-----
> From:
> address@hidden
> [mailto:address@hidden
> org] On Behalf Of Andrew Hutchinson
> Sent: Tuesday, January 01, 2008 1:11 PM
> To: address@hidden
> Subject: [avr-gcc-list] Bug 31786 spill in class 'BASE_POINTER_REGS'
>
> In particular 31786 - which is one example of where we get
> fatal error of :
>
> error: unable to find a register to spill in class 'BASE_POINTER_REGS'
>
> This is a nasty bug as it comes and goes with optimisation
> changes and
> there are no robust work arounds.
> reload in GCC is a magic bit that replaces pseudo registers with real
> ones - or stack slots.
>
> The problem occurs when reload tries to replace a stack
> address (SP+1)
> with one that is valid for AVR (Y+1) or (Z+1).
>
> There are only two base pointer registers Y (R28,29) and
> Z(R30,3). AVR
> backend tells reload to use these via LEGITIMIZE_RELOAD_ADDRESS
> But if they are both already in use, we get the ICE.
>
> The problem typically occurs when R30,31 is used for indirect calls
> (function pointer) or EEPROM/Assembler macros. (leaving only R28)
See also bug #31644
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31644>
For another ICE when using EEPROM macros.
I am planning to rewrite the EEPROM implementation in avr-libc (keeping
it API compatible) to implement it via macros instead of assembly
routines. The goal is to solve GCC bug #31644 and a couple of avr-libc
bugs where the EEPROM routines fail for a couple of AVR devices. The
point is to remove the explicit use of Z in the EEPROM routines. I'm
planning to do this rewrite sometime next week.
> This bug testcase has a indirect call - which must use Z. "count" and
> the index 'i' are potentially on the stack. Which accounts for R28
>
> extern void (*array_start []) (void);
> extern void (*array_end []) (void);
>
> void
> init_array (void)
> {
> int count;
> int i;
> count = array_end - array_start;
> for (i = 0; i < count; i++)
> array_start[i] ();
> }
>
>
> But i have not been able to figure out why it could not reuse R28.
> Perhaps R28 is tied up with 'array_start'?
>
> The Gcc dump files don't disclose the RTL instruction sequence - the
What do you mean by dump files? What flags are you using?
> failed instruction was one "reload" had added since the last
> pass (and
> last dump file).
> I am of the opinion that we should indeed permit R26 to be
> used as index
> (and maybe others). I believe we can still make gcc prefer
> Y&Z - if it
> doesnt already. If so there should be no penalty in code size
> and speed
> (in fact it might be better). Simplistically, the only time
> R26 would be
> used in this manner would be where we currently get fatal error.
>
> I have further opinion that LEGITIMIZE_RELOAD_ADDRESS is
> doing to much.
> Looking at other ports, they only seem to attempt to adjust
> pointers to
> account for large offsets eg. (SP+99) - and leave rest to GCC.
>
> I have compiled some other code and compared to Winavr, and
> so far, all
> is ok. I could do with some help though in checking for
> regressions and
> forming a bench mark for code size effects.
I can maybe provide some limited assistance in this area.
Can you also provide a patch that implements your changes?
Thanks,
Eric Weddington