public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Iain Buclaw <ibuclaw@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6645] d: Refactor DECL_ARGUMENT and DECL_RESULT generation to own function Date: Mon, 13 Mar 2023 21:16:57 +0000 (GMT) [thread overview] Message-ID: <20230313211657.8041D3858D1E@sourceware.org> (raw) https://gcc.gnu.org/g:499b07700f0e679a490c2e3b80ca7c382dd737ab commit r13-6645-g499b07700f0e679a490c2e3b80ca7c382dd737ab Author: Iain Buclaw <ibuclaw@gdcproject.org> Date: Sun Mar 12 21:43:31 2023 +0100 d: Refactor DECL_ARGUMENT and DECL_RESULT generation to own function When looking into PR109108, the reason why things go awry is because of the logic around functions with thunks - they have their definitions generated even when they are external. This subsequently then relied on the detection of whether a function receiving codegen really is extern or not, and this check ultimately prunes too much. This is a first step to both removing the call to `build_decl_tree' from `make_thunk' and the pruning of symbols within the `build_decl_tree' visitor method for functions. Move the generation of DECL_ARGUMENT and DECL_RESULT out of `build_decl_tree' and into their own functions. gcc/d/ChangeLog: * decl.cc (get_fndecl_result): New function. (get_fndecl_arguments): New function. (DeclVisitor::visit (FuncDeclaration *)): Adjust to call get_fndecl_arguments. (make_thunk): Adjust to call get_fndecl_arguments and get_fndecl_result. (start_function): Adjust to call get_fndecl_result. Diff: --- gcc/d/decl.cc | 206 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 118 insertions(+), 88 deletions(-) diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 990ac4016b8..d4e936d0f83 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -117,6 +117,113 @@ gcc_attribute_p (Dsymbol *decl) return false; } +/* Return the DECL_RESULT for the function declaration DECL, create it if it + doesn't already exist. */ + +static tree +get_fndecl_result (FuncDeclaration *decl) +{ + tree fndecl = get_symbol_decl (decl); + tree resdecl = DECL_RESULT (fndecl); + + if (resdecl != NULL_TREE) + return resdecl; + + resdecl = build_decl (make_location_t (decl->loc), RESULT_DECL, + NULL_TREE, TREE_TYPE (TREE_TYPE (fndecl))); + + DECL_ARTIFICIAL (resdecl) = 1; + DECL_IGNORED_P (resdecl) = 1; + DECL_CONTEXT (resdecl) = fndecl; + DECL_RESULT (fndecl) = resdecl; + return resdecl; +} + +/* Return the list of PARAM_DECLs for the function declaration DECL, create it + if it doesn't already exist. */ + +static tree +get_fndecl_arguments (FuncDeclaration *decl) +{ + tree fndecl = get_symbol_decl (decl); + tree param_list = DECL_ARGUMENTS (fndecl); + + if (param_list != NULL_TREE) + return param_list; + + if (decl->fbody) + { + /* Handle special arguments first. */ + + /* `this' parameter: + For nested functions, D still generates a vthis, but it + should not be referenced in any expression. */ + if (decl->vthis) + { + tree parm_decl = get_symbol_decl (decl->vthis); + DECL_ARTIFICIAL (parm_decl) = 1; + TREE_READONLY (parm_decl) = 1; + + if (decl->vthis->type == Type::tvoidptr) + { + /* Replace generic pointer with back-end closure type + (this wins for gdb). */ + tree frame_type = FRAMEINFO_TYPE (get_frameinfo (decl)); + gcc_assert (frame_type != NULL_TREE); + TREE_TYPE (parm_decl) = build_pointer_type (frame_type); + } + + param_list = chainon (param_list, parm_decl); + } + + /* `_arguments' parameter. */ + if (decl->v_arguments) + { + tree parm_decl = get_symbol_decl (decl->v_arguments); + param_list = chainon (param_list, parm_decl); + } + + /* Now add on formal function parameters. */ + size_t n_parameters = decl->parameters ? decl->parameters->length : 0; + + for (size_t i = 0; i < n_parameters; i++) + { + VarDeclaration *param = (*decl->parameters)[i]; + tree parm_decl = get_symbol_decl (param); + + /* Type `noreturn` is a terminator, as no other arguments can possibly + be evaluated after it. */ + if (TREE_TYPE (parm_decl) == noreturn_type_node) + break; + + /* Chain them in the correct order. */ + param_list = chainon (param_list, parm_decl); + } + } + else + { + /* Build parameters from the function type. */ + tree fntype = TREE_TYPE (fndecl); + + for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t)) + { + if (t == void_list_node) + break; + + tree param = build_decl (DECL_SOURCE_LOCATION (fndecl), + PARM_DECL, NULL_TREE, TREE_VALUE (t)); + DECL_ARG_TYPE (param) = TREE_TYPE (param); + DECL_ARTIFICIAL (param) = 1; + DECL_IGNORED_P (param) = 1; + DECL_CONTEXT (param) = fndecl; + param_list = chainon (param_list, param); + } + } + + DECL_ARGUMENTS (fndecl) = param_list; + return param_list; +} + /* Implements the visitor interface to lower all Declaration AST classes emitted from the D Front-end to GCC trees. All visit methods accept one parameter D, which holds the frontend AST @@ -861,66 +968,17 @@ public: message ("function %s", d->toPrettyChars ()); tree old_context = start_function (d); + tree param_list = get_fndecl_arguments (d); - tree parm_decl = NULL_TREE; - tree param_list = NULL_TREE; - - /* Special arguments... */ - - /* `this' parameter: - For nested functions, D still generates a vthis, but it - should not be referenced in any expression. */ - if (d->vthis) - { - parm_decl = get_symbol_decl (d->vthis); - DECL_ARTIFICIAL (parm_decl) = 1; - TREE_READONLY (parm_decl) = 1; - - if (d->vthis->type == Type::tvoidptr) - { - /* Replace generic pointer with back-end closure type - (this wins for gdb). */ - tree frame_type = FRAMEINFO_TYPE (get_frameinfo (d)); - gcc_assert (frame_type != NULL_TREE); - TREE_TYPE (parm_decl) = build_pointer_type (frame_type); - } - - param_list = chainon (param_list, parm_decl); - d_function_chain->static_chain = parm_decl; - } - - /* _arguments parameter. */ - if (d->v_arguments) - { - parm_decl = get_symbol_decl (d->v_arguments); - param_list = chainon (param_list, parm_decl); - } - - /* formal function parameters. */ - const size_t n_parameters = d->parameters ? d->parameters->length : 0; - - for (size_t i = 0; i < n_parameters; i++) - { - VarDeclaration *param = (*d->parameters)[i]; - - parm_decl = get_symbol_decl (param); - - /* Type `noreturn` is a terminator, as no other arguments can possibly - be evaluated after it. */ - if (TREE_TYPE (parm_decl) == noreturn_type_node) - break; - - /* Chain them in the correct order. */ - param_list = chainon (param_list, parm_decl); - } - - DECL_ARGUMENTS (fndecl) = param_list; DECL_IN_UNITTEST_CONDITION_P (fndecl) = this->in_version_unittest_; rest_of_decl_compilation (fndecl, 1, 0); /* If this is a member function that nested (possibly indirectly) in another function, construct an expession for this member function's static chain by going through parent link of nested classes. */ + if (d->vthis) + d_function_chain->static_chain = get_symbol_decl (d->vthis); + if (d->isThis ()) { AggregateDeclaration *ad = d->isThis (); @@ -935,7 +993,7 @@ public: ad = pd->isAggregateDeclaration (); if (ad == NULL) { - cfun->language->static_chain = this_tree; + d_function_chain->static_chain = this_tree; break; } } @@ -996,7 +1054,7 @@ public: var = build_address (var); tree init = build_call_expr (builtin_decl_explicit (BUILT_IN_VA_START), - 2, var, parm_decl); + 2, var, tree_last (param_list)); declare_local_var (d->v_argptr); add_stmt (init); @@ -1879,34 +1937,12 @@ make_thunk (FuncDeclaration *decl, int offset) { /* Build parameters for functions that are not being compiled, so that they can be correctly cloned in finish_thunk. */ - tree fntype = TREE_TYPE (function); - tree params = NULL_TREE; - - for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t)) - { - if (t == void_list_node) - break; - - tree param = build_decl (DECL_SOURCE_LOCATION (function), - PARM_DECL, NULL_TREE, TREE_VALUE (t)); - DECL_ARG_TYPE (param) = TREE_TYPE (param); - DECL_ARTIFICIAL (param) = 1; - DECL_IGNORED_P (param) = 1; - DECL_CONTEXT (param) = function; - params = chainon (params, param); - } - - DECL_ARGUMENTS (function) = params; + tree function = get_symbol_decl (decl); + DECL_ARGUMENTS (function) = get_fndecl_arguments (decl); /* Also build the result decl, which is needed when force creating the thunk in gimple inside cgraph_node::expand_thunk. */ - tree resdecl = build_decl (DECL_SOURCE_LOCATION (function), - RESULT_DECL, NULL_TREE, - TREE_TYPE (fntype)); - DECL_ARTIFICIAL (resdecl) = 1; - DECL_IGNORED_P (resdecl) = 1; - DECL_CONTEXT (resdecl) = function; - DECL_RESULT (function) = resdecl; + DECL_RESULT (function) = get_fndecl_result (decl); } } @@ -2018,14 +2054,8 @@ start_function (FuncDeclaration *fd) /* Let GCC know the current scope is this function. */ current_function_decl = fndecl; - tree restype = TREE_TYPE (TREE_TYPE (fndecl)); - tree resdecl = build_decl (make_location_t (fd->loc), RESULT_DECL, - NULL_TREE, restype); - - DECL_RESULT (fndecl) = resdecl; - DECL_CONTEXT (resdecl) = fndecl; - DECL_ARTIFICIAL (resdecl) = 1; - DECL_IGNORED_P (resdecl) = 1; + /* Build the result decl before calling allocate_struct_function. */ + DECL_RESULT (fndecl) = get_fndecl_result (fd); /* Initialize the RTL code for the function. */ allocate_struct_function (fndecl, false);
reply other threads:[~2023-03-13 21:16 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230313211657.8041D3858D1E@sourceware.org \ --to=ibuclaw@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).