aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2017-10-18 21:29:37 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2017-10-18 21:29:37 +0000
commite35ba10a77dae0b356d78f36bbabebe053264eb0 (patch)
tree7aa37aa9dd5d44e348748e53461b23454160f1f9
parent9d0d0a5a1312edb8c32160c5645cf72841efa12d (diff)
downloadgcc-e35ba10a77dae0b356d78f36bbabebe053264eb0.zip
gcc-e35ba10a77dae0b356d78f36bbabebe053264eb0.tar.gz
gcc-e35ba10a77dae0b356d78f36bbabebe053264eb0.tar.bz2
re PR fortran/82567 ([6/7/8] gfortran takes a long time to compile a simple implied-do with -Optimization.)
2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/82567 * frontend-passes.c (combine_array_constructor): If an array constructor is all constants and has more elements than a small constant, don't convert a*[b,c] to [a*b,a*c] to reduce compilation times. 2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/82567 * gfortran.dg/array_constructor_51.f90: New test. From-SVN: r253872
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/frontend-passes.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_51.f9020
4 files changed, 62 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8b9f90e..2d903e2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,13 @@
2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org>
+ PR fortran/82567
+ * frontend-passes.c (combine_array_constructor): If an array
+ constructor is all constants and has more elements than a small
+ constant, don't convert a*[b,c] to [a*b,a*c] to reduce compilation
+ times.
+
+2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org>
+
PR fortran/79795
* resolve.c (resovle_symbol): Change gcc_assert to
sensible error message.
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index ae4fba6..fcfaf95 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -1635,6 +1635,8 @@ combine_array_constructor (gfc_expr *e)
gfc_constructor *c, *new_c;
gfc_constructor_base oldbase, newbase;
bool scalar_first;
+ int n_elem;
+ bool all_const;
/* Array constructors have rank one. */
if (e->rank != 1)
@@ -1674,12 +1676,38 @@ combine_array_constructor (gfc_expr *e)
if (op2->ts.type == BT_CHARACTER)
return false;
- scalar = create_var (gfc_copy_expr (op2), "constr");
+ /* This might be an expanded constructor with very many constant values. If
+ we perform the operation here, we might end up with a long compile time
+ and actually longer execution time, so a length bound is in order here.
+ If the constructor constains something which is not a constant, it did
+ not come from an expansion, so leave it alone. */
+
+#define CONSTR_LEN_MAX 4
oldbase = op1->value.constructor;
+
+ n_elem = 0;
+ all_const = true;
+ for (c = gfc_constructor_first (oldbase); c; c = gfc_constructor_next(c))
+ {
+ if (c->expr->expr_type != EXPR_CONSTANT)
+ {
+ all_const = false;
+ break;
+ }
+ n_elem += 1;
+ }
+
+ if (all_const && n_elem > CONSTR_LEN_MAX)
+ return false;
+
+#undef CONSTR_LEN_MAX
+
newbase = NULL;
e->expr_type = EXPR_ARRAY;
+ scalar = create_var (gfc_copy_expr (op2), "constr");
+
for (c = gfc_constructor_first (oldbase); c;
c = gfc_constructor_next (c))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a792c35..8e866af 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org>
+ PR fortran/82567
+ * gfortran.dg/array_constructor_51.f90: New test.
+
+2017-10-18 Thomas Koenig <tkoenig@gcc.gnu.org>
+
PR fortran/79795
* gfortran.dg/assumed_size_2.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_51.f90 b/gcc/testsuite/gfortran.dg/array_constructor_51.f90
new file mode 100644
index 0000000..4c3cdf7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_constructor_51.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-additional-options "-ffrontend-optimize -fdump-tree-original" }
+! PR 82567 - long compile times caused by large constant constructors
+! multiplied by variables
+
+ SUBROUTINE sub()
+ IMPLICIT NONE
+
+ INTEGER, PARAMETER :: n = 1000
+ REAL, ALLOCATABLE :: x(:)
+ REAL :: xc, h
+ INTEGER :: i
+
+ ALLOCATE( x(n) )
+ xc = 100.
+ h = xc/n
+ x = h*[(i,i=1,n)]
+
+end
+! { dg-final { scan-tree-dump-times "__var" 0 "original" } }