[patch] Fix LRA/reload issue with -fnon-call-exceptions
Eric Botcazou
ebotcazou@adacore.com
Fri Feb 15 10:05:00 GMT 2019
Hi,
this is a regression present on all active branches since the controversial
get_initial_register_offset stuff was added to rtlanal.c some time ago, and
visible in the testsuite on PowerPC/Linux under the form of gnat.dg/opt73.adb
timing out at run time.
The problem is that the compiler generates code that doesn't save the frame
pointer before clobbering it, because rs6000_stack_info computes a wrong final
(post-reload) stack layout. The scenario is as follows: LRA decides to use
the frame pointer, sets reload_completed to 1 at the end and then does:
/* We've possibly turned single trapping insn into multiple ones. */
if (cfun->can_throw_non_call_exceptions)
{
auto_sbitmap blocks (last_basic_block_for_fn (cfun));
bitmap_ones (blocks);
find_many_sub_basic_blocks (blocks);
}
But find_many_sub_basic_blocks calls control_flow_insn_p, which in turn can
call rtx_addr_can_trap_p_1, which can call get_initial_register_offset, which
uses INITIAL_ELIMINATION_OFFSET, IOW rs6000_initial_elimination_offset, which
calls rs6000_stack_info. But at this point the DF information hasn't been
updated so the frame pointer isn't detected as live by df_regs_ever_live_p.
You may think that the fix is just to set reload_completed to 1 after the
above code in lra, but that's not sufficient because the same issue can arise
from the do_reload function:
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE);
when checking is enabled, because cleanup_cfg can calls control_flow_insn_p
and then eventually rtx_addr_can_trap_p_1. In other words, we would need
to set reload_completed to 1 only after the above code, which is very late.
As a matter of fact, that's not possible for old reload itself because of:
/* We must set reload_completed now since the cleanup_subreg_operands call
below will re-recognize each insn and reload may have generated insns
which are only valid during and after reload. */
reload_completed = 1;
So, barring the removal of the get_initial_register_offset stuff, the only
simple fix is probably to prevent it from calling into the back-end too early,
for example with the attached fixlet. Tested on x86-64 and PowerPC/Linux.
Thoughts? Where do we want to fix this?
* rtlanal.c (get_initial_register_offset): Fall back to the raw estimate
as long as the epilogue isn't completed.
--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p.diff
Type: text/x-patch
Size: 757 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20190215/191cc99c/attachment.bin>
More information about the Gcc-patches
mailing list