https://gcc.gnu.org/g:c2ce7393ce79293896ae05dcfff402ffea2c9176
commit c2ce7393ce79293896ae05dcfff402ffea2c9176 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Jan 21 22:27:02 2025 +0100 Factorisation shift descriptor Diff: --- gcc/fortran/trans-array.cc | 117 ++++++++++++++++++++++++++++++++++++--------- gcc/fortran/trans-array.h | 1 + gcc/fortran/trans-expr.cc | 82 ++----------------------------- 3 files changed, 100 insertions(+), 100 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index b05f69fdd874..7afa29746e08 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -1198,16 +1198,52 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, int dim, } -class lb_info +class lb_info_base { public: + virtual tree lower_bound (stmtblock_t *block, int dim) const = 0; +}; + + +class lb_info : public lb_info_base +{ +public: + using lb_info_base::lower_bound; virtual gfc_expr *lower_bound (int dim) const = 0; + virtual tree lower_bound (stmtblock_t *block, int dim) const; }; +tree +lb_info::lower_bound (stmtblock_t *block, int dim) const +{ + gfc_expr *lb_expr = lower_bound(dim); + + if (lb_expr == nullptr) + return gfc_index_one_node; + else + { + gfc_se lb_se; + + gfc_init_se (&lb_se, nullptr); + gfc_conv_expr (&lb_se, lb_expr); + + gfc_add_block_to_block (block, &lb_se.pre); + tree lb_var = gfc_create_var (gfc_array_index_type, "lower_bound"); + gfc_add_modify (block, lb_var, + fold_convert (gfc_array_index_type, lb_se.expr)); + gfc_add_block_to_block (block, &lb_se.post); + + return lb_var; + } +} + + + class unset_lb : public lb_info { public: + using lb_info::lower_bound; virtual gfc_expr *lower_bound (int) const { return nullptr; } }; @@ -1218,6 +1254,7 @@ class defined_lb : public lb_info gfc_expr * const * lower_bounds; public: + using lb_info::lower_bound; defined_lb (int arg_rank, gfc_expr * const arg_lower_bounds[GFC_MAX_DIMENSIONS]) : rank(arg_rank), lower_bounds(arg_lower_bounds) { } virtual gfc_expr *lower_bound (int dim) const { return lower_bounds[dim]; } @@ -1226,7 +1263,7 @@ public: static void conv_shift_descriptor (stmtblock_t *block, tree desc, int rank, - const lb_info &info) + const lb_info_base &info) { tree tmp = gfc_conv_descriptor_offset_get (desc); tree offset_var = gfc_create_var (TREE_TYPE (tmp), "offset"); @@ -1235,26 +1272,7 @@ conv_shift_descriptor (stmtblock_t *block, tree desc, int rank, /* Apply a shift of the lbound when supplied. */ for (int dim = 0; dim < rank; ++dim) { - gfc_expr *lb_expr = info.lower_bound(dim); - - tree lower_bound; - if (lb_expr == nullptr) - lower_bound = gfc_index_one_node; - else - { - gfc_se lb_se; - - gfc_init_se (&lb_se, nullptr); - gfc_conv_expr (&lb_se, lb_expr); - - gfc_add_block_to_block (block, &lb_se.pre); - tree lb_var = gfc_create_var (TREE_TYPE (lb_se.expr), "lower_bound"); - gfc_add_modify (block, lb_var, lb_se.expr); - gfc_add_block_to_block (block, &lb_se.post); - - lower_bound = lb_var; - } - + tree lower_bound = info.lower_bound (block, dim); conv_shift_descriptor_lbound (block, desc, dim, lower_bound, offset_var); } @@ -1337,6 +1355,61 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, } +class dataref_lb : public lb_info_base +{ + gfc_array_spec *as; + gfc_expr *conv_arg; + tree desc; + +public: + dataref_lb (gfc_array_spec *arg_as, gfc_expr *arg_conv_arg, tree arg_desc) + : as(arg_as), conv_arg (arg_conv_arg), desc (arg_desc) + {} + virtual tree lower_bound (stmtblock_t *block, int dim) const; +}; + + +tree +dataref_lb::lower_bound (stmtblock_t *block, int dim) const +{ + tree lbound; + if (as && as->lower[dim]) + { + gfc_se lbse; + gfc_init_se (&lbse, NULL); + gfc_conv_expr (&lbse, as->lower[dim]); + gfc_add_block_to_block (block, &lbse.pre); + lbound = gfc_evaluate_now (lbse.expr, block); + } + else if (as && conv_arg) + { + tree tmp = gfc_get_symbol_decl (conv_arg->symtree->n.sym); + lbound = gfc_conv_descriptor_lbound_get (tmp, gfc_rank_cst[dim]); + } + else if (as) + lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]); + else + lbound = gfc_index_one_node; + + return fold_convert (gfc_array_index_type, lbound); +} + + +void +gfc_conv_shift_descriptor_subarray (stmtblock_t *block, tree desc, + gfc_expr *value_expr, gfc_expr *conv_arg) +{ + /* Obtain the array spec of full array references. */ + gfc_array_spec *as; + if (conv_arg) + as = gfc_get_full_arrayspec_from_expr (conv_arg); + else + as = gfc_get_full_arrayspec_from_expr (value_expr); + + conv_shift_descriptor (block, desc, value_expr->rank, dataref_lb (as, conv_arg, desc)); +} + + void gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, int src_rank, const gfc_array_spec &as) diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 05ea68d531ac..f9988a5fd109 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -219,6 +219,7 @@ tree gfc_get_cfi_dim_sm (tree, tree); void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &); void gfc_conv_shift_descriptor (stmtblock_t*, tree, int); void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree); +void gfc_conv_shift_descriptor_subarray (stmtblock_t*, tree, gfc_expr *, gfc_expr *); /* Add pre-loop scalarization code for intrinsic functions which require special handling. */ diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 65b6cd8a4642..84c30321d431 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -9418,83 +9418,6 @@ gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr) } -static void -set_subarray_descriptor (stmtblock_t *block, tree desc, tree value, - gfc_expr *value_expr, gfc_expr *conv_arg) -{ - if (value_expr->expr_type != EXPR_VARIABLE) - gfc_conv_descriptor_data_set (block, value, - null_pointer_node); - - /* Obtain the array spec of full array references. */ - gfc_array_spec *as; - if (conv_arg) - as = gfc_get_full_arrayspec_from_expr (conv_arg); - else - as = gfc_get_full_arrayspec_from_expr (value_expr); - - /* Shift the lbound and ubound of temporaries to being unity, - rather than zero, based. Always calculate the offset. */ - tree offset = gfc_conv_descriptor_offset_get (desc); - gfc_add_modify (block, offset, gfc_index_zero_node); - tree tmp2 = gfc_create_var (gfc_array_index_type, NULL); - - for (int n = 0; n < value_expr->rank; n++) - { - tree span; - tree lbound; - - /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9. - TODO It looks as if gfc_conv_expr_descriptor should return - the correct bounds and that the following should not be - necessary. This would simplify gfc_conv_intrinsic_bound - as well. */ - if (as && as->lower[n]) - { - gfc_se lbse; - gfc_init_se (&lbse, NULL); - gfc_conv_expr (&lbse, as->lower[n]); - gfc_add_block_to_block (block, &lbse.pre); - lbound = gfc_evaluate_now (lbse.expr, block); - } - else if (as && conv_arg) - { - tree tmp = gfc_get_symbol_decl (conv_arg->symtree->n.sym); - lbound = gfc_conv_descriptor_lbound_get (tmp, - gfc_rank_cst[n]); - } - else if (as) - lbound = gfc_conv_descriptor_lbound_get (desc, - gfc_rank_cst[n]); - else - lbound = gfc_index_one_node; - - lbound = fold_convert (gfc_array_index_type, lbound); - - /* Shift the bounds and set the offset accordingly. */ - tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]); - span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - tmp, gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n])); - tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - span, lbound); - gfc_conv_descriptor_ubound_set (block, desc, - gfc_rank_cst[n], tmp); - gfc_conv_descriptor_lbound_set (block, desc, - gfc_rank_cst[n], lbound); - - tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - gfc_conv_descriptor_lbound_get (desc, - gfc_rank_cst[n]), - gfc_conv_descriptor_stride_get (desc, - 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, desc, tmp); - } -} - - static tree gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr) @@ -9571,7 +9494,10 @@ gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm, && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE) arg = expr->value.function.actual->expr; - set_subarray_descriptor (&block, dest, se.expr, expr, arg); + if (expr->expr_type != EXPR_VARIABLE) + gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node); + + gfc_conv_shift_descriptor_subarray (&block, dest, expr, arg); if (arg) {