public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* How can INITIAL_FRAME_POINTER_OFFSET be made correct?
@ 2004-03-19 16:46 Dave Korn
  2004-03-19 16:59 ` Joern Rennecke
  2004-03-19 21:02 ` Richard Henderson
  0 siblings, 2 replies; 11+ messages in thread
From: Dave Korn @ 2004-03-19 16:46 UTC (permalink / raw)
  To: gcc


  Erm.  Bit confused here.  

  INITIAL_FRAME_POINTER_OFFSET is supposed to be "the difference between the
frame pointer and the stack pointer values immediately after the function
prologue", according to gccint.  It goes on to suggest

"  The value would be computed from information such as the result of
`get_frame_size ()' and the tables of registers `regs_ever_live' and
`call_used_regs'.  "

  INITIAL_FRAME_POINTER_OFFSET is called before the md emit prologue
function has has a chance to run.  So it has to duplicate the exact
calculations that the prologue function does when it's deciding on the stack
frame layout for the current function.

  In the particular port I'm working with, we decide whether or not to
allocate a stack slot for saving the link register according to whether or
not we ever use it - i.e. we use code that looks like:

    info->lr_save_size = !current_function_is_leaf ||
regs_ever_live[LINK_REGNUM] ? 4 : 0;

[info is just a struct where I'm keeping the sizes and offsets of the
various areas of the stack frame].

  There's a bit of a problem, however.  regs_ever_live[LINK_REGNUM] is zero
when INITIAL_FRAME_POINTER_OFFSET is called, but something has set it to one
by the time we get to the emit prologue function.  The result is that the
two of them disagree about the size and layout of my stackframes, and I get
a lot of FAILs in the varargs tests.

  Is it valid that regs_ever_live[] changes between IFPO and emit_prologue?
If so, the documentation should warn *against* using it in IFPO.  If not,
I've got to get finding out why it changes when it shouldn't.......


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 16:46 How can INITIAL_FRAME_POINTER_OFFSET be made correct? Dave Korn
@ 2004-03-19 16:59 ` Joern Rennecke
  2004-03-19 17:55   ` Dave Korn
  2004-03-19 21:02 ` Richard Henderson
  1 sibling, 1 reply; 11+ messages in thread
From: Joern Rennecke @ 2004-03-19 16:59 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

>   There's a bit of a problem, however.  regs_ever_live[LINK_REGNUM] is zero
> when INITIAL_FRAME_POINTER_OFFSET is called, but something has set it to one
> by the time we get to the emit prologue function.  The result is that the
> two of them disagree about the size and layout of my stackframes, and I get
> a lot of FAILs in the varargs tests.

Is LINK_RENUM eliminable, or can something else be eliminated to it?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 16:59 ` Joern Rennecke
@ 2004-03-19 17:55   ` Dave Korn
  2004-03-19 18:31     ` Joern Rennecke
  2004-03-21 18:08     ` Hans-Peter Nilsson
  0 siblings, 2 replies; 11+ messages in thread
From: Dave Korn @ 2004-03-19 17:55 UTC (permalink / raw)
  To: 'Joern Rennecke'; +Cc: gcc

 

> -----Original Message-----
> From: Joern Rennecke 
> Sent: 19 March 2004 15:59
> To: Dave Korn

> >   There's a bit of a problem, however.  
> regs_ever_live[LINK_REGNUM] is 
> > zero when INITIAL_FRAME_POINTER_OFFSET is called, but something has 
> > set it to one by the time we get to the emit prologue 
> function.  The 
> > result is that the two of them disagree about the size and 
> layout of 
> > my stackframes, and I get a lot of FAILs in the varargs tests.
> 
> Is LINK_RENUM eliminable, or can something else be eliminated to it?

There is no ELIMINABLE_REGS definition, but FRAME_POINTER_REQUIRED is zero
so gcc can do its default eliminate-lr-vs-sp.



    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 17:55   ` Dave Korn
@ 2004-03-19 18:31     ` Joern Rennecke
  2004-03-19 18:41       ` Dave Korn
  2004-03-21 18:08     ` Hans-Peter Nilsson
  1 sibling, 1 reply; 11+ messages in thread
