https://gcc.gnu.org/g:edca835525ecdb57ab70f12a9fd7d7f06fbba5c9
commit edca835525ecdb57ab70f12a9fd7d7f06fbba5c9 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Jul 16 17:55:29 2025 +0200 Extraction gfc_conv_remap_descriptor Diff: --- gcc/fortran/trans-descriptor.cc | 119 ++++++++++++++++++++++++++++++++++++++-- gcc/fortran/trans-descriptor.h | 3 + gcc/fortran/trans-expr.cc | 110 +------------------------------------ 3 files changed, 120 insertions(+), 112 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index b9f593377c9d..726acb40c8c8 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -944,8 +944,8 @@ gfc_nullify_descriptor (stmtblock_t *block, tree descr) } -static int -descriptor_rank (tree descriptor) +int +gfc_descriptor_rank (tree descriptor) { tree dim = gfc_get_descriptor_dimension (descriptor); tree dim_type = TREE_TYPE (dim); @@ -965,8 +965,8 @@ void gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc, bool assumed_rank_lhs) { - int lhs_rank = descriptor_rank (lhs_desc); - int rhs_rank = descriptor_rank (rhs_desc); + int lhs_rank = gfc_descriptor_rank (lhs_desc); + int rhs_rank = gfc_descriptor_rank (rhs_desc); tree desc; if (assumed_rank_lhs || lhs_rank == rhs_rank) @@ -1003,3 +1003,114 @@ gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc, gfc_class_array_data_assign (&block, lhs_desc, desc, true); } + +void +gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, + int src_rank, const gfc_array_spec &as) +{ + int dest_rank = gfc_descriptor_rank (dest); + + /* Set dtype. */ + gfc_conv_descriptor_dtype_set (block, dest, gfc_get_dtype (TREE_TYPE (src))); + + /* 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 (as.lower[dim] && as.upper[dim]); + + /* Convert declared bounds. */ + gfc_init_se (&lower_se, NULL); + gfc_init_se (&upper_se, NULL); + gfc_conv_expr (&lower_se, as.lower[dim]); + gfc_conv_expr (&upper_se, as.upper[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); + } +} + + +void +gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, + int src_rank, const gfc_array_ref &ar) +{ + gfc_array_spec as; + + array_ref_to_array_spec (ar, as); + + gfc_conv_remap_descriptor (block, dest, src, src_rank, as); +} + diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 5319294d4f18..1d3c650b32ec 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -104,5 +104,8 @@ void gfc_conv_shift_descriptor (stmtblock_t *, tree, const gfc_array_ref &); /* Build a null array descriptor constructor. */ void gfc_nullify_descriptor (stmtblock_t *block, tree); void gfc_copy_sequence_descriptor (stmtblock_t &, tree, tree, bool); +int gfc_descriptor_rank (tree); +void gfc_conv_remap_descriptor (stmtblock_t *, tree, tree, int, + const gfc_array_ref &as); #endif /* GFC_TRANS_DESCRIPTOR_H */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 35f2ae28be90..006173f80752 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -11217,7 +11217,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) @@ -11226,113 +11225,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) 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, rse.expr, expr2->rank, + remap->u.ar); } else /* Bounds remapping. Just shift the lower bounds. */