To avoid confusion between multiple loops, a new loop field is added to the gfc_ss (patch 35). Then we can remove superfluous loop argument in function interfaces: - set_vector_loop_bounds (patch 36) - gfc_trans_array_constructor (patch 37) - gfc_trans_create_temp_array (patch 39) Patch 38 prepares patch 39 by adding a new variable total_dim which will be the sum of multiple nested loop dimensions so that the number of loop usages (through loop.dimen) is reduced. OK?
2011-10-19 Mikael Morin <mik...@gcc.gnu.org>
* trans.h (struct gfc_ss): New field loop. * trans-array.c (set_ss_loop): New function. (gfc_add_ss_to_loop): Call set_ss_loop.
diff --git a/trans-array.c b/trans-array.c index abb6db2..e64767a 100644 --- a/trans-array.c +++ b/trans-array.c @@ -618,6 +618,27 @@ gfc_cleanup_loop (gfc_loopinfo * loop) } +static void +set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop) +{ + int n; + + for (; ss != gfc_ss_terminator; ss = ss->next) + { + ss->loop = loop; + + if (ss->info->type == GFC_SS_SCALAR + || ss->info->type == GFC_SS_REFERENCE + || ss->info->type == GFC_SS_TEMP) + continue; + + for (n = 0; n < GFC_MAX_DIMENSIONS; n++) + if (ss->info->data.array.subscript[n] != NULL) + set_ss_loop (ss->info->data.array.subscript[n], loop); + } +} + + /* Associate a SS chain with a loop. */ void @@ -628,6 +649,8 @@ gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head) if (head == gfc_ss_terminator) return; + set_ss_loop (head, loop); + ss = head; for (; ss && ss != gfc_ss_terminator; ss = ss->next) { diff --git a/trans.h b/trans.h index 02f2b42..62bcc64 100644 --- a/trans.h +++ b/trans.h @@ -246,6 +246,9 @@ typedef struct gfc_ss struct gfc_ss *loop_chain; struct gfc_ss *next; + /* The loop this gfc_ss is in. */ + struct gfc_loopinfo *loop; + unsigned is_alloc_lhs:1; } gfc_ss;
2011-10-19 Mikael Morin <mik...@gcc.gnu.org> * trans-array.c (gfc_set_vector_loop_bounds): Get loop from ss. Remove loop argument. (gfc_add_loop_ss_code): Update call.
diff --git a/trans-array.c b/trans-array.c index e64767a..a305ac3 100644 --- a/trans-array.c +++ b/trans-array.c @@ -2162,8 +2162,9 @@ finish: loop bounds. */ static void -set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss * ss) +set_vector_loop_bounds (gfc_ss * ss) { + gfc_loopinfo *loop; gfc_array_info *info; gfc_se se; tree tmp; @@ -2173,6 +2174,7 @@ set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss * ss) int dim; info = &ss->info->data.array; + loop = ss->loop; for (n = 0; n < loop->dimen; n++) { @@ -2271,7 +2273,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript, if (info->subscript[n]) gfc_add_loop_ss_code (loop, info->subscript[n], true, where); - set_vector_loop_bounds (loop, ss); + set_vector_loop_bounds (ss); break; case GFC_SS_VECTOR:
2011-10-19 Mikael Morin <mik...@gcc.gnu.org> * trans-array.c (gfc_trans_array_constructor, trans_array_constructor): Rename the former to the later. Get loop from ss. Remove loop argument. (gfc_add_loop_ss_code): Update call.
diff --git a/trans-array.c b/trans-array.c index a305ac3..01a411a 100644 --- a/trans-array.c +++ b/trans-array.c @@ -1981,7 +1981,7 @@ constant_array_constructor_loop_size (gfc_loopinfo * loop) simplest method. */ static void -gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where) +trans_array_constructor (gfc_ss * ss, locus * where) { gfc_constructor_base c; tree offset; @@ -1992,6 +1992,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where) bool dynamic; bool old_first_len, old_typespec_chararray_ctor; tree old_first_len_val; + gfc_loopinfo *loop; gfc_ss_info *ss_info; gfc_expr *expr; @@ -2000,6 +2001,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where) old_first_len_val = first_len_val; old_typespec_chararray_ctor = typespec_chararray_ctor; + loop = ss->loop; ss_info = ss->info; expr = ss_info->expr; @@ -2314,7 +2316,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript, gfc_add_block_to_block (&loop->pre, &se.pre); gfc_add_block_to_block (&loop->post, &se.post); } - gfc_trans_array_constructor (loop, ss, where); + trans_array_constructor (ss, where); break; case GFC_SS_TEMP:
2011-10-19 Mikael Morin <mik...@gcc.gnu.org> * trans-array.c (gfc_trans_create_temp_array): New variable total_dim. Set total_dim to loop's rank. Replace usages of loop's rank.
diff --git a/trans-array.c b/trans-array.c index 01a411a..b2388c1 100644 --- a/trans-array.c +++ b/trans-array.c @@ -907,6 +907,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, tree cond; tree or_expr; int n, dim, tmp_dim; + int total_dim = 0; memset (from, 0, sizeof (from)); memset (to, 0, sizeof (to)); @@ -919,6 +920,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, if (gfc_option.warn_array_temp && where) gfc_warning ("Creating array temporary at %L", where); + total_dim = loop->dimen; /* Set the lower bound to zero. */ for (n = 0; n < loop->dimen; n++) { @@ -956,7 +958,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, /* Initialize the descriptor. */ type = - gfc_get_array_type_bounds (eltype, ss->dimen, 0, from, to, 1, + gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1, GFC_ARRAY_UNKNOWN, true); desc = gfc_create_var (type, "atmp"); GFC_DECL_PACKED_ARRAY (desc) = 1; @@ -985,8 +987,8 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, /* If there is at least one null loop->to[n], it is a callee allocated array. */ - for (n = 0; n < loop->dimen; n++) - if (loop->to[n] == NULL_TREE) + for (n = 0; n < total_dim; n++) + if (to[n] == NULL_TREE) { size = NULL_TREE; break; @@ -1009,7 +1011,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, } else { - for (n = 0; n < loop->dimen; n++) + for (n = 0; n < total_dim; n++) { /* Store the stride and bound components in the descriptor. */ gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
2011-10-19 Mikael Morin <mik...@gcc.gnu.org> * trans-array.h (gfc_trans_create_temp_array): Remove loop argument. * trans-array.c (gfc_trans_create_temp_array): Get loop from ss. Update reference to loop. Remove loop argument. (gfc_trans_array_constructor, gfc_conv_loop_setup): Update calls to gfc_trans_create_temp_array. * trans-expr.c (gfc_conv_procedure_call): Ditto. * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Ditto. * trans-stmt.c (gfc_conv_elemental_dependencies): Ditto. Set loop before calling gfc_trans_create_temp_array.
diff --git a/trans-array.c b/trans-array.c index b2388c1..d386a22 100644 --- a/trans-array.c +++ b/trans-array.c @@ -888,15 +888,14 @@ get_array_ref_dim (gfc_ss *ss, int loop_dim) callee allocated array. PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for - gfc_trans_allocate_array_storage. - */ + gfc_trans_allocate_array_storage. */ tree -gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, - gfc_loopinfo * loop, gfc_ss * ss, +gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, tree eltype, tree initial, bool dynamic, bool dealloc, bool callee_alloc, locus * where) { + gfc_loopinfo *loop; gfc_array_info *info; tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS]; tree type; @@ -915,11 +914,12 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, info = &ss->info->data.array; gcc_assert (ss->dimen > 0); - gcc_assert (loop->dimen == ss->dimen); + gcc_assert (ss->loop->dimen == ss->dimen); if (gfc_option.warn_array_temp && where) gfc_warning ("Creating array temporary at %L", where); + loop = ss->loop; total_dim = loop->dimen; /* Set the lower bound to zero. */ for (n = 0; n < loop->dimen; n++) @@ -1065,8 +1065,8 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial, dynamic, dealloc); - if (ss->dimen > loop->temp_dim) - loop->temp_dim = ss->dimen; + if (ss->dimen > ss->loop->temp_dim) + ss->loop->temp_dim = ss->dimen; return size; } @@ -2113,8 +2113,8 @@ trans_array_constructor (gfc_ss * ss, locus * where) if (TREE_CODE (loop->to[0]) == VAR_DECL) dynamic = true; - gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, ss, - type, NULL_TREE, dynamic, true, false, where); + gfc_trans_create_temp_array (&loop->pre, &loop->post, ss, type, NULL_TREE, + dynamic, true, false, where); desc = ss_info->data.array.descriptor; offset = gfc_index_zero_node; @@ -4211,9 +4211,8 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) gcc_assert (tmp_ss->dimen != 0); - gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, - tmp_ss, tmp, NULL_TREE, - false, true, false, where); + gfc_trans_create_temp_array (&loop->pre, &loop->post, tmp_ss, tmp, + NULL_TREE, false, true, false, where); } /* For array parameters we don't have loop variables, so don't calculate the diff --git a/trans-array.h b/trans-array.h index 57805b6..aad8c47 100644 --- a/trans-array.h +++ b/trans-array.h @@ -31,9 +31,8 @@ void gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping *, gfc_se *, gfc_array_spec *); /* Generate code to create a temporary array. */ -tree gfc_trans_create_temp_array (stmtblock_t *, stmtblock_t *, gfc_loopinfo *, - gfc_ss *, tree, tree, bool, bool, bool, - locus *); +tree gfc_trans_create_temp_array (stmtblock_t *, stmtblock_t *, gfc_ss *, + tree, tree, bool, bool, bool, locus *); /* Generate function entry code for allocation of compiler allocated array variables. */ diff --git a/trans-expr.c b/trans-expr.c index 01d4ca3..e091c89 100644 --- a/trans-expr.c +++ b/trans-expr.c @@ -3606,7 +3606,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, returns a pointer, the temporary will be a shallow copy and mustn't be deallocated. */ callee_alloc = comp->attr.allocatable || comp->attr.pointer; - gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, se->ss, + gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, tmp, NULL_TREE, false, !comp->attr.pointer, callee_alloc, &se->ss->info->expr->where); @@ -3642,7 +3642,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, returns a pointer, the temporary will be a shallow copy and mustn't be deallocated. */ callee_alloc = sym->attr.allocatable || sym->attr.pointer; - gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, se->ss, + gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, tmp, NULL_TREE, false, !sym->attr.pointer, callee_alloc, &se->ss->info->expr->where); diff --git a/trans-intrinsic.c b/trans-intrinsic.c index fcc59d7..c3a414b 100644 --- a/trans-intrinsic.c +++ b/trans-intrinsic.c @@ -5501,9 +5501,8 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr) /* Build a destination descriptor, using the pointer, source, as the data field. */ - gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, - se->ss, mold_type, NULL_TREE, false, true, false, - &expr->where); + gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, mold_type, + NULL_TREE, false, true, false, &expr->where); /* Cast the pointer to the result. */ tmp = gfc_conv_descriptor_data_get (info->descriptor); diff --git a/trans-stmt.c b/trans-stmt.c index 86a56e8..2e02320 100644 --- a/trans-stmt.c +++ b/trans-stmt.c @@ -309,11 +309,10 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse, size = gfc_create_var (gfc_array_index_type, NULL); data = gfc_create_var (pvoid_type_node, NULL); gfc_init_block (&temp_post); - tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, - &tmp_loop, ss, temptype, - initial, - false, true, false, - &arg->expr->where); + ss->loop = &tmp_loop; + tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, ss, + temptype, initial, false, true, + false, &arg->expr->where); gfc_add_modify (&se->pre, size, tmp); tmp = fold_convert (pvoid_type_node, info->data); gfc_add_modify (&se->pre, data, tmp);