https://gcc.gnu.org/g:59fe929d5714daedf861da55b5ae30e3530011c6
commit 59fe929d5714daedf861da55b5ae30e3530011c6 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Jan 22 19:02:13 2025 +0100 Introduction gfc_conv_descriptor_extent_get Diff: --- gcc/fortran/trans-array.cc | 84 ++++++++++++++++++++++++++-------------------- gcc/fortran/trans-array.h | 1 + gcc/fortran/trans-expr.cc | 6 +--- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 7afa29746e08..7357626be9a5 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -544,6 +544,51 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc, } +/* Calculate the size of a given array dimension from the bounds. This + is simply (ubound - lbound + 1) if this expression is positive + or 0 if it is negative (pick either one if it is zero). Optionally + (if or_expr is present) OR the (expression != 0) condition to it. */ + +static tree +conv_array_extent_dim (tree lbound, tree ubound, bool maybe_negative, tree* or_expr) +{ + tree res; + tree cond; + + /* Calculate (ubound - lbound + 1). */ + res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + ubound, lbound); + res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res, + gfc_index_one_node); + + /* Check whether the size for this dimension is negative. */ + if (maybe_negative) + { + cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res, + gfc_index_zero_node); + res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond, + gfc_index_zero_node, res); + } + + /* Build OR expression. */ + if (maybe_negative && or_expr) + *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR, + logical_type_node, *or_expr, cond); + + return res; +} + + +tree +gfc_conv_descriptor_extent_get (tree desc, tree dim) +{ + tree ubound = gfc_conv_descriptor_ubound_get (desc, dim); + tree lbound = gfc_conv_descriptor_lbound_get (desc, dim); + + return conv_array_extent_dim (lbound, ubound, false, NULL); +} + + static int get_type_info (const bt &type) { @@ -7111,30 +7156,9 @@ gfc_set_delta (gfc_loopinfo *loop) tree gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr) { - tree res; - tree cond; - - /* Calculate (ubound - lbound + 1). */ - res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - ubound, lbound); - res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res, - gfc_index_one_node); - - /* Check whether the size for this dimension is negative. */ - cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res, - gfc_index_zero_node); - res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond, - gfc_index_zero_node, res); - - /* Build OR expression. */ - if (or_expr) - *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR, - logical_type_node, *or_expr, cond); - - return res; + return conv_array_extent_dim (lbound, ubound, true, or_expr); } - /* For an array descriptor, get the total number of elements. This is just the product of the extents along from_dim to to_dim. */ @@ -7148,14 +7172,7 @@ gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim) for (dim = from_dim; dim < to_dim; ++dim) { - tree lbound; - tree ubound; - tree extent; - - lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]); - ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]); - - extent = gfc_conv_array_extent_dim (lbound, ubound, NULL); + tree extent = gfc_conv_descriptor_extent_get (desc, gfc_rank_cst[dim]); res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, res, extent); } @@ -10543,12 +10560,7 @@ gfc_full_array_size (stmtblock_t *block, tree decl, int rank) tree nelems; tree tmp; idx = gfc_rank_cst[rank - 1]; - nelems = gfc_conv_descriptor_ubound_get (decl, idx); - tmp = gfc_conv_descriptor_lbound_get (decl, idx); - tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - nelems, tmp); - tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - tmp, gfc_index_one_node); + tmp = gfc_conv_descriptor_extent_get (decl, idx); tmp = gfc_evaluate_now (tmp, block); nelems = gfc_conv_descriptor_stride_get (decl, idx); diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index f9988a5fd109..1d694989b4c3 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -194,6 +194,7 @@ tree gfc_get_descriptor_dimension (tree); tree gfc_conv_descriptor_stride_get (tree, tree); tree gfc_conv_descriptor_lbound_get (tree, tree); tree gfc_conv_descriptor_ubound_get (tree, tree); +tree gfc_conv_descriptor_extent_get (tree, tree); tree gfc_conv_descriptor_token (tree); void gfc_conv_descriptor_data_set (stmtblock_t *, tree, tree); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 84c30321d431..84111f5e3d3d 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6259,11 +6259,7 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) tmp = gfc_index_zero_node; gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp); /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */ - tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - gfc_conv_descriptor_ubound_get (gfc, idx), - gfc_conv_descriptor_lbound_get (gfc, idx)); - tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - tmp, gfc_index_one_node); + tmp = gfc_conv_descriptor_extent_get (gfc, idx); gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp); /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */ tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,