avr-gcc-list
[Top][All Lists]
Advanced

[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: 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:
-----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.

Avoiding "Z" will help. This frees up base pointer. Function pointers are diffiicult to avoid unless we use stack.


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?
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.

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.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]