This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
      }
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]