|
From: | Andrew Hutchinson |
Subject: | Re: [avr-gcc-list] Bug 31786 spill in class 'BASE_POINTER_REGS' |
Date: | Tue, 01 Jan 2008 15:53:07 -0500 |
User-agent: | Thunderbird 2.0.0.9 (Windows/20071031) |
Weddington, Eric wrote:
Avoiding "Z" will help. This frees up base pointer. Function pointers are diffiicult to avoid unless we use stack.-----Original Message-----From: address@hidden [mailto:address@hiddenorg] 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_ADDRESSBut 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.
for gcc dump files use -dA. This gives each pass of compiler. Helps track down if problem is created by GCC - or target. In this case, it did not list the "transient" instructions that caused problem.This bug testcase has a indirect call - which must use Z. "count" and the index 'i' are potentially on the stack. Which accounts for R28extern 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 - theWhat do you mean by dump files? What flags are you using?
for avr dump (to stderr) use -mdeb. This will give debugging infor from some back end routines.
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
I will create a patch when I think it is "stable" enough to test vigorously.
[Prev in Thread] | Current Thread | [Next in Thread] |