This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PLEASE APPROVE: patch to fix PR 5879, a serious gcc 3.1regression
OK. The problem seems to be a clash between the sibcall code and the EH
code. With the patch, looking at the 00.rtl dump, the end of
initializeClass looks like
-----
(call_insn 835 825 836 (call_placeholder 833 826 0 429 (call_insn 834 833 0 (parallel[
(call (mem:SI (symbol_ref:SI ("_Jv_MonitorExit")) [0 S4
A32])
(const_int 0 [0x0]))
(use (const_int 0 [0x0]))
(clobber (reg:SI 14 lr))
] ) -1 (nil)
(nil)
(expr_list (use (reg:SI 0 r0))
(nil)))) -1 (nil)
(nil)
(nil))
(note 836 835 837 0x408202c0 NOTE_INSN_BLOCK_END)
(jump_insn 837 836 838 (set (pc)
(label_ref 841)) -1 (nil)
(nil))
(barrier 838 837 839)
(jump_insn 839 838 840 (set (pc)
(label_ref 844)) -1 (nil)
(nil))
(barrier 840 839 841)
(code_label 841 840 842 414 "" "" [0 uses])
(note 842 841 844 NOTE_INSN_FUNCTION_END)
(code_label 844 842 0 387 "" "" [0 uses])
-----
without the patch, it looks like
-----
(call_insn 835 825 836 (call_placeholder 833 826 0 429 (call_insn 834 833 0 (parallel[
(call (mem:SI (symbol_ref:SI ("_Jv_MonitorExit")) [0 S4 A32])
(const_int 0 [0x0]))
(use (const_int 0 [0x0]))
(clobber (reg:SI 14 lr))
] ) -1 (nil)
(nil)
(expr_list (use (reg:SI 0 r0))
(nil)))) -1 (nil)
(nil)
(nil))
(note 836 835 837 0x40806ec0 NOTE_INSN_BLOCK_END)
(note 837 836 839 NOTE_INSN_FUNCTION_END)
(code_label 839 837 0 360 "" "" [0 uses])
-----
note that these two are equivalent; the first just has an extra jump; in
both cases we fall through to the end of the function. However, that extra
jump seems to be enough to prevent the sibcall code from turning the call
to _Jv_MonitorExit into a sibcall; without the jump, it does. After the
sibcall pass, the EH pass adds the call to _Unwind_SjLj_Unregister; but by
this time it's too late, as we never return from _Jv_MonitorExit.
Seems to me that the solution is to perform EH processing before the
sibcall pass; this also allows us to sibcallize the call to
_Unwind_SjLj_Unregister. Richard, what do you think?
Adam, Anthony, does this fix things for you?
2002-03-19 Jason Merrill <jason@redhat.com>
* toplev.c (rest_of_compilation): Do EH processing before
sibcalls.
*** toplev.c.~1~ Tue Mar 19 01:04:54 2002
--- toplev.c Tue Mar 19 13:35:32 2002
*************** rest_of_compilation (decl)
*** 2554,2582 ****
|| errorcount || sorrycount)
goto exit_rest_of_compilation;
! /* We may have potential sibling or tail recursion sites. Select one
! (of possibly multiple) methods of performing the call. */
! if (flag_optimize_sibling_calls)
{
timevar_push (TV_JUMP);
! open_dump_file (DFI_sibling, decl);
! optimize_sibling_and_tail_recursive_calls ();
! close_dump_file (DFI_sibling, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
}
! /* Complete generation of exception handling code. */
! find_exception_handler_labels ();
! if (doing_eh (0))
{
timevar_push (TV_JUMP);
! open_dump_file (DFI_eh, decl);
! finish_eh_generation ();
! close_dump_file (DFI_eh, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
}
--- 2554,2584 ----
|| errorcount || sorrycount)
goto exit_rest_of_compilation;
! /* Complete generation of exception handling code. For sjlj exceptions,
! this needs to happen before the sibcall pass, as it may add code to
! the end of the function. */
! find_exception_handler_labels ();
! if (doing_eh (0))
{
timevar_push (TV_JUMP);
! open_dump_file (DFI_eh, decl);
! finish_eh_generation ();
! close_dump_file (DFI_eh, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
}
! /* We may have potential sibling or tail recursion sites. Select one
! (of possibly multiple) methods of performing the call. */
! if (flag_optimize_sibling_calls)
{
timevar_push (TV_JUMP);
! open_dump_file (DFI_sibling, decl);
! optimize_sibling_and_tail_recursive_calls ();
! close_dump_file (DFI_sibling, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
}