[PATCH] Fix must-not-throw regions with SJLJ exception handling

Ulrich Weigand uweigand@de.ibm.com
Fri Jan 21 17:25:00 GMT 2011


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



More information about the Gcc-patches mailing list