From 1f34d027938e85a27c0cdfdac8b1009a74d09ccb Mon Sep 17 00:00:00 2001 From: tkoenig Date: Wed, 18 Oct 2017 21:29:37 +0000 Subject: [PATCH] 2017-10-18 Thomas Koenig 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 PR fortran/82567 * gfortran.dg/array_constructor_51.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253872 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 8 ++++++ gcc/fortran/frontend-passes.c | 30 +++++++++++++++++++++- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gfortran.dg/array_constructor_51.f90 | 20 +++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/array_constructor_51.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 8b9f90eeb0f..2d903e2969a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,13 @@ 2017-10-18 Thomas Koenig + 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 + 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 ae4fba63b3c..fcfaf9508c2 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 a792c359d00..8e866af0cf2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2017-10-18 Thomas Koenig + PR fortran/82567 + * gfortran.dg/array_constructor_51.f90: New test. + +2017-10-18 Thomas Koenig + 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 00000000000..4c3cdf71fcf --- /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" } } -- 2.11.4.GIT