Commit f2ff577a by Jerry DeLisle

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
parent 7c028163
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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment