Hi,

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
solutions:

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.

Wilco



Reply via email to