public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Mikael Morin <mikael@gcc.gnu.org>
To: fortran@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: [PATCH v3 3/5] fortran: simplify elemental arguments walking
Date: Sun,  7 Nov 2021 17:16:34 +0100	[thread overview]
Message-ID: <20211107161636.1167116-4-mikael@gcc.gnu.org> (raw)
In-Reply-To: <20211107161636.1167116-1-mikael@gcc.gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1611 bytes --]


This adds two functions working with the wrapper struct gfc_dummy_arg
and makes usage of them to simplify a bit the walking of elemental
procedure arguments for scalarization.  As information about dummy arguments
can be obtained from the actual argument through the just-introduced
associated_dummy field, there is no need to carry around the procedure
interface and walk dummy arguments manually together with actual arguments.

gcc/fortran/ChangeLog:
	* interface.c (gfc_dummy_arg_get_typespec,
	gfc_dummy_arg_is_optional): New functions.
	* gfortran.h (gfc_dummy_arg_get_typespec,
	gfc_dummy_arg_is_optional): Declare them.
	* trans.h (gfc_ss_info::dummy_arg): Use the wrapper type
	as declaration type.
	* trans-array.c (gfc_scalar_elemental_arg_saved_as_reference):
	use gfc_dummy_arg_get_typespec function to get the type.
	(gfc_walk_elemental_function_args): Remove proc_ifc argument.
	Get info about the dummy arg using the associated_dummy field.
	* trans-array.h (gfc_walk_elemental_function_args): Update declaration.
	* trans-intrinsic.c (gfc_walk_intrinsic_function):
	Update call to gfc_walk_elemental_function_args.
	* trans-stmt.c (gfc_trans_call): Ditto.
	(get_proc_ifc_for_call): Remove.
---
 gcc/fortran/gfortran.h        |  4 ++++
 gcc/fortran/interface.c       | 34 ++++++++++++++++++++++++++++++++++
 gcc/fortran/trans-array.c     | 19 ++++++-------------
 gcc/fortran/trans-array.h     |  2 +-
 gcc/fortran/trans-intrinsic.c |  2 +-
 gcc/fortran/trans-stmt.c      | 22 ----------------------
 gcc/fortran/trans.h           |  4 ++--
 7 files changed, 48 insertions(+), 39 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0003-fortran-simplify-elemental-arguments-walking.patch --]
[-- Type: text/x-patch; name="0003-fortran-simplify-elemental-arguments-walking.patch", Size: 7147 bytes --]

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index d678c6b56dc..7e76e482b98 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2333,6 +2333,10 @@ struct gfc_dummy_arg
 #define gfc_get_dummy_arg() XCNEW (gfc_dummy_arg)
 
 
+const gfc_typespec & gfc_dummy_arg_get_typespec (gfc_dummy_arg &);
+bool gfc_dummy_arg_is_optional (gfc_dummy_arg &);
+
+
 /* Specifies the various kinds of check functions used to verify the
    argument lists of intrinsic functions. fX with X an integer refer
    to check functions of intrinsics with X arguments. f1m is used for
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index c4ec0d89a58..db0b3b01b8c 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -5503,3 +5503,37 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym,
       f = &((*f)->next);
     }
 }
+
+
+const gfc_typespec &
+gfc_dummy_arg_get_typespec (gfc_dummy_arg & dummy_arg)
+{
+  switch (dummy_arg.intrinsicness)
+    {
+    case GFC_INTRINSIC_DUMMY_ARG:
+      return dummy_arg.u.intrinsic->ts;
+
+    case GFC_NON_INTRINSIC_DUMMY_ARG:
+      return dummy_arg.u.non_intrinsic->sym->ts;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
+
+bool
+gfc_dummy_arg_is_optional (gfc_dummy_arg & dummy_arg)
+{
+  switch (dummy_arg.intrinsicness)
+    {
+    case GFC_INTRINSIC_DUMMY_ARG:
+      return dummy_arg.u.intrinsic->optional;
+
+    case GFC_NON_INTRINSIC_DUMMY_ARG:
+      return dummy_arg.u.non_intrinsic->sym->attr.optional;
+
+    default:
+      gcc_unreachable ();
+    }
+}
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 79321854498..d37c1e7ad7f 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -3010,7 +3010,8 @@ gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info * ss_info)
   /* If the expression is of polymorphic type, it's actual size is not known,
      so we avoid copying it anywhere.  */
   if (ss_info->data.scalar.dummy_arg
-      && ss_info->data.scalar.dummy_arg->ts.type == BT_CLASS
+      && gfc_dummy_arg_get_typespec (*ss_info->data.scalar.dummy_arg).type
+	 == BT_CLASS
       && ss_info->expr->ts.type == BT_CLASS)
     return true;
 
