This is a new version which adds proper changelog entries and a test case (no actual code changes).
Bootstrapped an regression tested on x86_64. gcc/ * common.opt (flag_trampolines): Change default. * calls.c (prepare_call_address): Remove check for flag_trampolines. Decision is now made in FEs. * tree-nested.c (convert_tramp_reference_op): Likewise. gcc/ada/ * gcc-interface/trans.c (Attribute_to_gnu): Add check for flag_trampolines. gcc/c/ * c-objc-common.h: Define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS. * c-typeck.c (function_to_pointer_conversion): If using descriptors instead of trampolines, amend function address with FUNC_ADDR_BY_DESCRIPTOR and calls with ALL_EXPR_BY_DESCRIPTOR. gcc/testsuite/ * gcc.dg/trampoline-2.c: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec1fb242c23..e5f3844e8fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-08-20 Martin Uecker <martin.uec...@med.uni-goettingen.de> + + * common.opt (flag_trampolines): Change default. + * calls.c (prepare_call_address): Remove check for + flag_trampolines. Decision is now made in FEs. + * tree-nested.c (convert_tramp_reference_op): Likewise. + 2018-08-19 Uros Bizjak <ubiz...@gmail.com> PR target/86994 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 792811fb989..d906909774b 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2018-08-20 Martin Uecker <martin.uec...@med.uni-goettingen.de> + + * gcc-interface/trans.c (Attribute_to_gnu): Add check for + flag_trampolines. + 2018-08-03 Pierre-Marie de Rodat <dero...@adacore.com> Reverts diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc- interface/trans.c index 0371d00fce1..1b95f7070ac 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1769,7 +1769,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) if ((attribute == Attr_Access || attribute == Attr_Unrestricted_Access) && targetm.calls.custom_function_descriptors > 0 - && Can_Use_Internal_Rep (Etype (gnat_node))) + && Can_Use_Internal_Rep (Etype (gnat_node)) + && (flag_trampolines != 1)) FUNC_ADDR_BY_DESCRIPTOR (gnu_expr) = 1; /* Otherwise, we need to check that we are not violating the @@ -4341,7 +4342,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, /* If the access type doesn't require foreign-compatible representation, be prepared for descriptors. */ if (targetm.calls.custom_function_descriptors > 0 - && Can_Use_Internal_Rep (Etype (Prefix (Name (gnat_node))))) + && Can_Use_Internal_Rep (Etype (Prefix (Name (gnat_node)))) + && (flag_trampolines != 1)) by_descriptor = true; } else if (Nkind (Name (gnat_node)) == N_Attribute_Reference) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7bde11c1f19..028a7284e41 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2018-08-20 Martin Uecker <martin.uec...@med.uni-goettingen.de> + + * c-objc-common.h: Define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS. + * c-typeck.c (function_to_pointer_conversion): If using descriptors + instead of trampolines, amend function address with + FUNC_ADDR_BY_DESCRIPTOR and calls with ALL_EXPR_BY_DESCRIPTOR. + 2018-08-15 David Malcolm <dmalc...@redhat.com> * c-objc-common.c: Include "gcc-rich-location.h". diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 78e768c2366..ef039560eb9 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -110,4 +110,7 @@ along with GCC; see the file COPYING3. If not see #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p + +#undef LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS +#define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS true #endif /* GCC_C_OBJC_COMMON */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 726ea832ae1..a6a962d1e01 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -1912,7 +1912,13 @@ function_to_pointer_conversion (location_t loc, tree exp) if (TREE_NO_WARNING (orig_exp)) TREE_NO_WARNING (exp) = 1; - return build_unary_op (loc, ADDR_EXPR, exp, false); + tree r = build_unary_op (loc, ADDR_EXPR, exp, false); + + if ((TREE_CODE(r) == ADDR_EXPR) + && (flag_trampolines == 0)) + FUNC_ADDR_BY_DESCRIPTOR (r) = 1; + + return r; } /* Mark EXP as read, not just set, for set but not used -Wunused @@ -3135,6 +3141,11 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc, else result = build_call_array_loc (loc, TREE_TYPE (fntype), function, nargs, argarray); + + if ((TREE_CODE (result) == CALL_EXPR) + && (flag_trampolines == 0)) + CALL_EXPR_BY_DESCRIPTOR (result) = 1; + /* If -Wnonnull warning has been diagnosed, avoid diagnosing it again later. */ if (warned_p && TREE_CODE (result) == CALL_EXPR) diff --git a/gcc/calls.c b/gcc/calls.c index 384c0238748..1367e0305a3 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -230,7 +230,7 @@ prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value, { /* If it's an indirect call by descriptor, generate code to perform runtime identification of the pointer and load the descriptor. */ - if ((flags & ECF_BY_DESCRIPTOR) && !flag_trampolines) + if (flags & ECF_BY_DESCRIPTOR) { const int bit_val = targetm.calls.custom_function_descriptors; rtx call_lab = gen_label_rtx (); diff --git a/gcc/common.opt b/gcc/common.opt index ebc3ef43ce2..e56b134ba77 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2479,7 +2479,7 @@ Common Report Var(flag_tracer) Optimization Perform superblock formation via tail duplication. ftrampolines -Common Report Var(flag_trampolines) Init(0) +Common Report Var(flag_trampolines) Init(-1) For targets that normally need trampolines for nested functions, always generate them instead of using descriptors. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e89f4a4c093..8469a57eac3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-08-20 Martin Uecker <martin.uec...@med.uni-goettingen.de> + + * gcc.dg/trampoline-2.c: New test. + 2018-08-18 Iain Sandoe <i...@sandoe.co.uk> * gcc.dg/debug/dwarf2/pr80263.c: Suppress pubtypes output diff --git a/gcc/testsuite/gcc.dg/trampoline-2.c b/gcc/testsuite/gcc.dg/trampoline-2.c new file mode 100644 index 00000000000..7b3a2b64462 --- /dev/null +++ b/gcc/testsuite/gcc.dg/trampoline-2.c @@ -0,0 +1,23 @@ +/* test that nested function work without trampolines for -fno- trampolines */ +/* Origin: Martin Uecker <martin.uec...@med.uni-goettingen.de> */ +/* { dg-do run { target x86_64-*-* } } */ +/* { dg-options "-std=gnu11 -O2 -Wtrampolines -fno-trampolines" } */ + +static int p(void) { return +1; } +static int m(void) { return -1; } +static int z(void) { return 0; } + +typedef int (*funptr_t)(void); + +static int A(int k, funptr_t a1, funptr_t a2, funptr_t a3, funptr_t a4, funptr_t a5) +{ + int B(void) { return A(--k, B, a1, a2, a3, a4); } + + return (k <= 0) ? (a4() + a5()) : (B()); +} + +int main(void) +{ + return (0 == A(5, p, m, m, p, z)) ? 0 : 1; +} + diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 4c8eda94f14..4b49024b917 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -2497,7 +2497,7 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) continue; /* Decide whether to generate a descriptor or a trampoline. */ - descr = FUNC_ADDR_BY_DESCRIPTOR (t) && !flag_trampolines; + descr = FUNC_ADDR_BY_DESCRIPTOR (t); if (descr) x = lookup_descr_for_decl (i, decl, INSERT);