https://gcc.gnu.org/g:b7b0737f9d70a1415eedc9026932629ff025a5cb
commit b7b0737f9d70a1415eedc9026932629ff025a5cb Author: Mikael Morin <mik...@gcc.gnu.org> Date: Fri Mar 14 15:40:09 2025 +0100 Factorisation set descriptor with shape Diff: --- gcc/fortran/trans-array.cc | 114 ++++++++++++++++++++++++++++++++++++++++- gcc/fortran/trans-array.h | 2 + gcc/fortran/trans-intrinsic.cc | 108 ++------------------------------------ 3 files changed, 119 insertions(+), 105 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index d0f00f96fc02..abc0bd8756f4 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1553,7 +1553,7 @@ copy_descriptor (stmtblock_t *block, tree dest, tree src, && dest_ls->akind != src_ls->akind) tmp1 = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dest), src); else - tmp1 = desc; + tmp1 = src; /* Copy the descriptor for pointer assignments. */ gfc_add_modify (block, dest, tmp1); @@ -1562,7 +1562,7 @@ copy_descriptor (stmtblock_t *block, tree dest, tree src, gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr); /* ....and set the span field. */ - tree tmp2 + tree tmp2; if (src_expr->ts.type == BT_CHARACTER) tmp2 = gfc_conv_descriptor_span_get (src); else @@ -1571,6 +1571,116 @@ copy_descriptor (stmtblock_t *block, tree dest, tree src, } +void +gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree ptr, + gfc_expr *shape, gfc_expr *lower, locus *where) +{ + /* Set the span field. */ + tree tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc))); + tmp = fold_convert (gfc_array_index_type, tmp); + gfc_conv_descriptor_span_set (block, desc, tmp); + + /* Set data value, dtype, and offset. */ + tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)); + gfc_conv_descriptor_data_set (block, desc, fold_convert (tmp, ptr)); + gfc_add_modify (block, gfc_conv_descriptor_dtype (desc), + gfc_get_dtype (TREE_TYPE (desc))); + + /* Start scalarization of the bounds, using the shape argument. */ + + gfc_ss *shape_ss = gfc_walk_expr (shape); + gcc_assert (shape_ss != gfc_ss_terminator); + gfc_se shapese, lowerse; + gfc_init_se (&shapese, nullptr); + gfc_ss *lower_ss = nullptr; + if (lower) + { + lower_ss = gfc_walk_expr (lower); + gcc_assert (lower_ss != gfc_ss_terminator); + gfc_init_se (&lowerse, nullptr); + } + + gfc_loopinfo loop; + gfc_init_loopinfo (&loop); + gfc_add_ss_to_loop (&loop, shape_ss); + if (lower) + gfc_add_ss_to_loop (&loop, lower_ss); + gfc_conv_ss_startstride (&loop); + gfc_conv_loop_setup (&loop, where); + gfc_mark_ss_chain_used (shape_ss, 1); + if (lower) + gfc_mark_ss_chain_used (lower_ss, 1); + + gfc_copy_loopinfo_to_se (&shapese, &loop); + shapese.ss = shape_ss; + if (lower) + { + gfc_copy_loopinfo_to_se (&lowerse, &loop); + lowerse.ss = lower_ss; + } + + tree stride = gfc_create_var (gfc_array_index_type, "stride"); + tree offset = gfc_create_var (gfc_array_index_type, "offset"); + gfc_add_modify (block, stride, gfc_index_one_node); + gfc_add_modify (block, offset, gfc_index_zero_node); + + /* Loop body. */ + stmtblock_t body; + gfc_start_scalarized_body (&loop, &body); + + tree dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + loop.loopvar[0], loop.from[0]); + + tree lbound; + if (lower) + { + gfc_conv_expr (&lowerse, lower); + gfc_add_block_to_block (&body, &lowerse.pre); + lbound = fold_convert (gfc_array_index_type, lowerse.expr); + gfc_add_block_to_block (&body, &lowerse.post); + } + else + lbound = gfc_index_one_node; + + /* Set bounds and stride. */ + gfc_conv_descriptor_lbound_set (&body, desc, dim, lbound); + gfc_conv_descriptor_stride_set (&body, desc, dim, stride); + + gfc_conv_expr (&shapese, shape); + gfc_add_block_to_block (&body, &shapese.pre); + tree ubound = fold_build2_loc ( + input_location, MINUS_EXPR, gfc_array_index_type, + fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, lbound, + fold_convert (gfc_array_index_type, shapese.expr)), + gfc_index_one_node); + gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound); + gfc_add_block_to_block (&body, &shapese.post); + + /* Calculate offset. */ + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + stride, lbound); + gfc_add_modify (&body, offset, + fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, offset, tmp)); + + /* Update stride. */ + gfc_add_modify ( + &body, stride, + fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, stride, + fold_convert (gfc_array_index_type, shapese.expr))); + /* Finish scalarization loop. */ + gfc_trans_scalarizing_loops (&loop, &body); + gfc_add_block_to_block (block, &loop.pre); + gfc_add_block_to_block (block, &loop.post); + gfc_cleanup_loop (&loop); + + gfc_add_modify (block, offset, + fold_build1_loc (input_location, NEGATE_EXPR, + gfc_array_index_type, offset)); + gfc_conv_descriptor_offset_set (block, desc, offset); +} + + /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info). */ void diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index e48f72856f6a..a1d6bbeef98a 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -144,6 +144,8 @@ void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, tree); void gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *, tree); void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, gfc_expr *, tree); void gfc_set_scalar_descriptor (stmtblock_t *block, tree, gfc_symbol *, gfc_expr *, tree); +void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree, + gfc_expr *, gfc_expr *, locus *); /* Get a single array element. */ void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *); diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 895e2b0627be..c5632eb6d96d 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -9919,11 +9919,9 @@ static tree conv_isocbinding_subroutine (gfc_code *code) { gfc_expr *cptr, *fptr, *shape, *lower; - gfc_se se, cptrse, fptrse, shapese, lowerse; - gfc_ss *shape_ss, *lower_ss; - tree desc, dim, tmp, stride, offset, lbound, ubound; - stmtblock_t body, block; - gfc_loopinfo loop; + gfc_se se, cptrse, fptrse; + tree desc; + stmtblock_t block; gfc_actual_arglist *arg; arg = code->ext.actual; @@ -9965,106 +9963,10 @@ conv_isocbinding_subroutine (gfc_code *code) gfc_add_block_to_block (&block, &fptrse.pre); desc = fptrse.expr; - /* Set the span field. */ - tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc))); - tmp = fold_convert (gfc_array_index_type, tmp); - gfc_conv_descriptor_span_set (&block, desc, tmp); - - /* Set data value, dtype, and offset. */ - tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)); - gfc_conv_descriptor_data_set (&block, desc, fold_convert (tmp, cptrse.expr)); - gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc), - gfc_get_dtype (TREE_TYPE (desc))); - - /* Start scalarization of the bounds, using the shape argument. */ - - shape_ss = gfc_walk_expr (shape); - gcc_assert (shape_ss != gfc_ss_terminator); - gfc_init_se (&shapese, NULL); - if (lower) - { - lower_ss = gfc_walk_expr (lower); - gcc_assert (lower_ss != gfc_ss_terminator); - gfc_init_se (&lowerse, NULL); - } - - gfc_init_loopinfo (&loop); - gfc_add_ss_to_loop (&loop, shape_ss); - if (lower) - gfc_add_ss_to_loop (&loop, lower_ss); - gfc_conv_ss_startstride (&loop); - gfc_conv_loop_setup (&loop, &fptr->where); - gfc_mark_ss_chain_used (shape_ss, 1); - if (lower) - gfc_mark_ss_chain_used (lower_ss, 1); - - gfc_copy_loopinfo_to_se (&shapese, &loop); - shapese.ss = shape_ss; - if (lower) - { - gfc_copy_loopinfo_to_se (&lowerse, &loop); - lowerse.ss = lower_ss; - } + gfc_set_descriptor_with_shape (&block, desc, cptrse.expr, + shape, lower, &fptr->where); - stride = gfc_create_var (gfc_array_index_type, "stride"); - offset = gfc_create_var (gfc_array_index_type, "offset"); - gfc_add_modify (&block, stride, gfc_index_one_node); - gfc_add_modify (&block, offset, gfc_index_zero_node); - - /* Loop body. */ - gfc_start_scalarized_body (&loop, &body); - - dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - loop.loopvar[0], loop.from[0]); - - if (lower) - { - gfc_conv_expr (&lowerse, lower); - gfc_add_block_to_block (&body, &lowerse.pre); - lbound = fold_convert (gfc_array_index_type, lowerse.expr); - gfc_add_block_to_block (&body, &lowerse.post); - } - else - lbound = gfc_index_one_node; - - /* Set bounds and stride. */ - gfc_conv_descriptor_lbound_set (&body, desc, dim, lbound); - gfc_conv_descriptor_stride_set (&body, desc, dim, stride); - - gfc_conv_expr (&shapese, shape); - gfc_add_block_to_block (&body, &shapese.pre); - ubound = fold_build2_loc ( - input_location, MINUS_EXPR, gfc_array_index_type, - fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, lbound, - fold_convert (gfc_array_index_type, shapese.expr)), - gfc_index_one_node); - gfc_conv_descriptor_ubound_set (&body, desc, dim, ubound); - gfc_add_block_to_block (&body, &shapese.post); - - /* Calculate offset. */ - tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - stride, lbound); - gfc_add_modify (&body, offset, - fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, offset, tmp)); - - /* Update stride. */ - gfc_add_modify ( - &body, stride, - fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, stride, - fold_convert (gfc_array_index_type, shapese.expr))); - /* Finish scalarization loop. */ - gfc_trans_scalarizing_loops (&loop, &body); - gfc_add_block_to_block (&block, &loop.pre); - gfc_add_block_to_block (&block, &loop.post); gfc_add_block_to_block (&block, &fptrse.post); - gfc_cleanup_loop (&loop); - - gfc_add_modify (&block, offset, - fold_build1_loc (input_location, NEGATE_EXPR, - gfc_array_index_type, offset)); - gfc_conv_descriptor_offset_set (&block, desc, offset); - gfc_add_expr_to_block (&se.pre, gfc_finish_block (&block)); gfc_add_block_to_block (&se.pre, &se.post); return gfc_finish_block (&se.pre);