This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
question about spill failure - I smell a wumpus :-)
- To: gcc at gcc dot gnu dot org
- Subject: question about spill failure - I smell a wumpus :-)
- From: apl at alum dot mit dot edu
- Date: Tue, 19 Jun 2001 00:02:28 -0400 (EDT)
- cc: amylaar at redhat dot com, apl at alum dot mit dot edu
I've got a test case for a port I'm doing with a small number of
pointer registers that fails because it's unable to find an
appropriate pointer register.
I normally know how to track down these problems.
BUT, this one is unusual. The test case only fails when compiling THE
SECOND of two functions. If I reverse the order of definition, then
both functions compile. If I compile the second function by itself
it compiles too. Note that there is NO inlining occurring.
I can't think of ANYTHING where the register allocation should
remember any state between functions (other than global registers,
which we're not using....) I suppose I could start up TWO copies of
gdb and parallel step my way thru the reload pass. But I wonder if
anyone has any cleverer ideas?
Here's the RTL for the insn that it can't spill.
(insn 30 28 32 (set (reg/f:QI 33)
(plus:QI (mem/s:QI (reg/f:QI 29) 0)
(mem/s:QI (reg/f:QI 17 ptr1 [32]) 0))) 15 {*tpc.md:741} (insn_list 26 (insn_list 20 (nil)))
(nil))
There are quite a few reloads required for this (33 is a pseudo forced
to a stack location, and the machine doesn't support offset
addressing, only indirection (shades of the Univac 1100s!) I believe
that the spill failure occurs with reload #2.
(gdb) call debug_reload()
Reload 0: reload_in (QI) = (plus:QI (reg/f:QI 19 sp)
(const_int 1 [0x1]))
PTR_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0)
reload_in_reg: (plus:QI (reg/f:QI 19 sp)
(const_int 1 [0x1]))
Reload 1: reload_in (QI) = (mem:QI (plus:QI (reg/f:QI 19 sp)
(const_int 1 [0x1])) 0)
PTR_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine
reload_in_reg: (reg/f:QI 29)
Reload 2: reload_in (QI) = (mem/s:QI (reg/f:QI 29) 0)
reload_out (QI) = (reg/f:QI 33)
PTR_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (mem/s:QI (reg/f:QI 29) 0)
reload_out_reg: (reg/f:QI 33)
Reload 3: reload_in (QI) = (mem/s:QI (reg/f:QI 17 ptr1 [32]) 0)
GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 2), optional
reload_in_reg: (mem/s:QI (reg/f:QI 17 ptr1 [32]) 0)
(gdb)
What really has me confused is the fact that it doesn't fail if
the _Balloc() function isn't compiled before the _Bfree() function.
The spill failure is in compiling _Bfree.
_Bigint *
_Balloc(struct _reent *ptr , int k)
{
int x;
_Bigint *rv ;
ptr->_freelist = (struct _Bigint **) _calloc_r (ptr,
sizeof (struct _Bigint *),
15 + 1);
return rv;
}
void
_Bfree(struct _reent *ptr , _Bigint * v)
{
if (v)
{
v->_next = ptr->_freelist[v->_k];
ptr->_freelist[v->_k] = v;
}
}