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]

[PATCH] Make setjmp and friends LEAF


The following patch finally makes setjmp LEAF after I figured
what breaks the original testcase.  The inliner has an overzealous
assert that there cannot be new abnormal edges into the entry
block (the block preceeding the call we inline).  But that can
perfectly well happen with

bb1:
  setjmp ();

bb2:
  foo ();

when foo can transfer control flow to bb1.  And the code can
perfectly well handle the situation.

The patch avoids the odd abnormal edge we have now from each
setjmp call to itself.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

2013-05-07  Richard Biener  <rguenther@suse.de>

	* calls.c (special_function_p): setjmp-like functions are leaf.
	* builtins.def (BUILT_IN_SETJMP): setjmp is leaf.
	* tree-inline.c (update_ssa_across_abnormal_edges): Remove assert.

Index: gcc/calls.c
===================================================================
*** gcc/calls.c.orig	2013-05-03 11:29:16.000000000 +0200
--- gcc/calls.c	2013-05-07 11:36:30.886404048 +0200
*************** special_function_p (const_tree fndecl, i
*** 545,551 ****
  		  && ! strcmp (tname, "sigsetjmp"))
  	      || (tname[1] == 'a'
  		  && ! strcmp (tname, "savectx")))
! 	    flags |= ECF_RETURNS_TWICE;
  
  	  if (tname[1] == 'i'
  	      && ! strcmp (tname, "siglongjmp"))
--- 545,551 ----
  		  && ! strcmp (tname, "sigsetjmp"))
  	      || (tname[1] == 'a'
  		  && ! strcmp (tname, "savectx")))
! 	    flags |= ECF_RETURNS_TWICE | ECF_LEAF;
  
  	  if (tname[1] == 'i'
  	      && ! strcmp (tname, "siglongjmp"))
*************** special_function_p (const_tree fndecl, i
*** 557,563 ****
  		   && ! strcmp (tname, "vfork"))
  	       || (tname[0] == 'g' && tname[1] == 'e'
  		   && !strcmp (tname, "getcontext")))
! 	flags |= ECF_RETURNS_TWICE;
  
        else if (tname[0] == 'l' && tname[1] == 'o'
  	       && ! strcmp (tname, "longjmp"))
--- 557,563 ----
  		   && ! strcmp (tname, "vfork"))
  	       || (tname[0] == 'g' && tname[1] == 'e'
  		   && !strcmp (tname, "getcontext")))
! 	flags |= ECF_RETURNS_TWICE | ECF_LEAF;
  
        else if (tname[0] == 'l' && tname[1] == 'o'
  	       && ! strcmp (tname, "longjmp"))
Index: gcc/builtins.def
===================================================================
*** gcc/builtins.def.orig	2013-05-03 11:29:16.000000000 +0200
--- gcc/builtins.def	2013-05-07 11:36:30.887404061 +0200
*************** DEF_LIB_BUILTIN        (BUILT_IN_REALLOC
*** 732,738 ****
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
! DEF_GCC_BUILTIN        (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
  DEF_LIB_BUILTIN        (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
  DEF_GCC_BUILTIN        (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
--- 732,738 ----
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
! DEF_GCC_BUILTIN        (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NOTHROW_LEAF_LIST)
  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
  DEF_LIB_BUILTIN        (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
  DEF_GCC_BUILTIN        (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2013-05-07 12:35:12.000000000 +0200
--- gcc/tree-inline.c	2013-05-07 12:35:19.286140199 +0200
*************** update_ssa_across_abnormal_edges (basic_
*** 1839,1846 ****
  
  	    phi = gsi_stmt (si);
  
! 	    /* There shouldn't be any PHI nodes in the ENTRY_BLOCK.  */
! 	    gcc_assert (!e->dest->aux);
  
  	    gcc_assert ((e->flags & EDGE_EH)
  			|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)));
--- 1839,1846 ----
  
  	    phi = gsi_stmt (si);
  
! 	    /* For abnormal goto/call edges the receiver can be the
! 	       ENTRY_BLOCK.  Do not assert this cannot happen.  */
  
  	    gcc_assert ((e->flags & EDGE_EH)
  			|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)));


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