]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/20923 (gfortran slow for large array constructors)
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 9 Jan 2010 17:47:04 +0000 (17:47 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 9 Jan 2010 17:47:04 +0000 (17:47 +0000)
2010-01-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>

PR fortran/20923
PR fortran/32489
* trans-array.c (gfc_conv_array_initializer): Change call to
gfc_error_now to call to gfc_fatal_error.
* array.c (count_elements): Whitespace. (extract_element): Whitespace.
(is_constant_element): Changed name from constant_element.
(gfc_constant_ac): Only use expand_construuctor for expression
types of EXPR_ARRAY.  If expression type is EXPR_CONSTANT, no need to
call gfc_is_constant_expr.
* expr.c (gfc_reduce_init_expr): Adjust conditionals and delete error
message.
* resolve.c (gfc_is_expandable_expr): New function that determiners if
array expressions should have their constructors expanded.
(gfc_resolve_expr): Use new function to determine whether or not to call
gfc_expand_constructor.

From-SVN: r155769

gcc/fortran/ChangeLog
gcc/fortran/array.c
gcc/fortran/expr.c
gcc/fortran/resolve.c
gcc/fortran/trans-array.c

index 321a407fa3401198a3ade8dab867c9e25bc5f2d1..d6ec8aa559707de3e9bf450c0cbca8747f172613 100644 (file)
@@ -1,3 +1,21 @@
+2010-01-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+       PR fortran/20923
+       PR fortran/32489
+       * trans-array.c (gfc_conv_array_initializer): Change call to
+       gfc_error_now to call to gfc_fatal_error.
+       * array.c (count_elements): Whitespace. (extract_element): Whitespace.
+       (is_constant_element): Changed name from constant_element.
+       (gfc_constant_ac): Only use expand_construuctor for expression
+       types of EXPR_ARRAY.  If expression type is EXPR_CONSTANT, no need to
+       call gfc_is_constant_expr.
+       * expr.c (gfc_reduce_init_expr): Adjust conditionals and delete error
+       message.
+       * resolve.c (gfc_is_expandable_expr): New function that determiners if
+       array expressions should have their constructors expanded.
+       (gfc_resolve_expr): Use new function to determine whether or not to call
+       gfc_expand_constructor.
+
 2010-01-09  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/41298
index e1a5f25badf3e1d21cc5bfc5872c0815024e0bf4..7bb51003418142429575e909c48ee065c89b2073 100644 (file)
@@ -1237,7 +1237,6 @@ count_elements (gfc_expr *e)
 static gfc_try
 extract_element (gfc_expr *e)
 {
-
   if (e->rank != 0)
     {                          /* Something unextractable */
       gfc_free_expr (e);
@@ -1250,6 +1249,7 @@ extract_element (gfc_expr *e)
     gfc_free_expr (e);
 
   current_expand.extract_count++;
+  
   return SUCCESS;
 }
 
@@ -1495,7 +1495,7 @@ done:
    FAILURE if not so.  */
 
 static gfc_try
-constant_element (gfc_expr *e)
+is_constant_element (gfc_expr *e)
 {
   int rv;
 
@@ -1517,14 +1517,38 @@ gfc_constant_ac (gfc_expr *e)
 {
   expand_info expand_save;
   gfc_try rc;
+  gfc_constructor * con;
+  
+  rc = SUCCESS;
 
-  iter_stack = NULL;
-  expand_save = current_expand;
-  current_expand.expand_work_function = constant_element;
+  if (e->value.constructor
+      && e->value.constructor->expr->expr_type == EXPR_ARRAY 
+      && !e->value.constructor->iterator)
+    {
+      /* Expand the constructor.  */
+      iter_stack = NULL;
+      expand_save = current_expand;
+      current_expand.expand_work_function = is_constant_element;
 
-  rc = expand_constructor (e->value.constructor);
+      rc = expand_constructor (e->value.constructor);
+
+      current_expand = expand_save;
+    }
+  else
+    {
+      /* No need to expand this further.  */
+      for (con = e->value.constructor; con; con = con->next)
+       {
+         if (con->expr->expr_type == EXPR_CONSTANT)
+           continue;
+         else
+           {
+             if (!gfc_is_constant_expr (con->expr))
+               rc = FAILURE;
+           }
+       }
+    }
 
-  current_expand = expand_save;
   if (rc == FAILURE)
     return 0;
 
index 72420ff01b5b443e367deb85e7f0d7b67992fc74..8fa46d82f708557f35ab8e9ca25f87275bba850c 100644 (file)
@@ -2460,18 +2460,12 @@ gfc_reduce_init_expr (gfc_expr *expr)
   if (t == FAILURE)
     return FAILURE;
 
-  if (expr->expr_type == EXPR_ARRAY
-      && (gfc_check_constructor_type (expr) == FAILURE
-      || gfc_expand_constructor (expr) == FAILURE))
-    return FAILURE;
-
-  /* Not all inquiry functions are simplified to constant expressions
-     so it is necessary to call check_inquiry again.  */ 
-  if (!gfc_is_constant_expr (expr) && check_inquiry (expr, 1) != MATCH_YES
-      && !gfc_in_match_data ())
+  if (expr->expr_type == EXPR_ARRAY)
     {
-      gfc_error ("Initialization expression didn't reduce %C");
-      return FAILURE;
+      if (gfc_check_constructor_type (expr) == FAILURE)
+       return FAILURE;
+      if (gfc_expand_constructor (expr) == FAILURE)
+       return FAILURE;
     }
 
   return SUCCESS;
index 8e8de8d5923ca418386e8b56438b6370c88749cd..7321c0dd7675de5a83426cf9332f597fdff73595 100644 (file)
@@ -5516,6 +5516,32 @@ resolve_expr_ppc (gfc_expr* e)
 }
 
 
+static bool
+gfc_is_expandable_expr (gfc_expr *e)
+{
+  gfc_constructor *con;
+
+  if (e->expr_type == EXPR_ARRAY)
+    {
+      /* Traverse the constructor looking for variables that are flavor
+        parameter.  Parameters must be expanded since they are fully used at
+        compile time.  */
+      for (con = e->value.constructor; con; con = con->next)
+       {
+         if (con->expr->expr_type == EXPR_VARIABLE
+         && con->expr->symtree
+         && (con->expr->symtree->n.sym->attr.flavor == FL_PARAMETER
+             || con->expr->symtree->n.sym->attr.flavor == FL_VARIABLE))
+           return true;
+         if (con->expr->expr_type == EXPR_ARRAY
+           && gfc_is_expandable_expr (con->expr))
+           return true;
+       }
+    }
+
+  return false;
+}
+
 /* Resolve an expression.  That is, make sure that types of operands agree
    with their operators, intrinsic operators are converted to function calls
    for overloaded types and unresolved function references are resolved.  */
@@ -5582,14 +5608,20 @@ gfc_resolve_expr (gfc_expr *e)
       if (t == SUCCESS)
        {
          expression_rank (e);
-         gfc_expand_constructor (e);
+         if (gfc_is_constant_expr (e) || gfc_is_expandable_expr (e))
+           gfc_expand_constructor (e);
        }
 
       /* This provides the opportunity for the length of constructors with
         character valued function elements to propagate the string length
         to the expression.  */
       if (t == SUCCESS && e->ts.type == BT_CHARACTER)
-       t = gfc_resolve_character_array_constructor (e);
+        {
+         /* For efficiency, we call gfc_expand_constructor for BT_CHARACTER
+            here rather then add a duplicate test for it above.  */ 
+         gfc_expand_constructor (e);
+         t = gfc_resolve_character_array_constructor (e);
+       }
 
       break;
 
index 6486bb60ec6334abcc50dfac7c27321b1cb40b86..063b26297a70b8340384ce2a29f0228703a8c05d 100644 (file)
@@ -4109,11 +4109,11 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr)
             {
               /* Problems occur when we get something like
                  integer :: a(lots) = (/(i, i=1, lots)/)  */
-              gfc_error_now ("The number of elements in the array constructor "
-                            "at %L requires an increase of the allowed %d "
-                            "upper limit.   See -fmax-array-constructor "
-                            "option", &expr->where,
-                            gfc_option.flag_max_array_constructor);
+              gfc_fatal_error ("The number of elements in the array constructor "
+                              "at %L requires an increase of the allowed %d "
+                              "upper limit.   See -fmax-array-constructor "
+                              "option", &expr->where,
+                              gfc_option.flag_max_array_constructor);
              return NULL_TREE;
            }
           if (mpz_cmp_si (c->n.offset, 0) != 0)