This is the mail archive of the
mailing list for the GCC project.
RE: Frame pointer optimization issues
- From: "Wilco Dijkstra" <wdijkstr at arm dot com>
- To: "'Richard Henderson'" <rth at redhat dot com>, <gcc at gcc dot gnu dot org>
- Date: Thu, 21 Aug 2014 15:07:57 +0100
- Subject: RE: Frame pointer optimization issues
- Authentication-results: sourceware.org; auth=none
- References: <000801cfbc8a$8ce28d40$a6a7a7c0$ at com> <53F52E3A dot 9060807 at redhat dot com>
> 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:
= (! flag_omit_frame_pointer
|| targetm.frame_pointer_required ());
This would allow targets to choose whether to do leaf tail pointer optimization:
= ((! 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.