From: Joern Rennecke @ 2004-03-19 18:31 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Joern Rennecke', gcc

> There is no ELIMINABLE_REGS definition, but FRAME_POINTER_REQUIRED is zero
> so gcc can do its default eliminate-lr-vs-sp.

Are you saying here that LINK_REGNUM is the same as FRAME_POINTER_REGNUM?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 18:31     ` Joern Rennecke
@ 2004-03-19 18:41       ` Dave Korn
  2004-03-19 18:57         ` Joern Rennecke
  0 siblings, 1 reply; 11+ messages in thread
From: Dave Korn @ 2004-03-19 18:41 UTC (permalink / raw)
  To: 'Joern Rennecke'; +Cc: gcc

 

> -----Original Message-----
> From: Joern Rennecke
> Sent: 19 March 2004 17:02
> To: Dave Korn
> 
> > There is no ELIMINABLE_REGS definition, but 
> FRAME_POINTER_REQUIRED is 
> > zero so gcc can do its default eliminate-lr-vs-sp.
> 
> Are you saying here that LINK_REGNUM is the same as 
> FRAME_POINTER_REGNUM?

  Sorry, no, I made a thinko.  I meant eliminate-fp-vs-sp.


    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 18:41       ` Dave Korn
@ 2004-03-19 18:57         ` Joern Rennecke
  2004-03-19 19:49           ` Dave Korn
  0 siblings, 1 reply; 11+ messages in thread
From: Joern Rennecke @ 2004-03-19 18:57 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Joern Rennecke', gcc

If you mention LINK_REGS in EPILOGUE_USES, you'll have to assume that
it is always 'used', and use REG_N_SETS to check if it's clobbered.

Otherwise, I'd suggest setting a watchpoint to find out where exactly
regs_ever_live[LINK_REGS] is set.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 18:57         ` Joern Rennecke
@ 2004-03-19 19:49           ` Dave Korn
  0 siblings, 0 replies; 11+ messages in thread
From: Dave Korn @ 2004-03-19 19:49 UTC (permalink / raw)
  To: 'Joern Rennecke'; +Cc: gcc


> -----Original Message-----
> From: Joern Rennecke
> Sent: 19 March 2004 17:24

> If you mention LINK_REGS in EPILOGUE_USES, you'll have to 
> assume that it is always 'used', and use REG_N_SETS to check 
> if it's clobbered.

  Hmmm, actually there's no definition for EPILOGUE_USES at all, despite the
fact that it does actually use LINK_REGNUM.  Dunno if that's really  a
problem or not.  It *is* marked as a CALL_USED register.

> Otherwise, I'd suggest setting a watchpoint to find out where 
> exactly regs_ever_live[LINK_REGS] is set.

  Yeh, I guess that'll give me the definitive answer.  I was kinda hoping
that someone would be able to give me a definite answer about the scope of
validity of regs_ever_live, such as "It's only guaranteed to be completely
up-to-date by the time emit_prologue is called".

  ISTM that it would be very bad of the docs to suggest using regs_ever_live
at a time when the information in it was incorrect or incomplete, but maybe
it's not meant to change after IFPO and it's just a bug that is causing the
inconsistency.




    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 16:46 How can INITIAL_FRAME_POINTER_OFFSET be made correct? Dave Korn
  2004-03-19 16:59 ` Joern Rennecke
@ 2004-03-19 21:02 ` Richard Henderson
  2004-03-22 17:31   ` Dave Korn
  1 sibling, 1 reply; 11+ messages in thread
From: Richard Henderson @ 2004-03-19 21:02 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

On Fri, Mar 19, 2004 at 03:30:03PM -0000, Dave Korn wrote:
>   INITIAL_FRAME_POINTER_OFFSET is called before the md emit prologue
> function has has a chance to run.  So it has to duplicate the exact
> calculations that the prologue function does when it's deciding on the stack
> frame layout for the current function.

Yes.  This is true for everyone.  Preferred technique is to use a
common function to be used here and in the prologue/epilogue code.

>   Is it valid that regs_ever_live[] changes between IFPO and emit_prologue?

No.  Whenever reload adds a new spill register, it's supposed to go
back through the allocation loop, which will recompute that offset.

I don't suppose your link register is marked CALL_USED?  That's
probably a mistake...


r~

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 17:55   ` Dave Korn
  2004-03-19 18:31     ` Joern Rennecke
@ 2004-03-21 18:08     ` Hans-Peter Nilsson
  1 sibling, 0 replies; 11+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-21 18:08 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

