This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix must-not-throw regions with SJLJ exception handling
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: rth at redhat dot com (Richard Henderson)
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 21 Jan 2011 18:16:45 +0100 (CET)
- Subject: Re: [PATCH] Fix must-not-throw regions with SJLJ exception handling
Richard Henderson wrote:
> I think the patch is nearly ok, except for this last part. I think that
> sjlj_have_must_not_throw is redundant with function_needs_eh_personality.
> You don't need to scan all the insns; merely the exception tree.
Ah, I see. Updated patch to use function_needs_eh_personality below.
This version also fixed the four test case failures on SPU; full
test suite run is still in progress ...
Thanks,
Ulrich
ChangeLog:
* except.c (sjlj_assign_call_site_values): Move setting the
crtl->uses_eh_lsda flag to ...
(sjlj_mark_call_sites): ... here.
(sjlj_emit_function_enter): Support NULL dispatch label.
(sjlj_build_landing_pads): In a function with no landing pads
that still has must-not-throw regions, generate code to register
a personality function with empty LSDA.
Index: gcc/except.c
===================================================================
*** gcc/except.c (revision 168909)
--- gcc/except.c (working copy)
*************** sjlj_assign_call_site_values (void)
*** 998,1005 ****
/* First: build the action table. */
action = collect_one_action_chain (ar_hash, lp->region);
- if (action != -1)
- crtl->uses_eh_lsda = 1;
/* Next: assign call-site values. If dwarf2 terms, this would be
the region number assigned by convert_to_eh_region_ranges, but
--- 998,1003 ----
*************** sjlj_mark_call_sites (void)
*** 1065,1070 ****
--- 1063,1071 ----
this_call_site = 0;
}
+ if (this_call_site != -1)
+ crtl->uses_eh_lsda = 1;
+
if (this_call_site == last_call_site)
continue;
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 1119,1145 ****
else
emit_move_insn (mem, const0_rtx);
#ifdef DONT_USE_BUILTIN_SETJMP
! {
! rtx x, last;
! x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
! TYPE_MODE (integer_type_node), 1,
! plus_constant (XEXP (fc, 0),
! sjlj_fc_jbuf_ofs), Pmode);
!
! emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
! TYPE_MODE (integer_type_node), 0, dispatch_label);
! last = get_last_insn ();
! if (JUMP_P (last) && any_condjump_p (last))
! {
! gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
! add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
! }
! }
! #else
! expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
dispatch_label);
#endif
emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1, XEXP (fc, 0), Pmode);
--- 1120,1149 ----
else
emit_move_insn (mem, const0_rtx);
+ if (dispatch_label)
+ {
#ifdef DONT_USE_BUILTIN_SETJMP
! rtx x, last;
! x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
! TYPE_MODE (integer_type_node), 1,
! plus_constant (XEXP (fc, 0),
! sjlj_fc_jbuf_ofs), Pmode);
!
! emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
! TYPE_MODE (integer_type_node), 0,
dispatch_label);
+ last = get_last_insn ();
+ if (JUMP_P (last) && any_condjump_p (last))
+ {
+ gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
+ add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
+ }
+ #else
+ expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0),
+ sjlj_fc_jbuf_ofs),
+ dispatch_label);
#endif
+ }
emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1, XEXP (fc, 0), Pmode);
*************** sjlj_build_landing_pads (void)
*** 1363,1368 ****
--- 1367,1389 ----
sjlj_emit_function_exit ();
}
+ /* If we do not have any landing pads, we may still need to register a
+ personality routine and (empty) LSDA to handle must-not-throw regions. */
+ else if (function_needs_eh_personality (cfun))
+ {
+ int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
+ TYPE_MODE (sjlj_fc_type_node),
+ TYPE_ALIGN (sjlj_fc_type_node));
+ crtl->eh.sjlj_fc
+ = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
+ int_size_in_bytes (sjlj_fc_type_node),
+ align);
+
+ crtl->uses_eh_lsda = 1;
+ sjlj_emit_function_enter (NULL_RTX);
+ sjlj_emit_function_exit ();
+ }
+
VEC_free (int, heap, sjlj_lp_call_site_index);
}
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com