[Patch, fortran] PR29397 and PR29400 - parameter arrays with scalar initializers
FX Coudert
fxcoudert@gmail.com
Mon May 7 19:35:00 GMT 2007
:REVIEWMAIL:
> 2006-05-07 Paul Thomas <pault@gcc.gnu.org>
>
> PR fortran/29397
> PR fortran/29400
> * decl.c (add_init_expr_to_sym): Expand a scalar initializer
> for a parameter array into an array expression with the right
> shape.
> * array.c (spec_dimen_size): Remove static attribute.
> * gfortran.h : Prototype for spec_dimen_size.
I'm concerned that we create a string of constructors for each single
element of the constant array. This scales very badly, and even more
badly if you consider how gfc_append_constructor() appears to work:
for each element, we start from the start of the constructor chain,
and go down to the last element to add the new one. I'd suggest to
change the code to something like the following:
Index: decl.c
===================================================================
--- decl.c (revision 124460)
+++ decl.c (working copy)
@@ -974,7 +974,44 @@ add_init_expr_to_sym (const char *name,
/* Add initializer. Make sure we keep the ranks sane. */
if (sym->attr.dimension && init->rank == 0)
- init->rank = sym->as->rank;
+ {
+ mpz_t size;
+ if (sym->attr.flavor == FL_PARAMETER
+ && init->expr_type == EXPR_CONSTANT
+ && spec_size (sym->as, &size) == SUCCESS
+ && mpz_cmp_si (size, 0) > 0)
+ {
+ gfc_expr *array;
+ gfc_constructor *c = NULL;
+ int n;
+
+ array = gfc_start_constructor (init->ts.type, init-
>ts.kind,
+ &init->where);
+ array->value.constructor = gfc_get_constructor ();
+
+ for (n = 0; n < (int)mpz_get_si (size); n++)
+ {
+ if (c == NULL)
+ c = array->value.constructor;
+ else
+ {
+ c->next = gfc_get_constructor ();
+ c = c->next;
+ }
+
+ c->expr = gfc_copy_expr (init);
+ }
+
+ array->shape = gfc_get_shape (sym->as->rank);
+ for (n = 0; n < sym->as->rank; n++)
+ spec_dimen_size (sym->as, n, &array->shape[n]);
+
+ gfc_free_expr (init);
+ init = array;
+ mpz_clear (size);
+ }
+ init->rank = sym->as->rank;
+ }
sym->value = init;
*initp = NULL;
I didn't regtest it, but simple tests appear to pass and be way
faster for large arrays.
So, my question is: why can't we use the repeat element of the
constructor structure for that? (I tried, but it appears to be
ignored later, as if the array had only one element; the comment on
top of the structure definition in gfortran.h hints that it's only
used for data initialization).
To summarize: the patch is OK, with the modification I suggest above
or something similar.
Thanks,
FX
More information about the Gcc-patches
mailing list