On Fri, 19 Mar 2004, Dave Korn wrote:
> There is no ELIMINABLE_REGS definition, but FRAME_POINTER_REQUIRED is zero
> so gcc can do its default eliminate-lr-vs-sp.

You really want to define ELIMINABLE_REGS when the frame-pointer
can be eliminated and you don't have a separate argument
pointer.  (Make a fake argument pointer which is always
eliminated.)

I'm deliberately hazy on the details, because I don't quite
remember, but playing catch-up with the saved frame-pointer
regarding the offset to the arguments was IIRC key.

The docs may need an update.

brgds, H-P

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-19 21:02 ` Richard Henderson
@ 2004-03-22 17:31   ` Dave Korn
  2004-03-22 23:09     ` Richard Henderson
  0 siblings, 1 reply; 11+ messages in thread
From: Dave Korn @ 2004-03-22 17:31 UTC (permalink / raw)
  To: 'Richard Henderson'; +Cc: gcc

 
> -----Original Message-----
> From: Richard Henderson 
> Sent: 19 March 2004 19:49

>On Fri, Mar 19, 2004 at 03:30:03PM -0000, Dave Korn wrote:
>> INITIAL_FRAME_POINTER_OFFSET is called before the md emit prologue 
>> function has has a chance to run.  So it has to duplicate the exact 
>> calculations that the prologue function does when it's deciding on 
>> the stack frame layout for the current function.
> 
> Yes.  This is true for everyone.  Preferred technique is to 
> use a common function to be used here and in the 
> prologue/epilogue code.

  Yep, that's exactly how I do it: I defined a nice struct to wrap it all up
in

struct dlx_frame_info {
    int     lr_save_size;
    int     lr_save_pointer;
    int     fp_save_size;
    int     fp_save_pointer;
    int     gpr_save_size;
    int     gpr_save_pointer;
    int     aligned_outarg_size;
    int     aligned_vars_size;
    int     stack_size;
};

and a generic routine to perform the calculations:

void
dlx_init_frame_info (info, vars)
    struct dlx_frame_info *info;
    int vars;
{
    /* Start by initing all sizes to zero. */
    memset (info, 0, sizeof *info);
    /* Calculate space needed for various areas.  These magic 4s are bad
really. */
    info->lr_save_size = !current_function_is_leaf ||
regs_ever_live[LINK_REGNUM] ? 4 : 0;
    /* fp_save_size MUST be setup correctly before we iterate across gprs */
    info->fp_save_size = frame_pointer_needed ? 4 : 0;
    info->gpr_save_size = dlx_gpr_save_area_iterate (info, NULL, NULL) * 4;
    info->aligned_outarg_size =
DLX_ALIGN(current_function_outgoing_args_size,4);
    info->aligned_vars_size = DLX_ALIGN(vars,4);
    info->stack_size = info->aligned_outarg_size + info->lr_save_size +
info->fp_save_size + info->gpr_save_size + info->aligned_vars_size;
    info->lr_save_pointer = info->aligned_outarg_size;
    info->fp_save_pointer = info->lr_save_pointer + info->lr_save_size;
    info->gpr_save_pointer = info->aligned_outarg_size + info->lr_save_size
+ info->fp_save_size;
}

which I then call like this:

static void
dlx_output_function_prologue(file, vars)
    FILE *file;
    int vars;
{
struct dlx_frame_info info;
int regno;

    /* Allocate space in the stack frame and lay it out. */
    dlx_init_frame_info (&info, vars);

        ....more....

and like this:

static void
dlx_output_function_epilogue(file, vars)
    FILE *file;
    int vars;
{
struct dlx_frame_info info;

    /* Allocate space in the stack frame and lay it out. */
    dlx_init_frame_info (&info, vars);

        ....more....

and like this:

#define INITIAL_FRAME_POINTER_OFFSET(DEPTH)            \
    {                                                   \
    struct dlx_frame_info info;                         \
        dlx_init_frame_info (&info, get_frame_size ()); \
        (DEPTH) = info.stack_size;                     \
    }

  When I started to suspect that I might be getting inconsistent results, I
added a machine_function structure as well to cache the resulting frame info
struct in and actually verify with a memcmp that subsequent calls were
generating the same data in that struct; that's what gave me the clue that
something was changing in the input data the function was relying on.

> >   Is it valid that regs_ever_live[] changes between IFPO 
> and emit_prologue?
> 
> No.  Whenever reload adds a new spill register, it's supposed 
> to go back through the allocation loop, which will recompute 
> that offset.

  Gotcha.  I added trace code which shows me that IFPO is the first one of
those points to get called, followed by emit_prologue and then
emit_epilogue.  I noticed also that IFPO gets called several times per
function (and the others just once each): I suppose that's each time the
allocation loop needs to recompute the offset, and it's not important that
all those calls agree with each other, just so long as the very last call
produces the same state as is used in the prologue and epilogue.

> I don't suppose your link register is marked CALL_USED?  

  Bingo!

> That's probably a mistake...
> 
> 
> r~


  Turns out it certainly is, or at any rate it fixes my va-arg-11.c failure
and several others too.  I'm not sure why it's a mistake, though: function
calls are performed by a jump-and-link instruction that clobbers the LR; in
the definition of CALL_USED_REGISTERS in the documentation, it seems to
suggest that means I should include it.  Is it wrong because that counts as
being clobbered by the caller, rather than by the callee, perhaps?

  Aha: I've just noticed that the call* patterns in the .md file explicitly
include the link register as a clobber in the parallel.  So yes, it does
count as being clobbered by the call insn, rather than CALL_USED.  I'm
unsure why declaring it call used in addition doesn't just result in
needless loads and saves but actual inconsistent state, but there you go: it
seems to be playing nicely now.  Thanks for catching that one.




    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: How can INITIAL_FRAME_POINTER_OFFSET be made correct?
  2004-03-22 17:31   ` Dave Korn