@@ -11521,9 +11522,8 @@ arg_evaluated_for_scalarization (gfc_intrinsic_sym *function,
 gfc_ss *
 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
 				  gfc_intrinsic_sym *intrinsic_sym,
-				  gfc_symbol *proc_ifc, gfc_ss_type type)
+				  gfc_ss_type type)
 {
-  gfc_formal_arglist *dummy_arg;
   int scalar;
   gfc_ss *head;
   gfc_ss *tail;
@@ -11532,15 +11532,11 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
   head = gfc_ss_terminator;
   tail = NULL;
 
-  if (proc_ifc)
-    dummy_arg = gfc_sym_get_dummy_args (proc_ifc);
-  else
-    dummy_arg = NULL;
-
   int arg_num = 0;
   scalar = 1;
   for (; arg; arg = arg->next)
     {
+      gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
       if (!arg->expr
 	  || arg->expr->expr_type == EXPR_NULL
 	  || !arg_evaluated_for_scalarization (intrinsic_sym, *arg, arg_num))
@@ -11554,13 +11550,13 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
 	  newss = gfc_get_scalar_ss (head, arg->expr);
 	  newss->info->type = type;
 	  if (dummy_arg)
-	    newss->info->data.scalar.dummy_arg = dummy_arg->sym;
+	    newss->info->data.scalar.dummy_arg = dummy_arg;
 	}
       else
 	scalar = 0;
 
       if (dummy_arg != NULL
-	  && dummy_arg->sym->attr.optional
+	  && gfc_dummy_arg_is_optional (*dummy_arg)
 	  && arg->expr->expr_type == EXPR_VARIABLE
 	  && (gfc_expr_attr (arg->expr).optional
 	      || gfc_expr_attr (arg->expr).allocatable
@@ -11577,8 +11573,6 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
 
 loop_continue:
       arg_num++;
-      if (dummy_arg != NULL)
-	dummy_arg = dummy_arg->next;
     }
 
   if (scalar)
@@ -11638,7 +11632,6 @@ gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
       ss = gfc_walk_elemental_function_args (old_ss,
 					     expr->value.function.actual,
 					     gfc_get_intrinsic_for_expr (expr),
-					     gfc_get_proc_ifc_for_expr (expr),
 					     GFC_SS_REFERENCE);
       if (ss != old_ss
 	  && (comp
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 8f806c32f80..9c4bd06d414 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -87,7 +87,7 @@ gfc_ss *gfc_walk_array_ref (gfc_ss *, gfc_expr *, gfc_ref * ref);
 /* Walk the arguments of an elemental function.  */
 gfc_ss *gfc_walk_elemental_function_args (gfc_ss *, gfc_actual_arglist *,
 					  gfc_intrinsic_sym *,
-					  gfc_symbol *, gfc_ss_type);
+					  gfc_ss_type);
 /* Walk an intrinsic function.  */
 gfc_ss *gfc_walk_intrinsic_function (gfc_ss *, gfc_expr *,
 				     gfc_intrinsic_sym *);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 3f867911af5..c1b51f4da26 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -11085,7 +11085,7 @@ gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
   if (isym->elemental)
     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
 					     expr->value.function.isym,
-					     NULL, GFC_SS_SCALAR);
+					     GFC_SS_SCALAR);
 
   if (expr->rank == 0)
     return ss;
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index bdf7957c4a0..1fc6d3adda5 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -375,27 +375,6 @@ get_intrinsic_for_code (gfc_code *code)
 }
 
 
-/* Get the interface symbol for the procedure corresponding to the given call.
-   We can't get the procedure symbol directly as we have to handle the case
-   of (deferred) type-bound procedures.  */
-
-static gfc_symbol *
-get_proc_ifc_for_call (gfc_code *c)
-{
-  gfc_symbol *sym;
-
-  gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
-
-  sym = gfc_get_proc_ifc_for_expr (c->expr1);
-
-  /* Fall back/last resort try.  */
-  if (sym == NULL)
-    sym = c->resolved_sym;
-
-  return sym;
-}
-
-
 /* Translate the CALL statement.  Builds a call to an F95 subroutine.  */
 
 tree
@@ -422,7 +401,6 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
   if (code->resolved_sym->attr.elemental)
     ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
 					   get_intrinsic_for_code (code),
-					   get_proc_ifc_for_call (code),
 					   GFC_SS_REFERENCE);
 
   /* MVBITS is inlined but needs the dependency checking found here.  */
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 0d4eed20d20..15012a336ff 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -266,8 +266,8 @@ typedef struct gfc_ss_info
     struct
     {
       /* If the scalar is passed as actual argument to an (elemental) procedure,
-	 this is the symbol of the corresponding dummy argument.  */
-      gfc_symbol *dummy_arg;
+	 this is the corresponding dummy argument.  */
+      gfc_dummy_arg *dummy_arg;
       tree value;
       /* Tells that the scalar is a reference to a variable that might
 	 be present on the lhs, so that we should evaluate the value

  parent reply	other threads:[~2021-11-07 16:16 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-07 16:16 [PATCH v3 0/5] fortran: Ignore unused arguments for scalarisation [PR97896] Mikael Morin
2021-11-07 16:16 ` [PATCH v3 1/5] fortran: Tiny sort_actual internal refactoring Mikael Morin
2021-11-07 16:16 ` [PATCH v3 2/5] fortran: Reverse actual vs dummy argument mapping Mikael Morin
2021-11-07 16:16 ` Mikael Morin [this message]
2021-11-07 16:16 ` [PATCH v3 4/5] fortran: Delete redundant missing_arg_type field Mikael Morin
2021-11-07 16:16 ` [PATCH v3 5/5] fortran: Identify arguments by their names Mikael Morin
2021-11-11 18:32 ` [PATCH v3 0/5] fortran: Ignore unused arguments for scalarisation [PR97896] Thomas Koenig

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=20211107161636.1167116-4-mikael@gcc.gnu.org \
    --to=mikael@gcc.gnu.org \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@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).