aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2010-01-09 17:47:04 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2010-01-09 17:47:04 +0000
commitf2ff577a338d9422ee2b35786b3ae873aab933fe (patch)
treefaf22ebd02e6d70418500dc89807d3068c3b0ad2 /gcc/fortran/resolve.c
parent7c0281633fd3af8f287b51f89906ce3d528216d1 (diff)
downloadgcc-f2ff577a338d9422ee2b35786b3ae873aab933fe.zip
gcc-f2ff577a338d9422ee2b35786b3ae873aab933fe.tar.gz
gcc-f2ff577a338d9422ee2b35786b3ae873aab933fe.tar.bz2
re PR fortran/20923 (gfortran slow for large array constructors)
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
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 8e8de8d..7321c0d 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -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;