https://gcc.gnu.org/g:ff34c5d59b058d43f9150afd888e865a2f393fed
commit ff34c5d59b058d43f9150afd888e865a2f393fed Author: Mikael Morin <mik...@gcc.gnu.org> Date: Thu Jan 9 21:38:39 2025 +0100 Extraction fonction fcncall_realloc_result Diff: --- gcc/fortran/trans-array.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++ gcc/fortran/trans-array.h | 1 + gcc/fortran/trans-expr.cc | 35 +------------------------ 3 files changed, 66 insertions(+), 34 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 898930634ad1..7d43a8c000d3 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1451,6 +1451,70 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, } +class conditional_lb +{ + tree cond; +public: + conditional_lb (tree arg_cond) + : cond (arg_cond) { } + + tree lower_bound (tree src, int n) const { + tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[n]); + lbound = fold_build3_loc (input_location, COND_EXPR, + gfc_array_index_type, cond, + gfc_index_one_node, lbound); + return lbound; + } +}; + + +static void +gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src, + int rank, const conditional_lb &lb) +{ + tree tmp = gfc_conv_descriptor_data_get (src); + gfc_conv_descriptor_data_set (block, dest, tmp); + + tree offset = gfc_index_zero_node; + for (int n = 0 ; n < rank; n++) + { + tree lbound; + + lbound = lb.lower_bound (dest, n); + lbound = gfc_evaluate_now (lbound, block); + + tmp = gfc_conv_descriptor_ubound_get (src, gfc_rank_cst[n]); + tmp = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, tmp, lbound); + gfc_conv_descriptor_lbound_set (block, dest, + gfc_rank_cst[n], lbound); + gfc_conv_descriptor_ubound_set (block, dest, + gfc_rank_cst[n], tmp); + + /* Set stride and accumulate the offset. */ + tmp = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[n]); + gfc_conv_descriptor_stride_set (block, dest, + gfc_rank_cst[n], tmp); + tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, lbound, tmp); + offset = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, offset, tmp); + offset = gfc_evaluate_now (offset, block); + } + + gfc_conv_descriptor_offset_set (block, dest, offset); +} + + +void +gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src, + int rank, tree zero_cond) +{ + gfc_conv_shift_descriptor (block, dest, src, rank, + conditional_lb (zero_cond)); +} + + static bool keep_descriptor_lower_bound (gfc_expr *e) { diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 8df55c2c00a5..571322ae11ff 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -216,6 +216,7 @@ tree gfc_get_cfi_dim_sm (tree, tree); /* Shift lower bound of descriptor, updating ubound and offset. */ void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree); void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &); +void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree); /* Add pre-loop scalarization code for intrinsic functions which require special handling. */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index c50b1e05cdbd..b65474a0c919 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11628,9 +11628,6 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) tmp = gfc_call_free (tmp); gfc_add_expr_to_block (&se->post, tmp); - tmp = gfc_conv_descriptor_data_get (res_desc); - gfc_conv_descriptor_data_set (&se->post, desc, tmp); - /* Check that the shapes are the same between lhs and expression. The evaluation of the shape is done in 'shape_block' to avoid unitialized warnings from the lhs bounds. */ @@ -11674,37 +11671,7 @@ fcncall_realloc_result (gfc_se *se, int rank, tree dtype) /* Now reset the bounds returned from the function call to bounds based on the lhs lbounds, except where the lhs is not allocated or the shapes of 'variable and 'expr' are different. Set the offset accordingly. */ - offset = gfc_index_zero_node; - for (n = 0 ; n < rank; n++) - { - tree lbound; - - lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]); - lbound = fold_build3_loc (input_location, COND_EXPR, - gfc_array_index_type, zero_cond, - gfc_index_one_node, lbound); - lbound = gfc_evaluate_now (lbound, &se->post); - - tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, tmp, lbound); - gfc_conv_descriptor_lbound_set (&se->post, desc, - gfc_rank_cst[n], lbound); - gfc_conv_descriptor_ubound_set (&se->post, desc, - gfc_rank_cst[n], tmp); - - /* Set stride and accumulate the offset. */ - tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]); - gfc_conv_descriptor_stride_set (&se->post, desc, - gfc_rank_cst[n], tmp); - tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, lbound, tmp); - offset = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, offset, tmp); - offset = gfc_evaluate_now (offset, &se->post); - } - - gfc_conv_descriptor_offset_set (&se->post, desc, offset); + gfc_conv_shift_descriptor (&se->post, desc, res_desc, rank, zero_cond); }