This is the mail archive of the
mailing list for the GCC project.
Frame pointer optimization issues
- From: "Wilco Dijkstra" <wdijkstr at arm dot com>
- To: <gcc at gcc dot gnu dot org>
- Date: Wed, 20 Aug 2014 16:22:23 +0100
- Subject: Frame pointer optimization issues
- Authentication-results: sourceware.org; auth=none
Various targets implement -momit-leaf-frame-pointer to avoid using a frame pointer in leaf
functions. Currently the GCC mid-end does not provide a way of doing this, so targets have resorted
to hacks. Typically this involves forcing flag_omit_frame_pointer to be true in the
<arch>_option_override callback. The issue is that this doesn't work as it modifies the actual
option variable. As a result the callback is not idempotent, so option save/restore when using
function attributes fail as the callback is called multiple times on the modified options. Note this
bug exists on all targets which override options in <arch>_option_override (and despite claims to
the contrary in BZ 60580 this bug exists on all targets that implement -fomit-leaf-frame-pointer).
One could hack this a bit further and set flag_omit_frame_pointer = 2 to differentiate between a
user setting and the override hack, but that's just making things even worse. So I see 3 possible
1. Add a copy of flag_omit_frame_pointer, and only modify that in the override. This is the generic
correct solution that allows any kind of modifications on the copies. This could be done by making
all flags separate variables and automating the copy in the options parsing code. Any code that
writes the x_flag_ variables should eventually be fixed to stop doing this to avoid these bugs (i386
does this 22 times and c6x 2x).
2. Change the mid-end to call <arch>_frame_pointer_required even when !flag_omit_frame_pointer. This
is a generic solution which allows targets to decide when exactly to optimize frame pointers.
However it does mean all implementations of <arch>_frame_pointer_required must be updated (the
trivial safe fix is to add "if (!flag_omit_frame_pointer) return true;" at the start).
3. Add a new target callback to avoid having to update all targets. This replaces the existing
<arch>_frame_pointer_required if implemented and avoids having to update all targets in one go.
A second issue with frame pointers is that update_eliminables() in reload1.c might set
frame_pointer_needed to false without any checks. This can't be used to implement
-momit-leaf-frame-pointer as it doesn't always happen (ie. when <arch>_can_eliminate always returns
true). However assuming it does trigger in some circumstances, the bug is that it does not check
that the frame pointer really isn't required. Even if the frame pointer is completely unused and
thus eliminable from the function, the frame pointer setup might still be required by external
agents for debugging, unwinding and/or profiling. I believe a more elaborate check is needed, at a
minimum a call to <arch>_frame_pointer_required.
What do people think? My preference is for option 1 as it fixes all current and future issues with
option overrides, plus option 3 to make the frame pointer callback more generic.