> 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