https://gcc.gnu.org/g:29e382e1a33feba288edb915aacda6c6a954ba44
commit 29e382e1a33feba288edb915aacda6c6a954ba44 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Jul 22 12:17:50 2025 +0200 Extraction gfc_set_gfc_from_cfi Diff: --- gcc/fortran/trans-descriptor.cc | 98 +++++++++++++++++++++++++++++++++++++++++ gcc/fortran/trans-descriptor.h | 3 ++ gcc/fortran/trans-expr.cc | 92 +------------------------------------- 3 files changed, 102 insertions(+), 91 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index 4637ec30a3e2..a1ac97d712ea 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -1581,3 +1581,101 @@ gfc_set_subarray_descriptor (stmtblock_t *block, tree descr, tree value, } } + +void +gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, gfc_expr *e, tree rank, + tree gfc_strlen, tree cfi, gfc_symbol *fsym) +{ + stmtblock_t block2; + gfc_init_block (&block2); + if (e->rank == 0) + { + tree tmp = gfc_get_cfi_desc_base_addr (cfi); + gfc_add_modify (block, gfc, fold_convert (TREE_TYPE (gfc), tmp)); + } + else + { + tree tmp = gfc_get_cfi_desc_base_addr (cfi); + gfc_conv_descriptor_data_set (block, gfc, tmp); + + if (fsym->attr.allocatable) + { + /* gfc->span = cfi->elem_len. */ + tmp = fold_convert (gfc_array_index_type, + gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0])); + } + else + { + /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len) + ? cfi->dim[0].sm : cfi->elem_len). */ + tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]); + tree tmp2 = fold_convert (gfc_array_index_type, + gfc_get_cfi_desc_elem_len (cfi)); + tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR, + gfc_array_index_type, tmp, tmp2); + tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, + tmp, gfc_index_zero_node); + tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp, + gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2); + } + gfc_conv_descriptor_span_set (&block2, gfc, tmp); + + /* Calculate offset + set lbound, ubound and stride. */ + gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node); + /* Loop: for (i = 0; i < rank; ++i). */ + tree idx = gfc_create_var (TREE_TYPE (rank), "idx"); + /* Loop body. */ + stmtblock_t loop_body; + gfc_init_block (&loop_body); + /* gfc->dim[i].lbound = ... */ + tmp = gfc_get_cfi_dim_lbound (cfi, idx); + gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp); + + /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */ + tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + gfc_conv_descriptor_lbound_get (gfc, idx), + gfc_index_one_node); + tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, + gfc_get_cfi_dim_extent (cfi, idx), tmp); + gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp); + + /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */ + tmp = gfc_get_cfi_dim_sm (cfi, idx); + tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, + gfc_array_index_type, tmp, + fold_convert (gfc_array_index_type, + gfc_get_cfi_desc_elem_len (cfi))); + gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp); + + /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */ + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + gfc_conv_descriptor_stride_get (gfc, idx), + gfc_conv_descriptor_lbound_get (gfc, idx)); + tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + gfc_conv_descriptor_offset_get (gfc), tmp); + gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp); + /* Generate loop. */ + gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0), + rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1), + gfc_finish_block (&loop_body)); + } + + if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length) + { + tree tmp = fold_convert (gfc_charlen_type_node, + gfc_get_cfi_desc_elem_len (cfi)); + if (e->ts.kind != 1) + tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, + gfc_charlen_type_node, tmp, + build_int_cst (gfc_charlen_type_node, + e->ts.kind)); + gfc_add_modify (&block2, gfc_strlen, tmp); + } + + tree tmp = gfc_get_cfi_desc_base_addr (cfi); + tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, + tmp, null_pointer_node); + tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2), + build_empty_stmt (input_location)); + gfc_add_expr_to_block (block, tmp); +} diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 7b9aedf029c8..958109832f41 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -122,5 +122,8 @@ void gfc_set_contiguous_descriptor (stmtblock_t *, tree, tree, tree); void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree, gfc_expr *, locus *); void gfc_set_subarray_descriptor (stmtblock_t *, tree, tree, gfc_expr *); +void gfc_set_gfc_from_cfi (stmtblock_t *, tree, gfc_expr *, tree, tree, + tree, gfc_symbol *); + #endif /* GFC_TRANS_DESCRIPTOR_H */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 9fef28c9e67e..8d4010559ecd 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -6367,97 +6367,7 @@ done: || fsym->attr.intent == INTENT_IN) goto post_call; - gfc_init_block (&block2); - if (e->rank == 0) - { - tmp = gfc_get_cfi_desc_base_addr (cfi); - gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp)); - } - else - { - tmp = gfc_get_cfi_desc_base_addr (cfi); - gfc_conv_descriptor_data_set (&block, gfc, tmp); - - if (fsym->attr.allocatable) - { - /* gfc->span = cfi->elem_len. */ - tmp = fold_convert (gfc_array_index_type, - gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0])); - } - else - { - /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len) - ? cfi->dim[0].sm : cfi->elem_len). */ - tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]); - tmp2 = fold_convert (gfc_array_index_type, - gfc_get_cfi_desc_elem_len (cfi)); - tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR, - gfc_array_index_type, tmp, tmp2); - tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, - tmp, gfc_index_zero_node); - tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp, - gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2); - } - gfc_conv_descriptor_span_set (&block2, gfc, tmp); - - /* Calculate offset + set lbound, ubound and stride. */ - gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node); - /* Loop: for (i = 0; i < rank; ++i). */ - tree idx = gfc_create_var (TREE_TYPE (rank), "idx"); - /* Loop body. */ - stmtblock_t loop_body; - gfc_init_block (&loop_body); - /* gfc->dim[i].lbound = ... */ - tmp = gfc_get_cfi_dim_lbound (cfi, idx); - gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp); - - /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */ - tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - gfc_conv_descriptor_lbound_get (gfc, idx), - gfc_index_one_node); - tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - gfc_get_cfi_dim_extent (cfi, idx), tmp); - gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp); - - /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */ - tmp = gfc_get_cfi_dim_sm (cfi, idx); - tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, - gfc_array_index_type, tmp, - fold_convert (gfc_array_index_type, - gfc_get_cfi_desc_elem_len (cfi))); - gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp); - - /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */ - tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - gfc_conv_descriptor_stride_get (gfc, idx), - gfc_conv_descriptor_lbound_get (gfc, idx)); - tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - gfc_conv_descriptor_offset_get (gfc), tmp); - gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp); - /* Generate loop. */ - gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0), - rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1), - gfc_finish_block (&loop_body)); - } - - if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length) - { - tmp = fold_convert (gfc_charlen_type_node, - gfc_get_cfi_desc_elem_len (cfi)); - if (e->ts.kind != 1) - tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, - gfc_charlen_type_node, tmp, - build_int_cst (gfc_charlen_type_node, - e->ts.kind)); - gfc_add_modify (&block2, gfc_strlen, tmp); - } - - tmp = gfc_get_cfi_desc_base_addr (cfi), - tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, - tmp, null_pointer_node); - tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2), - build_empty_stmt (input_location)); - gfc_add_expr_to_block (&block, tmp); + gfc_set_gfc_from_cfi (&block, gfc, e, rank, gfc_strlen, cfi, fsym); post_call: gfc_add_block_to_block (&block, &se.post);