Fix for reload-failure

Geoff Keating geoffk@geoffk.org
Sat Feb 8 00:17:00 GMT 2003


> Date: Fri, 7 Feb 2003 23:46:13 +0100 (CET)
> From: Michael Matz <matz@suse.de>

> Hi,
> 
> On 7 Feb 2003, Geoff Keating wrote:
> 
> > > Now, when the actual insns for the reloads are emitted, some subfunctions
> > > of emit_move_insn() (in particular legitimize_pic_address() in i386.c)
> > > notices, that the address of the constant "(symbol_ref/u:SI ("*.LC0"))" is
> > > not actually a valid PIC address, so it makes it simply valid, and because
> > > it's written in the way it is, it also changes regs_ever_live[] for the
> > > PIC-reg (which now indeed is required) to 1.
> >
> > This is the problem.  If the address isn't a legitimate address, reload
> > should have noticed this earlier,
> 
> I agree, but that's not easily possible.  Because there are
> target-dependent ways to make an address legitimate for PIC, and some of
> them involve to emit code.  As far as reload is concerned the address from
> force_const_mem() is a valid address (and it actually is, if flag_pic
> weren't set).  The address is only created during collecting reloads, so
> it can't be validized before.  And during collecting reloads, there shall
> be no changes in the code.  And validizing a PIC address isn't always
> possible with reloads.  For instance for this case the address first is:
>   (symbol_ref/u:SI ("*.LC0"))
> 
> to validize that for PIC it needs to be changed into:
>   (plus:SI (reg:SI 3 ebx)
>             (const:SI (unspec:SI [
>                         (symbol_ref/u:SI ("*.LC0"))
>                     ] 1)))
> 
> There simply _is_ no reload which does something like that, so if the
> first address weren't valid for reload it would do strange and funny
> things while trying to make it valid (because it's just a symref it can't
> really split it more, loading it into a reg doesn't make it go away, so
> _somewhere_ the symref would remain, and then while emitting the reloads,
> the same would happen as now).

This is what LEGITIMIZE_RELOAD_ADDRESS is for.

It may be there's an easier-to-code way to handle the same situation.
In ix86_save_reg, there's:

  if (pic_offset_table_rtx
      && regno == REAL_PIC_OFFSET_TABLE_REGNUM
      && (regs_ever_live[REAL_PIC_OFFSET_TABLE_REGNUM]
          || current_function_profile
          || current_function_calls_eh_return))

Just add 'current_function_uses_const_pool' to the list.  I can't
guarantee that'll work for all cases, though.

-- 
- Geoffrey Keating <geoffk@geoffk.org>



More information about the Gcc-patches mailing list