https://gcc.gnu.org/g:63d697dba1aeb09caca29ebae0ecb5f5375dbbf9
commit 63d697dba1aeb09caca29ebae0ecb5f5375dbbf9 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Thu Feb 13 21:03:54 2025 +0100 Factorisation shift_descriptor Diff: --- gcc/fortran/trans-expr.cc | 76 ++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 8173f07a8328..f9078dd1b694 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -5364,6 +5364,43 @@ gfc_apply_interface_mapping (gfc_interface_mapping * mapping, } +static void +shift_descriptor (stmtblock_t *block, tree desc, int rank, + tree lbound[GFC_MAX_DIMENSIONS], + tree ubound[GFC_MAX_DIMENSIONS]) + +{ + tree size = gfc_index_one_node; + tree offset = gfc_index_zero_node; + for (int n = 0; n < rank; n++) + { + tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]); + tmp = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, tmp, + gfc_index_one_node); + gfc_conv_descriptor_ubound_set (block, + desc, + gfc_rank_cst[n], + tmp); + gfc_conv_descriptor_lbound_set (block, + desc, + gfc_rank_cst[n], + gfc_index_one_node); + size = gfc_evaluate_now (size, block); + offset = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + offset, size); + offset = gfc_evaluate_now (offset, block); + tmp = gfc_conv_array_extent_dim (lbound[n], ubound[n], nullptr); + size = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, size, tmp); + } + + gfc_conv_descriptor_offset_set (block, desc, + offset); +} + + /* Returns a reference to a temporary array into which a component of an actual argument derived type array is copied and then returned after the function call. */ @@ -5384,7 +5421,6 @@ gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77, tree tmp_index; tree tmp; tree base_type; - tree size; stmtblock_t body; int n; int dimen; @@ -5635,42 +5671,8 @@ class_array_fcn: /* Determine the offset for pointer formal arguments and set the lbounds to one. */ if (formal_ptr) - { - size = gfc_index_one_node; - offset = gfc_index_zero_node; - for (n = 0; n < dimen; n++) - { - tmp = gfc_conv_descriptor_ubound_get (parmse->expr, - gfc_rank_cst[n]); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, tmp, - gfc_index_one_node); - gfc_conv_descriptor_ubound_set (&parmse->pre, - parmse->expr, - gfc_rank_cst[n], - tmp); - gfc_conv_descriptor_lbound_set (&parmse->pre, - parmse->expr, - gfc_rank_cst[n], - gfc_index_one_node); - size = gfc_evaluate_now (size, &parmse->pre); - offset = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - offset, size); - offset = gfc_evaluate_now (offset, &parmse->pre); - tmp = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - rse.loop->to[n], rse.loop->from[n]); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, - tmp, gfc_index_one_node); - size = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, size, tmp); - } - - gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr, - offset); - } + shift_descriptor (&parmse->pre, parmse->expr, dimen, + rse.loop->from, rse.loop->to); /* We want either the address for the data or the address of the descriptor, depending on the mode of passing array arguments. */