@ 2004-03-22 23:09     ` Richard Henderson
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2004-03-22 23:09 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

On Mon, Mar 22, 2004 at 03:04:20PM -0000, Dave Korn wrote:
> > I don't suppose your link register is marked CALL_USED?  
> 
>   Turns out it certainly is, or at any rate it fixes my va-arg-11.c failure
> and several others too.  I'm not sure why it's a mistake, though: function
> calls are performed by a jump-and-link instruction that clobbers the LR; in
> the definition of CALL_USED_REGISTERS in the documentation, it seems to
> suggest that means I should include it.  Is it wrong because that counts as
> being clobbered by the caller, rather than by the callee, perhaps?

It's wrong because any function that clobbers the link register is
very likely to need to save the link register so that it can be 
restored for the return.

Not looking at sources, but I can well imagine that reload has an
optimization that says that it needn't go back through the allocation
loop if the new register it chose to use is call clobbered.


r~

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2004-03-22 18:21 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-19 16:46 How can INITIAL_FRAME_POINTER_OFFSET be made correct? Dave Korn
2004-03-19 16:59 ` Joern Rennecke
2004-03-19 17:55   ` Dave Korn
2004-03-19 18:31     ` Joern Rennecke
2004-03-19 18:41       ` Dave Korn
2004-03-19 18:57         ` Joern Rennecke
2004-03-19 19:49           ` Dave Korn
2004-03-21 18:08     ` Hans-Peter Nilsson
2004-03-19 21:02 ` Richard Henderson
2004-03-22 17:31   ` Dave Korn
2004-03-22 23:09     ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).