https://gcc.gnu.org/g:33e9f1d00e9cafffe6065d554bdce78300a65cd0
commit 33e9f1d00e9cafffe6065d554bdce78300a65cd0 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Jul 23 17:07:24 2025 +0200 Extraction gfc_conv_remap_descriptor Diff: --- gcc/fortran/trans-descriptor.cc | 105 +++++++++++++++++++++++++++++++++++++ gcc/fortran/trans-descriptor.h | 2 + gcc/fortran/trans-expr.cc | 111 +--------------------------------------- 3 files changed, 109 insertions(+), 109 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 4a78aadc697e..d9a817c2e1e8 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1226,3 +1226,108 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, conv_shift_descriptor (block, desc, as); } + + +void +gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, int dest_rank, + tree src, int src_rank, gfc_array_ref *ar) +{ + /* Set dtype. */ + gfc_conv_descriptor_dtype_set (block, dest, + gfc_get_dtype (TREE_TYPE (dest))); + + /* Copy data pointer. */ + gfc_conv_descriptor_data_set (block, dest, + gfc_conv_descriptor_data_get (src)); + + /* Copy the span. */ + tree span; + if (VAR_P (src) + && GFC_DECL_PTR_ARRAY_P (src)) + span = gfc_conv_descriptor_span_get (src); + else + { + tree tmp = TREE_TYPE (src); + tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp)); + span = fold_convert (gfc_array_index_type, tmp); + } + gfc_conv_descriptor_span_set (block, dest, span); + + /* Copy offset but adjust it such that it would correspond + to a lbound of zero. */ + if (src_rank == -1) + gfc_conv_descriptor_offset_set (block, dest, + gfc_index_zero_node); + else + { + tree offs = gfc_conv_descriptor_offset_get (src); + for (int dim = 0; dim < src_rank; ++dim) + { + tree stride = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[dim]); + tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[dim]); + tree tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, stride, lbound); + offs = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, offs, tmp); + } + gfc_conv_descriptor_offset_set (block, dest, offs); + } + + /* Set the bounds as declared for the LHS and calculate strides as + well as another offset update accordingly. */ + tree stride = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[0]); + for (int dim = 0; dim < dest_rank; ++dim) + { + gfc_se lower_se; + gfc_se upper_se; + + gcc_assert (ar->start[dim] && ar->end[dim]); + + if (ar->start[dim]->expr_type != EXPR_CONSTANT + || ar->start[dim]->expr_type != EXPR_VARIABLE) + gfc_resolve_expr (ar->start[dim]); + if (ar->end[dim]->expr_type != EXPR_CONSTANT + || ar->end[dim]->expr_type != EXPR_VARIABLE) + gfc_resolve_expr (ar->end[dim]); + + /* Convert declared bounds. */ + gfc_init_se (&lower_se, NULL); + gfc_init_se (&upper_se, NULL); + gfc_conv_expr (&lower_se, ar->start[dim]); + gfc_conv_expr (&upper_se, ar->end[dim]); + + gfc_add_block_to_block (block, &lower_se.pre); + gfc_add_block_to_block (block, &upper_se.pre); + + tree lbound = fold_convert (gfc_array_index_type, lower_se.expr); + tree ubound = fold_convert (gfc_array_index_type, upper_se.expr); + + lbound = gfc_evaluate_now (lbound, block); + ubound = gfc_evaluate_now (ubound, block); + + gfc_add_block_to_block (block, &lower_se.post); + gfc_add_block_to_block (block, &upper_se.post); + + /* Set bounds in descriptor. */ + gfc_conv_descriptor_lbound_set (block, dest, gfc_rank_cst[dim], lbound); + gfc_conv_descriptor_ubound_set (block, dest, gfc_rank_cst[dim], ubound); + + /* Set stride. */ + stride = gfc_evaluate_now (stride, block); + gfc_conv_descriptor_stride_set (block, dest, gfc_rank_cst[dim], stride); + + /* Update offset. */ + tree offs = gfc_conv_descriptor_offset_get (dest); + tree tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, lbound, stride); + offs = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, offs, tmp); + offs = gfc_evaluate_now (offs, block); + gfc_conv_descriptor_offset_set (block, dest, offs); + + /* Update stride. */ + tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL); + stride = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, stride, tmp); + } +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index c120a2f2cf5a..a356628e6755 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -105,6 +105,8 @@ void gfc_init_descriptor_variable (stmtblock_t *block, gfc_symbol *sym, tree des void gfc_conv_shift_descriptor_lbound (stmtblock_t *, tree, int, tree); void gfc_conv_shift_descriptor (stmtblock_t *, tree, int); void gfc_conv_shift_descriptor (stmtblock_t *, tree, const gfc_array_ref &); +void gfc_conv_remap_descriptor (stmtblock_t *, tree, int, tree, int, + gfc_array_ref *); void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree); void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree, gfc_expr *); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index e111a7347dd9..05840c271037 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11140,7 +11140,6 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) /* If we do bounds remapping, update LHS descriptor accordingly. */ if (remap) { - int dim; gcc_assert (remap->u.ar.dimen == expr1->rank); if (rank_remap) @@ -11148,114 +11147,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) /* Do rank remapping. We already have the RHS's descriptor converted in rse and now have to build the correct LHS descriptor for it. */ - - tree data, span; - tree offs, stride; - tree lbound, ubound; - - /* Set dtype. */ - gfc_conv_descriptor_dtype_set (&block, desc, - gfc_get_dtype (TREE_TYPE (desc))); - - /* Copy data pointer. */ - data = gfc_conv_descriptor_data_get (rse.expr); - gfc_conv_descriptor_data_set (&block, desc, data); - - /* Copy the span. */ - if (VAR_P (rse.expr) - && GFC_DECL_PTR_ARRAY_P (rse.expr)) - span = gfc_conv_descriptor_span_get (rse.expr); - else - { - tmp = TREE_TYPE (rse.expr); - tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp)); - span = fold_convert (gfc_array_index_type, tmp); - } - gfc_conv_descriptor_span_set (&block, desc, span); - - /* Copy offset but adjust it such that it would correspond - to a lbound of zero. */ - if (expr2->rank == -1) - gfc_conv_descriptor_offset_set (&block, desc, - gfc_index_zero_node); - else - { - offs = gfc_conv_descriptor_offset_get (rse.expr); - for (dim = 0; dim < expr2->rank; ++dim) - { - stride = gfc_conv_descriptor_stride_get (rse.expr, - gfc_rank_cst[dim]); - lbound = gfc_conv_descriptor_lbound_get (rse.expr, - gfc_rank_cst[dim]); - tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, stride, - lbound); - offs = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, offs, tmp); - } - gfc_conv_descriptor_offset_set (&block, desc, offs); - } - /* Set the bounds as declared for the LHS and calculate strides as - well as another offset update accordingly. */ - stride = gfc_conv_descriptor_stride_get (rse.expr, - gfc_rank_cst[0]); - for (dim = 0; dim < expr1->rank; ++dim) - { - gfc_se lower_se; - gfc_se upper_se; - - gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]); - - if (remap->u.ar.start[dim]->expr_type != EXPR_CONSTANT - || remap->u.ar.start[dim]->expr_type != EXPR_VARIABLE) - gfc_resolve_expr (remap->u.ar.start[dim]); - if (remap->u.ar.end[dim]->expr_type != EXPR_CONSTANT - || remap->u.ar.end[dim]->expr_type != EXPR_VARIABLE) - gfc_resolve_expr (remap->u.ar.end[dim]); - - /* Convert declared bounds. */ - gfc_init_se (&lower_se, NULL); - gfc_init_se (&upper_se, NULL); - gfc_conv_expr (&lower_se, remap->u.ar.start[dim]); - gfc_conv_expr (&upper_se, remap->u.ar.end[dim]); - - gfc_add_block_to_block (&block, &lower_se.pre); - gfc_add_block_to_block (&block, &upper_se.pre); - - lbound = fold_convert (gfc_array_index_type, lower_se.expr); - ubound = fold_convert (gfc_array_index_type, upper_se.expr); - - lbound = gfc_evaluate_now (lbound, &block); - ubound = gfc_evaluate_now (ubound, &block); - - gfc_add_block_to_block (&block, &lower_se.post); - gfc_add_block_to_block (&block, &upper_se.post); - - /* Set bounds in descriptor. */ - gfc_conv_descriptor_lbound_set (&block, desc, - gfc_rank_cst[dim], lbound); - gfc_conv_descriptor_ubound_set (&block, desc, - gfc_rank_cst[dim], ubound); - - /* Set stride. */ - stride = gfc_evaluate_now (stride, &block); - gfc_conv_descriptor_stride_set (&block, desc, - gfc_rank_cst[dim], stride); - - /* Update offset. */ - offs = gfc_conv_descriptor_offset_get (desc); - tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, lbound, stride); - offs = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, offs, tmp); - offs = gfc_evaluate_now (offs, &block); - gfc_conv_descriptor_offset_set (&block, desc, offs); - - /* Update stride. */ - tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL); - stride = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, stride, tmp); - } + gfc_conv_remap_descriptor (&block, desc, expr1->rank, + rse.expr, expr2->rank, &remap->u.ar); } else /* Bounds remapping. Just shift the lower bounds. */