[PATCH 2/3] fortran: array descriptor: Move rank offset construction [PR122521]

Mikael Morin <[email protected]> Tue, 28 Jul 2026 17:20:11 +0200
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
From: Mikael Morin <[email protected]>

Fortran-tested on aarch64-unknown-linux-gnu.  OK for mainline?

-- >8 --

The construction of the array descriptor debug info uses the rank field
layout information to generate an expression for the rank in trans-type.cc's
`gfc_get_array_descr_info'.

This change moves the rank offset construction to trans-descriptor.cc's
`gfc_get_descriptor_offsets_for_info', so that the layout of the rank field
doesn't need to be known outside of trans-descriptor.cc.

	PR fortran/122521

gcc/fortran/ChangeLog:

	* trans-descriptor.cc (gfc_get_descriptor_offsets_for_info): Remove
	the dtype offset argument and add a rank offset argument.  Set the
	value of that offset.  Use a variable to factor repeated accesses to
	TYPE_FIELDS (type).
	* trans-types.cc (gfc_get_array_descr_info): Update caller.  Create
	the rank expression using the just obtained rank offset.
---
 gcc/fortran/trans-descriptor.cc | 18 ++++++++++++------
 gcc/fortran/trans-types.cc      | 16 +++++-----------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index e4ff96fff67..e20159fa3c6 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -593,7 +593,7 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
 
 void
 gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off,
-				     tree *dtype_off, tree *span_off,
+				     tree *rank_off, tree *span_off,
 				     tree *dim_off, tree *dim_size,
 				     tree *stride_suboff, tree *lower_suboff,
 				     tree *upper_suboff)
@@ -602,13 +602,19 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off,
   tree type;
 
   type = TYPE_MAIN_VARIANT (desc_type);
-  field = gfc_advance_chain (TYPE_FIELDS (type), DATA_FIELD);
+  tree fields = TYPE_FIELDS (type);
+  field = gfc_advance_chain (fields, DATA_FIELD);
   *data_off = byte_position (field);
-  field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
-  *dtype_off = byte_position (field);
-  field = gfc_advance_chain (TYPE_FIELDS (type), SPAN_FIELD);
+  field = gfc_advance_chain (fields, DTYPE_FIELD);
+  tree dtype_off = byte_position (field);
+  type = TREE_TYPE (field);
+  field = gfc_advance_chain (TYPE_FIELDS (type), GFC_DTYPE_RANK);
+  tree rank_suboff = byte_position (field);
+  *rank_off = fold_build2 (PLUS_EXPR, TREE_TYPE (dtype_off), dtype_off,
+			   rank_suboff);
+  field = gfc_advance_chain (fields, SPAN_FIELD);
   *span_off = byte_position (field);
-  field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
+  field = gfc_advance_chain (fields, DIMENSION_FIELD);
   *dim_off = byte_position (field);
   type = TREE_TYPE (TREE_TYPE (field));
   *dim_size = TYPE_SIZE_UNIT (type);
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 4cc63c4f64d..c9dddca3f71 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -3709,9 +3709,8 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
   int rank, dim;
   bool indirect = false;
   tree etype, ptype, t, base_decl;
-  tree data_off, span_off, dim_off, dtype_off, dim_size, elem_size;
+  tree data_off, span_off, dim_off, rank_off, dim_size, elem_size;
   tree lower_suboff, upper_suboff, stride_suboff;
-  tree dtype, field, rank_off;
 
   if (! GFC_DESCRIPTOR_TYPE_P (type))
     {
@@ -3764,7 +3763,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
   if (indirect)
     base_decl = build1 (INDIRECT_REF, ptype, base_decl);
 
-  gfc_get_descriptor_offsets_for_info (type, &data_off, &dtype_off, &span_off,
+  gfc_get_descriptor_offsets_for_info (type, &data_off, &rank_off, &span_off,
 				       &dim_off, &dim_size, &stride_suboff,
 				       &lower_suboff, &upper_suboff);
 
@@ -3796,14 +3795,9 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
     {
       rank = 1;
       info->ndimensions = 1;
-      t = fold_build_pointer_plus (base_decl, dtype_off);
-      dtype = TYPE_MAIN_VARIANT (get_dtype_type_node ());
-      field = gfc_advance_chain (TYPE_FIELDS (dtype), GFC_DTYPE_RANK);
-      rank_off = byte_position (field);
-      t = fold_build_pointer_plus (t, rank_off);
-
-      t = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (field)), t);
-      t = build1 (INDIRECT_REF, TREE_TYPE (field), t);
+      t = fold_build_pointer_plus (base_decl, rank_off);
+      t = build1 (NOP_EXPR, build_pointer_type (signed_char_type_node), t);
+      t = build1 (INDIRECT_REF, signed_char_type_node, t);
       info->rank = t;
       t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
       t = size_binop (MULT_EXPR, t, dim_size);
-- 
2.53.0