Re: [PATCH 6/6] fortran: array descriptor: Move null actual creation [PR122521]

Harald Anlauf <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
Hi Mikael,

thanks for this refactorization and cleanup.  It is nice that you
could remove an old hack for avoiding and unwanted write-back of an
array descriptor.

I have only skimmed the patches, most of which appear clear enough.
There is only a minor and trivial cleanup (missed dead code) below.

Am 02.08.26 um 10:59 PM schrieb Mikael Morin:
> From: Mikael Morin <[email protected]>
> 
> Fortran-tested on aarch64-unknown-linux-gnu.  OK for mainline?
> 
> -- >8 --
> 
> The creation of a descriptor corresponding to a null() actual argument is
> repeated three times in conv_null_actual to handle three different cases.
> Factor that code to a common function in to trans-descriptor.cc.
> 
> The factored code consisted of calling the scalar descriptor generator,
> and then generating a modification of the descriptor rank.  This was
> producing correct initialization code for the descriptor, but with a
> wrong type and an incorrect zero GFC_TYPE_ARRAY_RANK attached to it.  So
> this change additionnally inlines the scalar descriptor generation,
> replacing the hardcoded zero rank with the true rank passed as argument, so
> that the variable has the right type and is directly generated with the
> correct rank.  With this, the descriptor is bigger because of a non-empty
> array of useless (and uninitialized) dimensions, but it's the type that is
> expected from within the procedure.
> 
> More, the scalar descriptor generation, as an argument passing
> implementation detail, was generating code copying back to the original
> variable on return.  This is not applicable to null() actual arguments and
> this change removes it from the inlined code.  That part actually used to
> cause a gimplification failure for copy back code that looked like this:
>      &C.5048 = (void * *) desc.14.data;
> Harald provided a workaround for this with his r15-6408-gd637e6d069ade7 [1]
> null() work, that changed the intent attribute of an argument in one of the
> three places modified here.  This change, having removed the offending code,
> removes the workaround as well.
> 
> [1]: https://gcc.gnu.org/pipermail/gcc-patches/2024-December/671673.html
> 
> 	PR fortran/122521
> 
> gcc/fortran/ChangeLog:
> 
> 	* trans-expr.cc (conv_null_actual): Remove dummy symbol intent
> 	attribute modification.  Move the three times repeated descriptor
> 	initialization...
> 	* trans-descriptor.cc (gfc_create_null_actual_descriptor): ...
> 	here as a new function and inline the call to
> 	gfc_conv_scalar_to_descriptor.  Remove the inapplicable or
> 	redundant parts from the inlined code.  Create lower and upper
> 	bounds arrays and clear them before passing to the type creation
> 	function.
> 	* trans-descriptor.h (gfc_create_null_actual_descriptor): New
> 	declaration.
> ---
>   gcc/fortran/trans-descriptor.cc | 39 +++++++++++++++++++++++++++++++++
>   gcc/fortran/trans-descriptor.h  |  2 ++
>   gcc/fortran/trans-expr.cc       | 21 ++++++------------
>   3 files changed, 48 insertions(+), 14 deletions(-)
> 
> diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
> index 85a9471bcf1..9c273bf10ea 100644
> --- a/gcc/fortran/trans-descriptor.cc
> +++ b/gcc/fortran/trans-descriptor.cc
> @@ -805,6 +805,45 @@ gfc_create_unallocated_library_result_descriptor (stmtblock_t *block,
>   }
>   
>   
> +/* Create a new descriptor to represent a null actual argument of type TS and
> +   rank RANK passed to a dummy argument having attributes ATTR.  Add
> +   initialization code to BLOCK and return the descriptor declaration.  */
> +
> +tree
> +gfc_create_null_actual_descriptor (stmtblock_t *block, gfc_typespec *ts,
> +				   symbol_attribute attr, int rank)
> +{
> +  tree etype = gfc_typenode_for_spec (ts);
> +
> +  enum gfc_array_kind akind;
> +
> +  if (attr.pointer)
> +    akind = GFC_ARRAY_POINTER_CONT;
> +  else if (attr.allocatable)
> +    akind = GFC_ARRAY_ALLOCATABLE;
> +  else
> +    akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
> +
> +  tree lower[GFC_MAX_DIMENSIONS];
> +  tree upper[GFC_MAX_DIMENSIONS];
> +  memset (&lower, 0, rank * sizeof (lower[0]));
> +  memset (&upper, 0, rank * sizeof (upper[0]));
> +
> +  tree type = gfc_get_array_type_bounds (etype, rank, 0, lower, upper, 1,
> +					 akind, !(attr.pointer || attr.target));
> +  tree desc = gfc_create_var (type, "desc");
> +  DECL_ARTIFICIAL (desc) = 1;
> +
> +  gfc_conv_descriptor_dtype_set (block, desc,
> +				 gfc_get_dtype_rank_type (rank, etype));
> +  gfc_conv_descriptor_data_set (block, desc, null_pointer_node);
> +  gfc_conv_descriptor_span_set (block, desc,
> +				gfc_conv_descriptor_elem_len_get (desc));
> +
> +  return desc;
> +}
> +
> +
>   /* For an array descriptor, get the total number of elements.  This is just
>      the product of the extents along from_dim to to_dim.  */
>   
> diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
> index 80f5db72d84..c7f3df02def 100644
> --- a/gcc/fortran/trans-descriptor.h
> +++ b/gcc/fortran/trans-descriptor.h
> @@ -70,6 +70,8 @@ void gfc_init_descriptor_variable (stmtblock_t *block, gfc_symbol *sym,
>   				   tree descr);
>   tree gfc_create_unallocated_library_result_descriptor (stmtblock_t *, tree,
>   						       tree);
> +tree gfc_create_null_actual_descriptor (stmtblock_t *, gfc_typespec *,
> +					symbol_attribute, int);
>   
>   tree gfc_conv_descriptor_size (tree, int);
>   tree gfc_conv_descriptor_cosize (tree, int, int);
> diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
> index 59ce9c64ad8..5e13d595095 100644
> --- a/gcc/fortran/trans-expr.cc
> +++ b/gcc/fortran/trans-expr.cc
> @@ -6874,8 +6874,8 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, gfc_symbol * fsym)
>   	  if (fsym->as && fsym->as->type == AS_ASSUMED_RANK)
>   	    {
>   	      tree tmp = parmse->expr;
> -	      tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, fsym->attr);
> -	      gfc_conv_descriptor_rank_set (&parmse->pre, tmp, e->rank);
> +	      tmp = gfc_create_null_actual_descriptor (&parmse->pre, &e->ts,
> +						       fsym->attr, e->rank);
>   	      parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
>   	    }
>   	  else
> @@ -6927,26 +6927,19 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, gfc_symbol * fsym)
>   	{
>   	  tree tmp = parmse->expr;
>   
> -	  tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, gfc_expr_attr (e));
> -	  gfc_conv_descriptor_rank_set (&parmse->pre, tmp, e->rank);
> -	  gfc_conv_descriptor_data_set (&parmse->pre, tmp, null_pointer_node);
> +	  tmp = gfc_create_null_actual_descriptor (&parmse->pre, &e->ts,
> +						   fsym->attr, e->rank);
>   	  parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
>   	}
>         else
>   	/* MOLD is not present.  Use attributes from dummy argument, which is
>   	   not allowed to be assumed-rank.  */
>   	{
> -	  int dummy_rank;
>   	  tree tmp = parmse->expr;
                      ^^^^^^^^^^^^
The r.h.s. here is dead code and can be removed.

>   
> -	  if ((fsym->attr.allocatable || fsym->attr.pointer)
> -	      && fsym->attr.intent == INTENT_UNKNOWN)
> -	    fsym->attr.intent = INTENT_IN;
> -	  tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, fsym->attr);
> -	  dummy_rank = fsym->as ? fsym->as->rank : 0;
> -	  if (dummy_rank > 0)
> -	    gfc_conv_descriptor_rank_set (&parmse->pre, tmp, dummy_rank);
> -	  gfc_conv_descriptor_data_set (&parmse->pre, tmp, null_pointer_node);
> +	  int dummy_rank = fsym->as ? fsym->as->rank : 0;
> +	  tmp = gfc_create_null_actual_descriptor (&parmse->pre, &fsym->ts,
> +						   fsym->attr, dummy_rank);
>   	  parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
>   	}
>       }

Thanks,
Harald
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.