[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Restauration intrinsic stride (correction régression finalize_17)
Mikael Morin
mikael@gcc.gnu.org
Fri Jun 13 15:00:09 GMT 2025
https://gcc.gnu.org/g:dcba9a4db0d614f17583495ca6687912bca3f0b7
commit dcba9a4db0d614f17583495ca6687912bca3f0b7
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Tue Apr 29 18:40:50 2025 +0200
Restauration intrinsic stride (correction régression finalize_17)
Diff:
---
gcc/fortran/class.cc | 43 +++++++++++++++++++++++-------------------
gcc/fortran/intrinsic.cc | 8 ++++++++
gcc/fortran/trans-intrinsic.cc | 32 +++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 23d8701ac44f..e92760db51dd 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1343,14 +1343,12 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
offset = 0
do idx2 = 1, rank
offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
- end do
- offset = offset * byte_stride. */
+ end do */
static gfc_code*
finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
gfc_symbol *strides, gfc_symbol *sizes,
- gfc_symbol *byte_stride, gfc_expr *rank,
- gfc_code *block, gfc_namespace *sub_ns)
+ gfc_expr *rank, gfc_code *block, gfc_namespace *sub_ns)
{
gfc_iterator *iter;
gfc_expr *expr, *expr2;
@@ -1443,17 +1441,6 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
block->block->next->expr2->ts = idx->ts;
block->block->next->expr2->where = gfc_current_locus;
- /* After the loop: offset = offset * byte_stride. */
- block->next = gfc_get_code (EXEC_ASSIGN);
- block = block->next;
- block->expr1 = gfc_lval_expr_from_sym (offset);
- block->expr2 = gfc_get_expr ();
- block->expr2->expr_type = EXPR_OP;
- block->expr2->value.op.op = INTRINSIC_TIMES;
- block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
- block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
- block->expr2->ts = block->expr2->value.op.op1->ts;
- block->expr2->where = gfc_current_locus;
return block;
}
@@ -1926,10 +1913,29 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
last_code->ext.iterator = iter;
last_code->block = gfc_get_code (EXEC_DO);
- /* sizes(idx) = ... */
+ /* strides(idx) = _F._stride(array,dim=idx). */
last_code->block->next = gfc_get_code (EXEC_ASSIGN);
block = last_code->block->next;
+ block->expr1 = gfc_lval_expr_from_sym (strides);
+ block->expr1->ref = gfc_get_ref ();
+ block->expr1->ref->type = REF_ARRAY;
+ block->expr1->ref->u.ar.type = AR_ELEMENT;
+ block->expr1->ref->u.ar.dimen = 1;
+ block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
+ block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
+ block->expr1->ref->u.ar.as = strides->as;
+
+ block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
+ gfc_current_locus, 2,
+ gfc_lval_expr_from_sym (array),
+ gfc_lval_expr_from_sym (idx));
+
+ /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
+ block->next = gfc_get_code (EXEC_ASSIGN);
+ block = block->next;
+
+ /* sizes(idx) = ... */
block->expr1 = gfc_lval_expr_from_sym (sizes);
block->expr1->ref = gfc_get_ref ();
block->expr1->ref->type = REF_ARRAY;
@@ -2146,8 +2152,7 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
/* Offset calculation. */
block = finalization_get_offset (idx, idx2, offset, strides, sizes,
- byte_stride, rank, block->block,
- sub_ns);
+ rank, block->block, sub_ns);
/* Create code for
CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
@@ -2217,7 +2222,7 @@ finish_assumed_rank:
/* Offset calculation. */
block = finalization_get_offset (idx, idx2, offset, strides, sizes,
- byte_stride, rank, last_code->block,
+ rank, last_code->block,
sub_ns);
/* Create code for
diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc
index c39cb85784a6..9e07627503de 100644
--- a/gcc/fortran/intrinsic.cc
+++ b/gcc/fortran/intrinsic.cc
@@ -3179,6 +3179,14 @@ add_functions (void)
make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95);
+ /* Obtain the stride for a given dimensions; to be used only internally.
+ "make_from_module" makes it inaccessible for external users. */
+ add_sym_2 (GFC_PREFIX ("stride"), GFC_ISYM_STRIDE, CLASS_INQUIRY, ACTUAL_NO,
+ BT_INTEGER, gfc_index_integer_kind, GFC_STD_GNU,
+ NULL, NULL, gfc_resolve_stride,
+ ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
+ make_from_module();
+
add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, CLASS_INQUIRY, ACTUAL_NO,
BT_INTEGER, ii, GFC_STD_GNU,
gfc_check_sizeof, gfc_simplify_sizeof, NULL,
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index d3353bb61bab..4cb279b4c6ca 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -2744,6 +2744,34 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
}
+static void
+conv_intrinsic_stride (gfc_se * se, gfc_expr * expr)
+{
+ gfc_actual_arglist *array_arg;
+ gfc_actual_arglist *dim_arg;
+ gfc_se argse;
+ tree desc, tmp;
+
+ array_arg = expr->value.function.actual;
+ dim_arg = array_arg->next;
+
+ gcc_assert (array_arg->expr->expr_type == EXPR_VARIABLE);
+
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_descriptor (&argse, array_arg->expr);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ desc = argse.expr;
+
+ gcc_assert (dim_arg->expr);
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_type (&argse, dim_arg->expr, gfc_array_index_type);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ argse.expr, gfc_index_one_node);
+ se->expr = gfc_conv_descriptor_spacing_get (desc, tmp);
+}
+
static void
gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
{
@@ -11258,6 +11286,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_spacing (se, expr);
break;
+ case GFC_ISYM_STRIDE:
+ conv_intrinsic_stride (se, expr);
+ break;
+
case GFC_ISYM_SUM:
gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
break;
More information about the Gcc-cvs
mailing list