> Richard Henderson wrote:
> On 08/20/2014 08:22 AM, Wilco Dijkstra wrote:
> > 2. Change the mid-end to call <arch>_frame_pointer_required even when
> > !flag_omit_frame_pointer.
> 
> Um, it does that already.  At least as far as I can see from
> ira_setup_eliminable_regset and update_eliminables.

No, in ira_setup_eliminable_regset the frame pointer is always forced if 
!flag_omit_frame_pointer without allowing frame_pointer_required to override it:

  frame_pointer_needed
    = (! flag_omit_frame_pointer
       ...
       || targetm.frame_pointer_required ());

This would allow targets to choose whether to do leaf tail pointer optimization:

  frame_pointer_needed
    = ((! flag_omit_frame_pointer && targetm.frame_pointer_required ())

> It turns out to be much easier to re-enable a frame pointer for a given
> function than to disable a frame pointer.  Thus I believe that you should
> approach -momit_leaf_frame_pointer as setting flag_omit_frame_pointer, and 
> then
> re-enabling it in frame_pointer_required.  This requires more than one line in
> common/config/arch/arch.c, but it shouldn't be much more than ten.

As I explained it is not correct to force flag_omit_frame_pointer to be true. 
This is what is done today and it fails in various cases. So unless the way 
options
are handled is changed, this possibility is out.

> > A second issue with frame pointers is that update_eliminables() in 
> > reload1.c might set
> > frame_pointer_needed to false without any checks.
> 
> How?  I don't see that path, since the very first thing update_eliminables 
> does
> is call frame_pointer_required -- even before it calls can_eliminate.

Update_eliminables() does indeed call frame_pointer_required at the start, 
however this 
only blocks elimination *from* HARD_FRAME_POINTER_REGNUM, while the code at the 
end clears 
frame_pointer_needed if FRAME_POINTER_REGNUM can be eliminated into any 
register other 
than HARD_FRAME_POINTER_REGNUM. The middle bit of the function is not relevant 
as 
HARD_FRAME_POINTER_REGNUM should only be eliminable into SP (but even if say it 
could be 
eliminable into another register X, it will only block eliminations of X to SP).
 
So frame_pointer_needed can be cleared even when frame_pointer_required is 
true...

In principle if this function worked reliably then we could implement leaf FPO 
using this 
mechanism. Unfortunately it doesn't, update_eliminables is not called in 
trivial leaf 
functions even when can_eliminate always returns true, so the frame pointer is 
never removed. 
Additionally I'd be worried about compilation performance as it would introduce 
extra
register allocation passes for ~50% of functions.

Wilco



Reply via email to