From: Mikael Morin <[email protected]>

Regression tested on powerpc64le-unknown-linux-gnu.  OK for master?

-- >8 --

Add accessor functions to get or set the value of the elements of the dim
field of array descriptors, and remove from the public API the function
giving direct acces to the elements.

There are already accessors for the lower bound, upper bound and stride
subfields.  But there is one place where the elements are copied as a whole
without looking at the subfields, and using the subfields accessors for that
case would be more noisy and less efficient.

gcc/fortran/ChangeLog:

        * trans-descriptor.cc (gfc_conv_descriptor_dimension): Make static
        and rename ...
        (conv_descriptor_dimension): ... to this.
        (gfc_conv_descriptor_subfield): Update caller.
        (gfc_conv_descriptor_dimension_get,
        gfc_conv_descriptor_dimension_set): New functions.
        * trans-descriptor.h (gfc_conv_descriptor_dimension): Remove
        declaration.
        (gfc_conv_descriptor_dimension_get,
        gfc_conv_descriptor_dimension_set): New declarations.
        * trans-array.cc (gfc_conv_array_parameter): Use
        gfc_conv_descriptor_dimension_get to get an element of the dim
        field, und gfc_conv_descriptor_dimension_set to set it.
---
 gcc/fortran/trans-array.cc      |  9 +++---
 gcc/fortran/trans-descriptor.cc | 50 +++++++++++++++++++++++++++++++--
 gcc/fortran/trans-descriptor.h  |  5 +++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 1254eae8ea1..bd9f66a34d6 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9075,11 +9075,10 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
 
              for (int i = 0; i < expr->rank; i++)
                {
-                 old_field = gfc_conv_descriptor_dimension (old_desc,
-                       gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]);
-                 new_field = gfc_conv_descriptor_dimension (new_desc,
-                       gfc_rank_cst[i]);
-                 gfc_add_modify (&se->pre, new_field, old_field);
+                 int idx = get_array_ref_dim_for_loop_dim (ss, i);
+                 old_field = gfc_conv_descriptor_dimension_get (old_desc, idx);
+                 gfc_conv_descriptor_dimension_set (&se->pre, new_desc, i,
+                                                    old_field);
                }
 
              if (flag_coarray == GFC_FCOARRAY_LIB
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index c3aaacd7514..5f7b9955ad0 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -398,8 +398,11 @@ gfc_get_descriptor_dimension (tree desc)
 }
 
 
-tree
-gfc_conv_descriptor_dimension (tree desc, tree dim)
+/* Return a reference to the array access information of the (zero-based)
+   dimension DIM of the array descriptor DESC.  */
+
+static tree
+conv_descriptor_dimension (tree desc, tree dim)
 {
   tree tmp;
 
@@ -408,6 +411,47 @@ gfc_conv_descriptor_dimension (tree desc, tree dim)
   return gfc_build_array_ref (tmp, dim, NULL_TREE, true);
 }
 
+/* Return the value of the array access information of the (zero-based)
+   dimension DIM of the array represented by descriptor DESC.  */
+
+tree
+gfc_conv_descriptor_dimension_get (tree desc, tree dim)
+{
+  return conv_descriptor_dimension (desc, dim);
+}
+
+/* Return the value of the array access information of the (zero-based)
+   dimension DIM of the array represented by descriptor DESC.  */
+
+tree
+gfc_conv_descriptor_dimension_get (tree desc, int dim)
+{
+  return gfc_conv_descriptor_dimension_get (desc, gfc_rank_cst[dim]);
+}
+
+/* Add code to BLOCK setting to VALUE the array access information of the
+   (zero-based) dimension DIM of the array descriptor DESC.  */
+
+void
+gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, tree dim,
+                                  tree value)
+{
+  location_t loc = input_location;
+  tree t = conv_descriptor_dimension (desc, dim);
+  gfc_add_modify_loc (loc, block, t,
+                     fold_convert_loc (loc, TREE_TYPE (t), value));
+}
+
+/* Add code to BLOCK setting to VALUE the array access information of the
+   (zero-based) dimension DIM of the array descriptor DESC.  */
+
+void
+gfc_conv_descriptor_dimension_set (stmtblock_t *block, tree desc, int dim,
+                                  tree value)
+{
+  gfc_conv_descriptor_dimension_set (block, desc, gfc_rank_cst[dim], value);
+}
+
 
 tree
 gfc_conv_descriptor_token (tree desc)
@@ -423,7 +467,7 @@ gfc_conv_descriptor_token (tree desc)
 static tree
 gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx)
 {
-  tree tmp = gfc_conv_descriptor_dimension (desc, dim);
+  tree tmp = conv_descriptor_dimension (desc, dim);
   tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx);
   gcc_assert (field != NULL_TREE);
 
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 3ad9b660052..8c28eb1c54a 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -21,7 +21,6 @@ along with GCC; see the file COPYING3.  If not see
 
 
 tree gfc_get_descriptor_dimension (tree);
-tree gfc_conv_descriptor_dimension (tree, tree);
 tree gfc_conv_descriptor_token (tree);
 
 tree gfc_conv_descriptor_data_get (tree);
@@ -33,6 +32,8 @@ tree gfc_conv_descriptor_rank_get (tree);
 tree gfc_conv_descriptor_type_get (tree);
 tree gfc_conv_descriptor_span_get (tree);
 
+tree gfc_conv_descriptor_dimension_get (tree desc, tree dim);
+tree gfc_conv_descriptor_dimension_get (tree desc, int dim);
 tree gfc_conv_descriptor_stride_get (tree, tree);
 tree gfc_conv_descriptor_lbound_get (tree, tree);
 tree gfc_conv_descriptor_ubound_get (tree, tree);
@@ -48,6 +49,8 @@ void gfc_conv_descriptor_type_set (stmtblock_t *, tree, tree);
 tree gfc_conv_descriptor_type_set (tree, tree);
 tree gfc_conv_descriptor_type_set (tree, int);
 void gfc_conv_descriptor_span_set (stmtblock_t *, tree, tree);
+void gfc_conv_descriptor_dimension_set (stmtblock_t *, tree, tree, tree);
+void gfc_conv_descriptor_dimension_set (stmtblock_t *, tree, int, tree);
 void gfc_conv_descriptor_stride_set (stmtblock_t *, tree, tree, tree);
 void gfc_conv_descriptor_lbound_set (stmtblock_t *, tree, tree, tree);
 void gfc_conv_descriptor_ubound_set (stmtblock_t *, tree, tree, tree);
-- 
2.51.0

Reply via email to