https://gcc.gnu.org/g:a8ebd0806f4e015d9409b3e7a268afc8729cd131

commit a8ebd0806f4e015d9409b3e7a268afc8729cd131
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Wed Jul 16 21:39:51 2025 +0200

    Extraction gfc_conv_shift_descriptor

Diff:
---
 gcc/fortran/trans-descriptor.cc | 45 +++++++++++++++++++++++++++++++++++++++++
 gcc/fortran/trans-descriptor.h  |  1 +
 2 files changed, 46 insertions(+)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 726acb40c8c8..747c4f57bf2a 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -947,6 +947,9 @@ gfc_nullify_descriptor (stmtblock_t *block, tree descr)
 int
 gfc_descriptor_rank (tree descriptor)
 {
+  if (TREE_TYPE (descriptor) != NULL_TREE)
+    return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
+
   tree dim = gfc_get_descriptor_dimension (descriptor);
   tree dim_type = TREE_TYPE (dim);
   gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
@@ -1114,3 +1117,45 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, tree src,
   gfc_conv_remap_descriptor (block, dest, src, src_rank, as);
 }
 
+
+void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src,
+                          int rank, tree zero_cond)
+{
+  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 = gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]);
+      lbound = fold_build3_loc (input_location, COND_EXPR,
+                               gfc_array_index_type, zero_cond,
+                               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);
+    }
+
+  gfc_conv_descriptor_offset_set (block, dest, offset);
+}
+
+
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 1d3c650b32ec..e0033831ce26 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -107,5 +107,6 @@ void gfc_copy_sequence_descriptor (stmtblock_t &, tree, 
tree, bool);
 int gfc_descriptor_rank (tree);
 void gfc_conv_remap_descriptor (stmtblock_t *, tree, tree, int,
                                const gfc_array_ref &as);
+void gfc_conv_shift_descriptor (stmtblock_t *, tree, tree, int, tree);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */

Reply via email to