https://gcc.gnu.org/g:1da75d3bea1cc72cf79d9f18051fbe66fc599533
commit 1da75d3bea1cc72cf79d9f18051fbe66fc599533 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Aug 13 14:02:37 2025 +0200 Refactoring shift descriptor Correction pr85938 Correction régression associate_33 Correction pr43808 Correction associate_38 Sauvegarde compil' OK Suppression évaluation redondante lbound & stride Diff: --- gcc/fortran/trans-descriptor.cc | 123 ++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 69 deletions(-) diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index b34943395c00..e8058752bd81 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -982,6 +982,35 @@ gfc_set_descriptor_from_scalar (stmtblock_t *block, tree descr, } +static void +shift_dimension_bounds (stmtblock_t * block, tree descr, tree dim, + tree new_lbound, tree orig_lbound, tree orig_ubound, + tree orig_stride, tree *offset_value) +{ + new_lbound = fold_convert (gfc_array_index_type, new_lbound); + new_lbound = gfc_evaluate_now (new_lbound, block); + + orig_stride = gfc_evaluate_now (orig_stride, block); + + /* Get difference (new - old) by which to shift stuff. */ + tree diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, + new_lbound, orig_lbound); + + /* Shift ubound and offset accordingly. This has to be done before + updating the lbound, as they depend on the lbound expression! */ + tree ubound = fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, orig_ubound, diff); + gfc_conv_descriptor_ubound_set (block, descr, dim, ubound); + tree tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, new_lbound, orig_stride); + *offset_value = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, *offset_value, tmp); + + /* Finally set lbound to value we want. */ + gfc_conv_descriptor_lbound_set (block, descr, dim, new_lbound); +} + + /* Modify a descriptor such that the lbound of a given dimension is the value specified. This also updates ubound and offset accordingly. */ @@ -990,32 +1019,15 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, int dim, tree new_lbound, tree *offset) { tree ubound, lbound, stride; - tree diff; new_lbound = fold_convert (gfc_array_index_type, new_lbound); - new_lbound = gfc_evaluate_now (new_lbound, block); lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]); ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]); stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]); - stride = gfc_evaluate_now (stride, block); - - /* Get difference (new - old) by which to shift stuff. */ - diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - new_lbound, lbound); - - /* Shift ubound and offset accordingly. This has to be done before - updating the lbound, as they depend on the lbound expression! */ - ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - ubound, diff); - gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound); - tree tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - new_lbound, stride); - *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - *offset, tmp); - /* Finally set lbound to value we want. */ - gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound); + shift_dimension_bounds (block, desc, gfc_rank_cst[dim], new_lbound, lbound, + ubound, stride, offset); } @@ -1025,8 +1037,8 @@ gfc_conv_shift_descriptor (stmtblock_t* block, tree desc, int rank) /* Apply a shift of the lbound when supplied. */ tree offset = gfc_index_zero_node; for (int dim = 0; dim < rank; ++dim) - conv_shift_descriptor_lbound (block, desc, dim, - gfc_index_one_node, &offset); + conv_shift_descriptor_lbound (block, desc, dim, gfc_index_one_node, + &offset); gfc_conv_descriptor_offset_set (block, desc, offset); } @@ -1141,23 +1153,14 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src, gfc_index_one_node, lbound); 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); + tree dim = gfc_rank_cst[n]; + tree stride = gfc_conv_descriptor_stride_get (src, dim); + shift_dimension_bounds (block, dest, gfc_rank_cst[n], + lbound, gfc_index_zero_node, + gfc_conv_descriptor_ubound_get (src, dim), + stride, &offset); + + gfc_conv_descriptor_stride_set (block, dest, dim, stride); } gfc_conv_descriptor_offset_set (block, dest, offset); @@ -1185,7 +1188,6 @@ gfc_set_subarray_descriptor (stmtblock_t *block, tree descr, tree value, for (int n = 0; n < value_expr->rank; n++) { - tree span; tree lbound; /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9. @@ -1214,24 +1216,14 @@ gfc_set_subarray_descriptor (stmtblock_t *block, tree descr, tree value, lbound = fold_convert (gfc_array_index_type, lbound); /* Shift the bounds and set the offset accordingly. */ - tree tmp = gfc_conv_descriptor_ubound_get (descr, gfc_rank_cst[n]); - span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - tmp, gfc_conv_descriptor_lbound_get (descr, gfc_rank_cst[n])); - tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - span, lbound); - gfc_conv_descriptor_ubound_set (block, descr, gfc_rank_cst[n], tmp); - gfc_conv_descriptor_lbound_set (block, descr, gfc_rank_cst[n], lbound); - - tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - gfc_conv_descriptor_lbound_get (descr, - gfc_rank_cst[n]), - gfc_conv_descriptor_stride_get (descr, - gfc_rank_cst[n])); - gfc_add_modify (block, tmp2, tmp); - tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - offset, tmp2); - gfc_conv_descriptor_offset_set (block, descr, tmp); + tree dim = gfc_rank_cst[n]; + shift_dimension_bounds (block, descr, dim, lbound, + gfc_conv_descriptor_lbound_get (descr, dim), + gfc_conv_descriptor_ubound_get (descr, dim), + gfc_conv_descriptor_stride_get (descr, dim), + &offset); } + gfc_conv_descriptor_offset_set (block, descr, offset); } @@ -1244,19 +1236,12 @@ gfc_shift_descriptor (stmtblock_t *block, tree descr, int rank, tree offset = gfc_index_zero_node; for (int n = 0; n < rank; n++) { - tree tmp = gfc_conv_descriptor_ubound_get (descr, gfc_rank_cst[n]); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, tmp, - gfc_index_one_node); - gfc_conv_descriptor_ubound_set (block, descr, gfc_rank_cst[n], tmp); - gfc_conv_descriptor_lbound_set (block, descr, gfc_rank_cst[n], - gfc_index_one_node); - size = gfc_evaluate_now (size, block); - offset = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, offset, size); - offset = gfc_evaluate_now (offset, block); - tmp = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, ubound[n], lbound[n]); + tree dim = gfc_rank_cst[n]; + shift_dimension_bounds (block, descr, dim, gfc_index_one_node, + lbound[n], ubound[n], size, &offset); + + tree tmp = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, ubound[n], lbound[n]); tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp, gfc_index_one_node); size = fold_build2_loc (input_location, MULT_EXPR,