[backport gcc-4.9/trunk r198681 ] List-Archive: Date: Tue, 7 May 2013 14:58:59 +0200 (CEST) From: Richard Biener 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. gcc/ 2013-05-07 Richard Biener * 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. --- gcc-4.8.0/gcc/builtins.def.~1~ 2013-05-09 17:15:05.048030057 +0200 +++ gcc-4.8.0/gcc/builtins.def 2013-05-09 17:15:46.987892912 +0200 @@ -732,7 +732,7 @@ DEF_LIB_BUILTIN (BUILT_IN_REALLOC 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_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) --- gcc-4.8.0/gcc/calls.c.~1~ 2013-01-12 00:39:18.000000000 +0100 +++ gcc-4.8.0/gcc/calls.c 2013-05-09 17:15:46.987892912 +0200 @@ -545,7 +545,7 @@ special_function_p (const_tree fndecl, i && ! strcmp (tname, "sigsetjmp")) || (tname[1] == 'a' && ! strcmp (tname, "savectx"))) - flags |= ECF_RETURNS_TWICE; + flags |= ECF_RETURNS_TWICE | ECF_LEAF; if (tname[1] == 'i' && ! strcmp (tname, "siglongjmp")) @@ -557,7 +557,7 @@ special_function_p (const_tree fndecl, i && ! strcmp (tname, "vfork")) || (tname[0] == 'g' && tname[1] == 'e' && !strcmp (tname, "getcontext"))) - flags |= ECF_RETURNS_TWICE; + flags |= ECF_RETURNS_TWICE | ECF_LEAF; else if (tname[0] == 'l' && tname[1] == 'o' && ! strcmp (tname, "longjmp")) --- gcc-4.8.0/gcc/tree-inline.c.~1~ 2013-05-09 17:15:34.337934270 +0200 +++ gcc-4.8.0/gcc/tree-inline.c 2013-05-09 17:15:46.987892912 +0200 @@ -1837,8 +1837,8 @@ update_ssa_across_abnormal_edges (basic_ phi = gsi_stmt (si); - /* There shouldn't be any PHI nodes in the ENTRY_BLOCK. */ - gcc_assert (!e->dest->aux); + /* 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)));