[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Factorisation gfc_conv_shift_descriptor
Mikael Morin
mikael@gcc.gnu.org
Mon May 19 16:03:12 GMT 2025
https://gcc.gnu.org/g:f8223bcc7fe3ef718208cc05c4365a3f57e05dc7
commit f8223bcc7fe3ef718208cc05c4365a3f57e05dc7
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Thu Feb 6 17:16:13 2025 +0100
Factorisation gfc_conv_shift_descriptor
Correction compil'
Correction régression allocated_4.f90
Factorisation gfc_conv_shift_descriptor.
Correction régression allocated_4.f90
Modifications mineures
Correction régression bound_10.f90
Correction régression alloc_comp_constructor_1.f90
Correction régression realloc_on_assign_10
Revert "Correction régression realloc_on_assign_10"
This reverts commit 007ca869933eb74b76398200ef0237219ba01cd8.
Correction régression realloc_on_assign_11.f90
Diff:
---
gcc/fortran/trans-array.cc | 165 ++++++++++++++++++++++-----------------------
gcc/fortran/trans-expr.cc | 15 ++++-
2 files changed, 94 insertions(+), 86 deletions(-)
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index c383d9c58342..ee5b95df9ccb 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1478,35 +1478,43 @@ gfc_build_null_descriptor (tree type)
specified. This also updates ubound and offset accordingly. */
static void
-conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, int dim,
- tree new_lbound, tree offset)
+conv_shift_descriptor_lbound (stmtblock_t* block, tree from_desc, tree to_desc, int dim,
+ tree new_lbound, tree offset, bool zero_based)
{
- tree ubound, lbound, stride;
- tree diff, offs_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]);
+ tree lbound = gfc_conv_descriptor_lbound_get (from_desc, gfc_rank_cst[dim]);
+ tree ubound = gfc_conv_descriptor_ubound_get (from_desc, gfc_rank_cst[dim]);
+ tree stride = gfc_conv_descriptor_stride_get (from_desc, gfc_rank_cst[dim]);
- /* Get difference (new - old) by which to shift stuff. */
- diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
- new_lbound, lbound);
+ tree diff;
+ if (zero_based)
+ diff = new_lbound;
+ else
+ {
+ /* Get difference (new - old) by which to shift stuff. */
+ diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ new_lbound, lbound);
+ diff = gfc_evaluate_now (diff, block);
+ }
/* 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);
- offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
- diff, stride);
- tree tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
- offset, offs_diff);
- gfc_add_modify (block, offset, tmp);
+ tree tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+ ubound, diff);
+ gfc_conv_descriptor_ubound_set (block, to_desc, gfc_rank_cst[dim], tmp1);
+ /* Set lbound to the value we want. */
+ gfc_conv_descriptor_lbound_set (block, to_desc, gfc_rank_cst[dim], new_lbound);
- /* Finally set lbound to value we want. */
- gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
+ tree offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+ diff, stride);
+ tree tmp2 = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ offset, offs_diff);
+ gfc_add_modify (block, offset, tmp2);
+
+ if (from_desc != to_desc)
+ gfc_conv_descriptor_stride_set (block, to_desc, gfc_rank_cst[dim], stride);
}
@@ -1514,6 +1522,7 @@ class lb_info_base
{
public:
virtual tree lower_bound (stmtblock_t *block, int dim) const = 0;
+ virtual bool zero_based_src () const { return false; }
};
@@ -1574,21 +1583,64 @@ public:
static void
-conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+conv_shift_descriptor (stmtblock_t *block, tree src, tree dest, int rank,
const lb_info_base &info)
{
- tree tmp = gfc_conv_descriptor_offset_get (desc);
- tree offset_var = gfc_create_var (TREE_TYPE (tmp), "offset");
- gfc_add_modify (block, offset_var, tmp);
+ if (src != dest)
+ {
+ tree tmp = gfc_conv_descriptor_data_get (src);
+ gfc_conv_descriptor_data_set (block, dest, tmp);
+ }
+
+ tree offset_var = gfc_create_var (gfc_array_index_type, "offset");
+ tree init_offset;
+ if (info.zero_based_src ())
+ init_offset = gfc_index_zero_node;
+ else
+ init_offset = gfc_conv_descriptor_offset_get (src);
+ gfc_add_modify (block, offset_var, init_offset);
/* Apply a shift of the lbound when supplied. */
for (int dim = 0; dim < rank; ++dim)
{
tree lower_bound = info.lower_bound (block, dim);
- conv_shift_descriptor_lbound (block, desc, dim, lower_bound, offset_var);
+ conv_shift_descriptor_lbound (block, src, dest, dim, lower_bound, offset_var,
+ info.zero_based_src ());
}
- gfc_conv_descriptor_offset_set (block, desc, offset_var);
+ gfc_conv_descriptor_offset_set (block, dest, offset_var);
+}
+
+
+static void
+conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+ const lb_info_base &info)
+{
+ conv_shift_descriptor (block, desc, desc, rank, info);
+}
+
+
+class cond_descr_lb : public lb_info_base
+{
+ tree desc;
+ tree cond;
+public:
+ cond_descr_lb (tree arg_desc, tree arg_cond)
+ : desc (arg_desc), cond (arg_cond) { }
+
+ virtual tree lower_bound (stmtblock_t *block, int dim) const;
+ virtual bool zero_based_src () const { return true; }
+};
+
+
+tree
+cond_descr_lb::lower_bound (stmtblock_t *block ATTRIBUTE_UNUSED, int dim) const
+{
+ tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
+ lbound = fold_build3_loc (input_location, COND_EXPR,
+ gfc_array_index_type, cond,
+ gfc_index_one_node, lbound);
+ return lbound;
}
@@ -1861,67 +1913,12 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src,
}
-class conditional_lb
-{
- tree cond;
-public:
- conditional_lb (tree arg_cond)
- : cond (arg_cond) { }
-
- tree lower_bound (tree src, int n) const {
- tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[n]);
- lbound = fold_build3_loc (input_location, COND_EXPR,
- gfc_array_index_type, cond,
- gfc_index_one_node, lbound);
- return lbound;
- }
-};
-
-
-static void
-gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src,
- int rank, const conditional_lb &lb)
-{
- tree tmp = gfc_conv_descriptor_data_get (src);
- gfc_conv_descriptor_data_set (block, dest, tmp);
-
- tree offset = gfc_index_zero_node;
- for (int n = 0 ; n < rank; n++)
- {
- tree lbound;
-
- lbound = lb.lower_bound (dest, n);
- 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);
- }
-
- gfc_conv_descriptor_offset_set (block, dest, offset);
-}
-
-
void
gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src,
int rank, tree zero_cond)
{
- gfc_conv_shift_descriptor (block, dest, src, rank,
- conditional_lb (zero_cond));
+ conv_shift_descriptor (block, src, dest, rank,
+ cond_descr_lb (dest, zero_cond));
}
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index c283929f44d0..8375339001ca 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9525,11 +9525,22 @@ 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;
+ stmtblock_t shift_block;
+ gfc_init_block (&shift_block);
+ gfc_conv_shift_descriptor_subarray (&shift_block, dest, expr, arg);
+
+ tree data = gfc_conv_descriptor_data_get (se.expr);
+ data = fold_convert (pvoid_type_node, data);
+ tree non_null = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
+ data, null_pointer_node);
+ tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
+ non_null, gfc_finish_block (&shift_block),
+ build_empty_stmt (input_location));
+ gfc_add_expr_to_block (&block, tmp);
+
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)
{
/* If a conversion expression has a null data pointer
More information about the Gcc-cvs
mailing list