This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

question about spill failure - I smell a wumpus :-)



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;
	}
    }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]