This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Non-call exceptions and libcalls
- To: gcc at gcc dot gnu dot org
- Subject: Non-call exceptions and libcalls
- From: Andrew Haley <aph at cambridge dot redhat dot com>
- Date: Tue, 19 Jun 2001 17:13:18 +0100 (BST)
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