Commit 9157ccb2 by Mikael Morin

trans-array.c (gfc_free_ss): Don't free beyond ss rank.

2010-07-17  Mikael Morin  <mikael@gcc.gnu.org>

	* trans-array.c (gfc_free_ss): Don't free beyond ss rank.
	Access subscript through the "dim" field index.
	(gfc_trans_create_temp_array): Access ss info through the "dim" field
	index.
	(gfc_conv_array_index_offset): Ditto.
	(gfc_conv_loop_setup): Ditto.
	(gfc_conv_expr_descriptor): Ditto.
	(gfc_conv_ss_startstride): Ditto.  Update call to
	gfc_conv_section_startstride.
	(gfc_conv_section_startstride): Set values along the array dimension.
	Get array dimension directly from the argument.

From-SVN: r162276
parent 77198d71
2010-07-17 Mikael Morin <mikael@gcc.gnu.org>
* trans-array.c (gfc_free_ss): Don't free beyond ss rank.
Access subscript through the "dim" field index.
(gfc_trans_create_temp_array): Access ss info through the "dim" field
index.
(gfc_conv_array_index_offset): Ditto.
(gfc_conv_loop_setup): Ditto.
(gfc_conv_expr_descriptor): Ditto.
(gfc_conv_ss_startstride): Ditto. Update call to
gfc_conv_section_startstride.
(gfc_conv_section_startstride): Set values along the array dimension.
Get array dimension directly from the argument.
2010-07-15 Jakub Jelinek <jakub@redhat.com> 2010-07-15 Jakub Jelinek <jakub@redhat.com>
* trans.h (gfc_string_to_single_character): New prototype. * trans.h (gfc_string_to_single_character): New prototype.
...@@ -75,7 +89,7 @@ ...@@ -75,7 +89,7 @@
* trans-array.c (gfc_conv_section_upper_bound): Remove * trans-array.c (gfc_conv_section_upper_bound): Remove
(gfc_conv_section_startstride): Don't set the upper bound in the (gfc_conv_section_startstride): Don't set the upper bound in the
vector subscript case. vector subscript case.
(gfc_conv_loop_setup): Don't use gfc_conv_section_upper_bound (gfc_conv_loop_setup): Don't use gfc_conv_section_upper_bound
2010-07-14 Janus Weil <janus@gcc.gnu.org> 2010-07-14 Janus Weil <janus@gcc.gnu.org>
...@@ -200,11 +214,11 @@ ...@@ -200,11 +214,11 @@
* trans-stmt.c (ADD_FIELD): Ditto. * trans-stmt.c (ADD_FIELD): Ditto.
* trans-types.c * trans-types.c
(gfc_get_derived_type): Ditto. Don't create backend_decl for C_PTR's (gfc_get_derived_type): Ditto. Don't create backend_decl for C_PTR's
C_ADDRESS field. C_ADDRESS field.
(gfc_add_field_to_struct_1): Set TYPE_FIELDS(context) instead of (gfc_add_field_to_struct_1): Set TYPE_FIELDS(context) instead of
fieldlist, remove fieldlist from argument list. fieldlist, remove fieldlist from argument list.
(gfc_add_field_to_struct): Update call to gfc_add_field_to_struct_1 (gfc_add_field_to_struct): Update call to gfc_add_field_to_struct_1
and remove fieldlist from argument list. and remove fieldlist from argument list.
(gfc_get_desc_dim_type, gfc_get_array_descriptor_base, (gfc_get_desc_dim_type, gfc_get_array_descriptor_base,
gfc_get_mixed_entry_union): Move setting gfc_get_mixed_entry_union): Move setting
TYPE_FIELDS to gfc_add_field_to_struct_1 and update calls to it. TYPE_FIELDS to gfc_add_field_to_struct_1 and update calls to it.
......
...@@ -434,10 +434,10 @@ gfc_free_ss (gfc_ss * ss) ...@@ -434,10 +434,10 @@ gfc_free_ss (gfc_ss * ss)
switch (ss->type) switch (ss->type)
{ {
case GFC_SS_SECTION: case GFC_SS_SECTION:
for (n = 0; n < GFC_MAX_DIMENSIONS; n++) for (n = 0; n < ss->data.info.dimen; n++)
{ {
if (ss->data.info.subscript[n]) if (ss->data.info.subscript[ss->data.info.dim[n]])
gfc_free_ss_chain (ss->data.info.subscript[n]); gfc_free_ss_chain (ss->data.info.subscript[ss->data.info.dim[n]]);
} }
break; break;
...@@ -762,25 +762,28 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, ...@@ -762,25 +762,28 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
for (n = 0; n < info->dimen; n++) for (n = 0; n < info->dimen; n++)
{ {
dim = info->dim[n];
if (size == NULL_TREE) if (size == NULL_TREE)
{ {
/* For a callee allocated array express the loop bounds in terms /* For a callee allocated array express the loop bounds in terms
of the descriptor fields. */ of the descriptor fields. */
tmp = tmp = fold_build2 (
fold_build2 (MINUS_EXPR, gfc_array_index_type, MINUS_EXPR, gfc_array_index_type,
gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]), gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n])); gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
loop->to[n] = tmp; loop->to[n] = tmp;
continue; continue;
} }
/* Store the stride and bound components in the descriptor. */ /* Store the stride and bound components in the descriptor. */
gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size); gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[dim], size);
gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n], gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[dim],
gfc_index_zero_node); gfc_index_zero_node);
gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], loop->to[n]); gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[dim],
loop->to[n]);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
loop->to[n], gfc_index_one_node); loop->to[n], gfc_index_one_node);
...@@ -2387,7 +2390,8 @@ gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n, ...@@ -2387,7 +2390,8 @@ gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
/* Return the offset for an index. Performs bound checking for elemental /* Return the offset for an index. Performs bound checking for elemental
dimensions. Single element references are processed separately. */ dimensions. Single element references are processed separately.
DIM is the array dimension, I is the loop dimension. */
static tree static tree
gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i, gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
...@@ -2448,14 +2452,14 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i, ...@@ -2448,14 +2452,14 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
/* Scalarized dimension. */ /* Scalarized dimension. */
gcc_assert (info && se->loop); gcc_assert (info && se->loop);
/* Multiply the loop variable by the stride and delta. */ /* Multiply the loop variable by the stride and delta. */
index = se->loop->loopvar[i]; index = se->loop->loopvar[i];
if (!integer_onep (info->stride[i])) if (!integer_onep (info->stride[dim]))
index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
info->stride[i]); info->stride[dim]);
if (!integer_zerop (info->delta[i])) if (!integer_zerop (info->delta[dim]))
index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
info->delta[i]); info->delta[dim]);
break; break;
default: default:
...@@ -2467,9 +2471,9 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i, ...@@ -2467,9 +2471,9 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
/* Temporary array or derived type component. */ /* Temporary array or derived type component. */
gcc_assert (se->loop); gcc_assert (se->loop);
index = se->loop->loopvar[se->loop->order[i]]; index = se->loop->loopvar[se->loop->order[i]];
if (!integer_zerop (info->delta[i])) if (!integer_zerop (info->delta[dim]))
index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
index, info->delta[i]); index, info->delta[dim]);
} }
/* Multiply by the stride. */ /* Multiply by the stride. */
...@@ -2967,7 +2971,7 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body) ...@@ -2967,7 +2971,7 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
/* Calculate the lower bound of an array section. */ /* Calculate the lower bound of an array section. */
static void static void
gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n) gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
{ {
gfc_expr *start; gfc_expr *start;
gfc_expr *end; gfc_expr *end;
...@@ -2975,19 +2979,17 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n) ...@@ -2975,19 +2979,17 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
tree desc; tree desc;
gfc_se se; gfc_se se;
gfc_ss_info *info; gfc_ss_info *info;
int dim;
gcc_assert (ss->type == GFC_SS_SECTION); gcc_assert (ss->type == GFC_SS_SECTION);
info = &ss->data.info; info = &ss->data.info;
dim = info->dim[n];
if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
{ {
/* We use a zero-based index to access the vector. */ /* We use a zero-based index to access the vector. */
info->start[n] = gfc_index_zero_node; info->start[dim] = gfc_index_zero_node;
info->stride[n] = gfc_index_one_node; info->stride[dim] = gfc_index_one_node;
info->end[n] = NULL; info->end[dim] = NULL;
return; return;
} }
...@@ -3005,14 +3007,14 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n) ...@@ -3005,14 +3007,14 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
gfc_init_se (&se, NULL); gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, start, gfc_array_index_type); gfc_conv_expr_type (&se, start, gfc_array_index_type);
gfc_add_block_to_block (&loop->pre, &se.pre); gfc_add_block_to_block (&loop->pre, &se.pre);
info->start[n] = se.expr; info->start[dim] = se.expr;
} }
else else
{ {
/* No lower bound specified so use the bound of the array. */ /* No lower bound specified so use the bound of the array. */
info->start[n] = gfc_conv_array_lbound (desc, dim); info->start[dim] = gfc_conv_array_lbound (desc, dim);
} }
info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre); info->start[dim] = gfc_evaluate_now (info->start[dim], &loop->pre);
/* Similarly calculate the end. Although this is not used in the /* Similarly calculate the end. Although this is not used in the
scalarizer, it is needed when checking bounds and where the end scalarizer, it is needed when checking bounds and where the end
...@@ -3023,24 +3025,24 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n) ...@@ -3023,24 +3025,24 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
gfc_init_se (&se, NULL); gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, end, gfc_array_index_type); gfc_conv_expr_type (&se, end, gfc_array_index_type);
gfc_add_block_to_block (&loop->pre, &se.pre); gfc_add_block_to_block (&loop->pre, &se.pre);
info->end[n] = se.expr; info->end[dim] = se.expr;
} }
else else
{ {
/* No upper bound specified so use the bound of the array. */ /* No upper bound specified so use the bound of the array. */
info->end[n] = gfc_conv_array_ubound (desc, dim); info->end[dim] = gfc_conv_array_ubound (desc, dim);
} }
info->end[n] = gfc_evaluate_now (info->end[n], &loop->pre); info->end[dim] = gfc_evaluate_now (info->end[dim], &loop->pre);
/* Calculate the stride. */ /* Calculate the stride. */
if (stride == NULL) if (stride == NULL)
info->stride[n] = gfc_index_one_node; info->stride[dim] = gfc_index_one_node;
else else
{ {
gfc_init_se (&se, NULL); gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, stride, gfc_array_index_type); gfc_conv_expr_type (&se, stride, gfc_array_index_type);
gfc_add_block_to_block (&loop->pre, &se.pre); gfc_add_block_to_block (&loop->pre, &se.pre);
info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre); info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
} }
} }
...@@ -3105,7 +3107,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3105,7 +3107,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter); gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
for (n = 0; n < ss->data.info.dimen; n++) for (n = 0; n < ss->data.info.dimen; n++)
gfc_conv_section_startstride (loop, ss, n); gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n]);
break; break;
case GFC_SS_INTRINSIC: case GFC_SS_INTRINSIC:
...@@ -3180,11 +3182,10 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3180,11 +3182,10 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
check_upper = true; check_upper = true;
/* Zero stride is not allowed. */ /* Zero stride is not allowed. */
tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[n], tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[dim],
gfc_index_zero_node); gfc_index_zero_node);
asprintf (&msg, "Zero stride is not allowed, for dimension %d " asprintf (&msg, "Zero stride is not allowed, for dimension %d "
"of array '%s'", info->dim[n]+1, "of array '%s'", dim + 1, ss->expr->symtree->name);
ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp, &inner, gfc_trans_runtime_check (true, false, tmp, &inner,
&ss->expr->where, msg); &ss->expr->where, msg);
gfc_free (msg); gfc_free (msg);
...@@ -3192,27 +3193,27 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3192,27 +3193,27 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
desc = ss->data.info.descriptor; desc = ss->data.info.descriptor;
/* This is the run-time equivalent of resolve.c's /* This is the run-time equivalent of resolve.c's
check_dimension(). The logical is more readable there check_dimension(). The logical is more readable there
than it is here, with all the trees. */ than it is here, with all the trees. */
lbound = gfc_conv_array_lbound (desc, dim); lbound = gfc_conv_array_lbound (desc, dim);
end = info->end[n]; end = info->end[dim];
if (check_upper) if (check_upper)
ubound = gfc_conv_array_ubound (desc, dim); ubound = gfc_conv_array_ubound (desc, dim);
else else
ubound = NULL; ubound = NULL;
/* non_zerosized is true when the selected range is not /* non_zerosized is true when the selected range is not
empty. */ empty. */
stride_pos = fold_build2 (GT_EXPR, boolean_type_node, stride_pos = fold_build2 (GT_EXPR, boolean_type_node,
info->stride[n], gfc_index_zero_node); info->stride[dim], gfc_index_zero_node);
tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[n], tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[dim],
end); end);
stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
stride_pos, tmp); stride_pos, tmp);
stride_neg = fold_build2 (LT_EXPR, boolean_type_node, stride_neg = fold_build2 (LT_EXPR, boolean_type_node,
info->stride[n], gfc_index_zero_node); info->stride[dim], gfc_index_zero_node);
tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[n], tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[dim],
end); end);
stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
stride_neg, tmp); stride_neg, tmp);
...@@ -3225,41 +3226,41 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3225,41 +3226,41 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
error message. */ error message. */
if (check_upper) if (check_upper)
{ {
tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp = fold_build2 (LT_EXPR, boolean_type_node,
info->start[n], lbound); info->start[dim], lbound);
tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
non_zerosized, tmp); non_zerosized, tmp);
tmp2 = fold_build2 (GT_EXPR, boolean_type_node, tmp2 = fold_build2 (GT_EXPR, boolean_type_node,
info->start[n], ubound); info->start[dim], ubound);
tmp2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, tmp2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
non_zerosized, tmp2); non_zerosized, tmp2);
asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
"outside of expected range (%%ld:%%ld)", "outside of expected range (%%ld:%%ld)",
info->dim[n]+1, ss->expr->symtree->name); dim + 1, ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp, &inner, gfc_trans_runtime_check (true, false, tmp, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
fold_convert (long_integer_type_node, info->start[n]), fold_convert (long_integer_type_node, info->start[dim]),
fold_convert (long_integer_type_node, lbound), fold_convert (long_integer_type_node, lbound),
fold_convert (long_integer_type_node, ubound)); fold_convert (long_integer_type_node, ubound));
gfc_trans_runtime_check (true, false, tmp2, &inner, gfc_trans_runtime_check (true, false, tmp2, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
fold_convert (long_integer_type_node, info->start[n]), fold_convert (long_integer_type_node, info->start[dim]),
fold_convert (long_integer_type_node, lbound), fold_convert (long_integer_type_node, lbound),
fold_convert (long_integer_type_node, ubound)); fold_convert (long_integer_type_node, ubound));
gfc_free (msg); gfc_free (msg);
} }
else else
{ {
tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp = fold_build2 (LT_EXPR, boolean_type_node,
info->start[n], lbound); info->start[dim], lbound);
tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
non_zerosized, tmp); non_zerosized, tmp);
asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
"below lower bound of %%ld", "below lower bound of %%ld",
info->dim[n]+1, ss->expr->symtree->name); dim + 1, ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp, &inner, gfc_trans_runtime_check (true, false, tmp, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
fold_convert (long_integer_type_node, info->start[n]), fold_convert (long_integer_type_node, info->start[dim]),
fold_convert (long_integer_type_node, lbound)); fold_convert (long_integer_type_node, lbound));
gfc_free (msg); gfc_free (msg);
} }
...@@ -3269,9 +3270,9 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3269,9 +3270,9 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
and check it against both lower and upper bounds. */ and check it against both lower and upper bounds. */
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end, tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
info->start[n]); info->start[dim]);
tmp = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp, tmp = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp,
info->stride[n]); info->stride[dim]);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end, tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
tmp); tmp);
tmp2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, lbound); tmp2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, lbound);
...@@ -3283,8 +3284,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3283,8 +3284,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
tmp3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, tmp3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
non_zerosized, tmp3); non_zerosized, tmp3);
asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
"outside of expected range (%%ld:%%ld)", "outside of expected range (%%ld:%%ld)",
info->dim[n]+1, ss->expr->symtree->name); dim + 1, ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp2, &inner, gfc_trans_runtime_check (true, false, tmp2, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
fold_convert (long_integer_type_node, tmp), fold_convert (long_integer_type_node, tmp),
...@@ -3300,32 +3301,32 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) ...@@ -3300,32 +3301,32 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
else else
{ {
asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' " asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
"below lower bound of %%ld", "below lower bound of %%ld",
info->dim[n]+1, ss->expr->symtree->name); dim + 1, ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp2, &inner, gfc_trans_runtime_check (true, false, tmp2, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
fold_convert (long_integer_type_node, tmp), fold_convert (long_integer_type_node, tmp),
fold_convert (long_integer_type_node, lbound)); fold_convert (long_integer_type_node, lbound));
gfc_free (msg); gfc_free (msg);
} }
/* Check the section sizes match. */ /* Check the section sizes match. */
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end, tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
info->start[n]); info->start[dim]);
tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp, tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
info->stride[n]); info->stride[dim]);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
gfc_index_one_node, tmp); gfc_index_one_node, tmp);
tmp = fold_build2 (MAX_EXPR, gfc_array_index_type, tmp, tmp = fold_build2 (MAX_EXPR, gfc_array_index_type, tmp,
build_int_cst (gfc_array_index_type, 0)); build_int_cst (gfc_array_index_type, 0));
/* We remember the size of the first section, and check all the /* We remember the size of the first section, and check all the
others against this. */ others against this. */
if (size[n]) if (size[n])
{ {
tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]); tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
asprintf (&msg, "Array bound mismatch for dimension %d " asprintf (&msg, "Array bound mismatch for dimension %d "
"of array '%s' (%%ld/%%ld)", "of array '%s' (%%ld/%%ld)",
info->dim[n]+1, ss->expr->symtree->name); dim + 1, ss->expr->symtree->name);
gfc_trans_runtime_check (true, false, tmp3, &inner, gfc_trans_runtime_check (true, false, tmp3, &inner,
&ss->expr->where, msg, &ss->expr->where, msg,
...@@ -3517,7 +3518,7 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest, ...@@ -3517,7 +3518,7 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
void void
gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
{ {
int n; int n, dim, spec_dim;
gfc_ss_info *info; gfc_ss_info *info;
gfc_ss_info *specinfo; gfc_ss_info *specinfo;
gfc_ss *ss; gfc_ss *ss;
...@@ -3533,14 +3534,34 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3533,14 +3534,34 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
loopspec[n] = NULL; loopspec[n] = NULL;
dynamic[n] = false; dynamic[n] = false;
/* We use one SS term, and use that to determine the bounds of the /* We use one SS term, and use that to determine the bounds of the
loop for this dimension. We try to pick the simplest term. */ loop for this dimension. We try to pick the simplest term. */
for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
{ {
if (ss->type == GFC_SS_SCALAR || ss->type == GFC_SS_REFERENCE)
continue;
info = &ss->data.info;
dim = info->dim[n];
if (loopspec[n] != NULL)
{
specinfo = &loopspec[n]->data.info;
spec_dim = specinfo->dim[n];
}
else
{
/* Silence unitialized warnings. */
specinfo = NULL;
spec_dim = 0;
}
if (ss->shape) if (ss->shape)
{ {
gcc_assert (ss->shape[dim]);
/* The frontend has worked out the size for us. */ /* The frontend has worked out the size for us. */
if (!loopspec[n] || !loopspec[n]->shape if (!loopspec[n]
|| !integer_zerop (loopspec[n]->data.info.start[n])) || !loopspec[n]->shape
|| !integer_zerop (specinfo->start[spec_dim]))
/* Prefer zero-based descriptors if possible. */ /* Prefer zero-based descriptors if possible. */
loopspec[n] = ss; loopspec[n] = ss;
continue; continue;
...@@ -3567,22 +3588,16 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3567,22 +3588,16 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
/* TODO: Pick the best bound if we have a choice between a /* TODO: Pick the best bound if we have a choice between a
function and something else. */ function and something else. */
if (ss->type == GFC_SS_FUNCTION) if (ss->type == GFC_SS_FUNCTION)
{ {
loopspec[n] = ss; loopspec[n] = ss;
continue; continue;
} }
if (ss->type != GFC_SS_SECTION) if (ss->type != GFC_SS_SECTION)
continue; continue;
if (loopspec[n]) if (!loopspec[n])
specinfo = &loopspec[n]->data.info;
else
specinfo = NULL;
info = &ss->data.info;
if (!specinfo)
loopspec[n] = ss; loopspec[n] = ss;
/* Criteria for choosing a loop specifier (most important first): /* Criteria for choosing a loop specifier (most important first):
doesn't need realloc doesn't need realloc
...@@ -3593,14 +3608,14 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3593,14 +3608,14 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
*/ */
else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n]) else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
loopspec[n] = ss; loopspec[n] = ss;
else if (integer_onep (info->stride[n]) else if (integer_onep (info->stride[dim])
&& !integer_onep (specinfo->stride[n])) && !integer_onep (specinfo->stride[spec_dim]))
loopspec[n] = ss; loopspec[n] = ss;
else if (INTEGER_CST_P (info->stride[n]) else if (INTEGER_CST_P (info->stride[dim])
&& !INTEGER_CST_P (specinfo->stride[n])) && !INTEGER_CST_P (specinfo->stride[spec_dim]))
loopspec[n] = ss; loopspec[n] = ss;
else if (INTEGER_CST_P (info->start[n]) else if (INTEGER_CST_P (info->start[dim])
&& !INTEGER_CST_P (specinfo->start[n])) && !INTEGER_CST_P (specinfo->start[spec_dim]))
loopspec[n] = ss; loopspec[n] = ss;
/* We don't work out the upper bound. /* We don't work out the upper bound.
else if (INTEGER_CST_P (info->finish[n]) else if (INTEGER_CST_P (info->finish[n])
...@@ -3613,26 +3628,27 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3613,26 +3628,27 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
gcc_assert (loopspec[n]); gcc_assert (loopspec[n]);
info = &loopspec[n]->data.info; info = &loopspec[n]->data.info;
dim = info->dim[n];
/* Set the extents of this range. */ /* Set the extents of this range. */
cshape = loopspec[n]->shape; cshape = loopspec[n]->shape;
if (cshape && INTEGER_CST_P (info->start[n]) if (cshape && INTEGER_CST_P (info->start[dim])
&& INTEGER_CST_P (info->stride[n])) && INTEGER_CST_P (info->stride[dim]))
{ {
loop->from[n] = info->start[n]; loop->from[n] = info->start[dim];
mpz_set (i, cshape[n]); mpz_set (i, cshape[n]);
mpz_sub_ui (i, i, 1); mpz_sub_ui (i, i, 1);
/* To = from + (size - 1) * stride. */ /* To = from + (size - 1) * stride. */
tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind); tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
if (!integer_onep (info->stride[n])) if (!integer_onep (info->stride[dim]))
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
tmp, info->stride[n]); tmp, info->stride[dim]);
loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type, loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
loop->from[n], tmp); loop->from[n], tmp);
} }
else else
{ {
loop->from[n] = info->start[n]; loop->from[n] = info->start[dim];
switch (loopspec[n]->type) switch (loopspec[n]->type)
{ {
case GFC_SS_CONSTRUCTOR: case GFC_SS_CONSTRUCTOR:
...@@ -3644,7 +3660,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3644,7 +3660,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
case GFC_SS_SECTION: case GFC_SS_SECTION:
/* Use the end expression if it exists and is not constant, /* Use the end expression if it exists and is not constant,
so that it is only evaluated once. */ so that it is only evaluated once. */
loop->to[n] = info->end[n]; loop->to[n] = info->end[dim];
break; break;
case GFC_SS_FUNCTION: case GFC_SS_FUNCTION:
...@@ -3658,20 +3674,20 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3658,20 +3674,20 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
} }
/* Transform everything so we have a simple incrementing variable. */ /* Transform everything so we have a simple incrementing variable. */
if (integer_onep (info->stride[n])) if (integer_onep (info->stride[dim]))
info->delta[n] = gfc_index_zero_node; info->delta[dim] = gfc_index_zero_node;
else else
{ {
/* Set the delta for this section. */ /* Set the delta for this section. */
info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre); info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre);
/* Number of iterations is (end - start + step) / step. /* Number of iterations is (end - start + step) / step.
with start = 0, this simplifies to with start = 0, this simplifies to
last = end / step; last = end / step;
for (i = 0; i<=last; i++){...}; */ for (i = 0; i<=last; i++){...}; */
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
loop->to[n], loop->from[n]); loop->to[n], loop->from[n]);
tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type,
tmp, info->stride[n]); tmp, info->stride[dim]);
tmp = fold_build2 (MAX_EXPR, gfc_array_index_type, tmp, tmp = fold_build2 (MAX_EXPR, gfc_array_index_type, tmp,
build_int_cst (gfc_array_index_type, -1)); build_int_cst (gfc_array_index_type, -1));
loop->to[n] = gfc_evaluate_now (tmp, &loop->pre); loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
...@@ -3732,18 +3748,20 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) ...@@ -3732,18 +3748,20 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
/* If we are specifying the range the delta is already set. */ /* If we are specifying the range the delta is already set. */
if (loopspec[n] != ss) if (loopspec[n] != ss)
{ {
dim = ss->data.info.dim[n];
/* Calculate the offset relative to the loop variable. /* Calculate the offset relative to the loop variable.
First multiply by the stride. */ First multiply by the stride. */
tmp = loop->from[n]; tmp = loop->from[n];
if (!integer_onep (info->stride[n])) if (!integer_onep (info->stride[dim]))
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
tmp, info->stride[n]); tmp, info->stride[dim]);
/* Then subtract this from our starting value. */ /* Then subtract this from our starting value. */
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
info->start[n], tmp); info->start[dim], tmp);
info->delta[n] = gfc_evaluate_now (tmp, &loop->pre); info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre);
} }
} }
} }
...@@ -5296,7 +5314,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) ...@@ -5296,7 +5314,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
gcc_assert (info->dim[dim] == n); gcc_assert (info->dim[dim] == n);
/* Evaluate and remember the start of the section. */ /* Evaluate and remember the start of the section. */
start = info->start[dim]; start = info->start[n];
stride = gfc_evaluate_now (stride, &loop.pre); stride = gfc_evaluate_now (stride, &loop.pre);
} }
...@@ -5343,11 +5361,11 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) ...@@ -5343,11 +5361,11 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
/* Multiply the stride by the section stride to get the /* Multiply the stride by the section stride to get the
total stride. */ total stride. */
stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
stride, info->stride[dim]); stride, info->stride[n]);
if (se->direct_byref if (se->direct_byref
&& info->ref && info->ref
&& info->ref->u.ar.type != AR_FULL) && info->ref->u.ar.type != AR_FULL)
{ {
base = fold_build2 (MINUS_EXPR, TREE_TYPE (base), base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
base, stride); base, stride);
......
...@@ -114,8 +114,8 @@ typedef struct gfc_ss_info ...@@ -114,8 +114,8 @@ typedef struct gfc_ss_info
tree stride[GFC_MAX_DIMENSIONS]; tree stride[GFC_MAX_DIMENSIONS];
tree delta[GFC_MAX_DIMENSIONS]; tree delta[GFC_MAX_DIMENSIONS];
/* Translation from scalarizer dimensions to actual dimensions. /* Translation from loop dimensions to actual dimensions.
actual = dim[scalarizer] */ actual_dim = dim[loop_dim] */
int dim[GFC_MAX_DIMENSIONS]; int dim[GFC_MAX_DIMENSIONS];
} }
gfc_ss_info; gfc_ss_info;
......
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