[fortran] Improve expansion of constant array expressions within constructors

Message ID trinity-6c2ea06f-d063-4853-8e5c-3713b118c3f7-1638046587840@3c-app-gmx-bs26
State New
Headers
Series [fortran] Improve expansion of constant array expressions within constructors |

Commit Message

Harald Anlauf Nov. 27, 2021, 8:56 p.m. UTC
  Dear all,

while analyzing several issues involving constructors and constant
array expressions, such as in PR102717 and PR102787, a common problem
showed up: we did not always properly expand parameter arrays,
array sections, or sections with vector subscripts.

Besides several ICEs as in these PRs, the incomplete expansion
led to an unnecessary creation of array temporaries.  This is
improved by the attached patch.

Regtested on x86_64-pc-linux-gnu.

OK for mainline?

Thanks,
Harald
  

Comments

Mikael Morin Nov. 30, 2021, 8:51 p.m. UTC | #1
Hello,

On 27/11/2021 21:56, Harald Anlauf via Fortran wrote:
> diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
> index 6552eaf3b0c..fbc66097c80 100644
> --- a/gcc/fortran/array.c
> +++ b/gcc/fortran/array.c
> @@ -1804,6 +1804,12 @@ expand_constructor (gfc_constructor_base base)
>        if (empty_constructor)
>  	empty_ts = e->ts;
> 
> +      /* Simplify constant array expression/section within constructor.  */
> +      if (e->expr_type == EXPR_VARIABLE && e->rank > 0 && e->ref
> +	  && e->symtree && e->symtree->n.sym
> +	  && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
> +	gfc_simplify_expr (e, 0);
> +
>        if (e->expr_type == EXPR_ARRAY)
>  	{
>  	  if (!expand_constructor (e->value.constructor))

There is another simplification call just a few lines below, that I 
thought could just be moved up.
But it works on a copy of the expression, and managing the copy makes it 
complex as well, so let’s do it your way.

OK.
  

Patch

From 6aced0b26e54cea48cca36637f3616054391864b Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Sat, 27 Nov 2021 21:43:52 +0100
Subject: [PATCH] Fortran: improve expansion of constant array expressions
 within constructors

gcc/fortran/ChangeLog:

	PR fortran/102787
	* array.c (expand_constructor): When encountering a constant array
	expression or array section within a constructor, simplify it to
	enable better expansion.

gcc/testsuite/ChangeLog:

	* gfortran.dg/array_constructor_54.f90: New test.
---
 gcc/fortran/array.c                           |  6 +++++
 .../gfortran.dg/array_constructor_54.f90      | 23 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/array_constructor_54.f90

diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 6552eaf3b0c..fbc66097c80 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -1804,6 +1804,12 @@  expand_constructor (gfc_constructor_base base)
       if (empty_constructor)
 	empty_ts = e->ts;

+      /* Simplify constant array expression/section within constructor.  */
+      if (e->expr_type == EXPR_VARIABLE && e->rank > 0 && e->ref
+	  && e->symtree && e->symtree->n.sym
+	  && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
+	gfc_simplify_expr (e, 0);
+
       if (e->expr_type == EXPR_ARRAY)
 	{
 	  if (!expand_constructor (e->value.constructor))
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_54.f90 b/gcc/testsuite/gfortran.dg/array_constructor_54.f90
new file mode 100644
index 00000000000..44d2f9fdf42
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_constructor_54.f90
@@ -0,0 +1,23 @@ 
+! { dg-do compile }
+! { dg-options "-fdump-tree-original -Warray-temporaries" }
+! { dg-final { scan-tree-dump-not "stride" "original" } }
+! Verify that no temporary array is generated for a constant array constructor
+! See e.g. PR fortran/102717, PR fortran/102787
+
+program p
+  integer, parameter :: a(*)   = [1,2,3,4]
+  integer, parameter :: b(2,3) = reshape([1,2,3,4,5,6], shape (b))
+  print *, [a]
+  print *, [a( : ) ]
+  print *, [a( ::1)]
+  print *, [a( ::2)]
+  print *, [a(1:2:1)]
+  print *, [a(4:1:-2)]
+  print *, [a([3,2])]
+  print *, [a,1]
+  print *, [1,a]
+  print *, [a,a]
+  print *, [b(:,3:1:-2)]
+  print *, [1,b(1,[2,1,3])]
+  print *, [a,b]
+end
--
2.26.2