This is the mail archive of the gcc@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]

Non-call exceptions and libcalls


All libcalls are marked as "cannot throw", but in the case of
-fnon-call-exceptions this isn't true: if a divide insn can throw an
exception, so can a call to __divdi3.

In gcj 3.0 we get around this problem by calling a divide subroutine
in libgcj for every division, but this is a temporary fix that we'd
like to get rid of.  It is very inefficient, obviously.

This patch removes "can't throw" notes in libcall blocks where
appropriate.  

In addition, some of the functions in libgcc2 must be compiled with
-fnon-call-exceptions so that we can unwind through them.

What do people think?

Andrew.


2001-06-14  Andrew Haley  <aph@cambridge.redhat.com>

	* optabs.c (emit_libcall_block): When using non-call exceptions,
	don't mark libcalls never throwing.  */

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.87.4.4
diff -c -2 -p -r1.87.4.4 optabs.c
*** optabs.c	2001/05/13 07:09:55	1.87.4.4
--- optabs.c	2001/06/14 18:11:34
*************** emit_libcall_block (insns, target, resul
*** 2809,2829 ****
    if (! REG_P (target) || REG_USERVAR_P (target))
      target = gen_reg_rtx (GET_MODE (target));
! 
    /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
       reg note to indicate that this call cannot throw or execute a nonlocal
       goto (unless there is already a REG_EH_REGION note, in which case
       we update it).  */
! 
!   for (insn = insns; insn; insn = NEXT_INSN (insn))
!     if (GET_CODE (insn) == CALL_INSN)
!       {
! 	rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 
! 	if (note != 0)
! 	  XEXP (note, 0) = GEN_INT (-1);
! 	else
! 	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
! 						REG_NOTES (insn));
!       }
  
    /* First emit all insns that set pseudos.  Remove them from the list as
--- 2809,2842 ----
    if (! REG_P (target) || REG_USERVAR_P (target))
      target = gen_reg_rtx (GET_MODE (target));
!   
!   /* If we're using non-call exceptions, a libcall corresponding to an
!      operation that may trap may also trap.  */
!   if (flag_non_call_exceptions && may_trap_p (equiv))
!     {
!       for (insn = insns; insn; insn = NEXT_INSN (insn))
! 	if (GET_CODE (insn) == CALL_INSN)
! 	  {
! 	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 	    
! 	    if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
! 	      remove_note (insn, note);
! 	  }
!     }
!   else
    /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
       reg note to indicate that this call cannot throw or execute a nonlocal
       goto (unless there is already a REG_EH_REGION note, in which case
       we update it).  */
!     for (insn = insns; insn; insn = NEXT_INSN (insn))
!       if (GET_CODE (insn) == CALL_INSN)
! 	{
! 	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 	
! 	  if (note != 0)
! 	    XEXP (note, 0) = GEN_INT (-1);
! 	  else
! 	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
! 						  REG_NOTES (insn));
! 	}
  
    /* First emit all insns that set pseudos.  Remove them from the list as


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