Patch to improve register elimination

Jeffrey A Law law@hurl.cygnus.com
Sun Feb 28 18:15:00 GMT 1999


  In message < 199902122331.SAA25820@jwlab.FEITH.COM >you write:
  > I believe so.  My impression is that a chain of eliminations will be
  > processed by eliminate_regs and eliminate_rgs_in_insn one link at a
  > time with reload calling set_inital_label_offset (which calls
  > set_label_offsets) and calculate_needs_all_insns calling
  > set_label_offsets between each link so if the chain is:
  > 
  >   ARG -> FRAME
  >   FRAME -> STACK
  > 
  > and the ARG pointer is used in the last block and the offset between
  > the FRAME and STACK isn't known then the first pass of reload will
  > replace ARG with FRAME and (due to my change) not disable the FRAME
  > to STACK elimination.  The second pass of reload will disable the
  > FRAME to STACK elimination since the offset isn't known and the
  > FRAME is being used.
OK.  I just walked through the path too.  I'm still not sure it will actually
work.

Let's assume the port defines an elimination from ap->fp and from fp->sp, but
not one from ap->sp (ie, it relies on multiple iterations to eliminate from
ap->sp).

Let's assume the last block has no references to fp or sp, but does have a
reference to ap.

can_eliminate for ap->fp and fp->sp will be initially be true because there
are no references to either fp or sp in the last block.  So we replace ap with
fp.

Assume nothing else changes.  We set chain->need_elim &
something_needs_elimination, then eventually exit from
calculate_needs_all_insns.


update_eliminables is called soon after calculate_needs_all_insns returns, but
I don't see that it will notice the case where we can no longer eliminate
fp->sp in the last block (because the last block now references fp).  So 
update_eliminables doesn't generate any new spills.

Also assume that finish_spills has nothing to do, so it returns zero.

Now, since nothing has set "something_changed" the big for loop in reload
exits.  And I think we end up losing.

This is rather complex, so maybe I missed something.    I do believe that if
the big for loop iterates again that the right thing will happen, but I can't
convince myself that the loop will iterate again.

  > Granted I haven't given this a lot of thought, however is it actually all
  > that common for an elimination to be disabled due to the offset being
  > unknown at a label (other than due to the EXIT_IGNORE_STACK optimization)?
Not sure myself.  Though imagine an exit path like (no cycles, all edges
flow down :-)

    A
   / \
  B   C
   \ /
    D
    |
   Exit

This is fairly common when setting the return value to different values.

There must be a label at B or C, and if we don't know the elimination
offset at B or C, then we'll think we can't perform the elimination even
if none of B, C or D reference the eliminable register.

Though maybe this isn't tickled by the EXIT_IGNORE_STACK stuff.  


jeff



More information about the Gcc-patches mailing list