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: link
Be 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).