This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Make setjmp and friends LEAF
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 7 May 2013 14:58:59 +0200 (CEST)
- Subject: [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)));