> 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