From: Mikael Morin <[email protected]>
Regression tested on powerpc64le-unknown-linux-gnu. OK for master?
-- >8 --
gcc/fortran/ChangeLog:
* trans-descriptor.h (gfc_copy_descriptor): Add declaration.
* trans-stmt.cc (trans_associate_var): Update caller.
(copy_descriptor): Rename function and move it ...
* trans-descriptor.cc (gfc_copy_descriptor): ... here.
---
gcc/fortran/trans-descriptor.cc | 42 ++++++++++++++++++++++++++++++
gcc/fortran/trans-descriptor.h | 2 ++
gcc/fortran/trans-stmt.cc | 46 ++-------------------------------
3 files changed, 46 insertions(+), 44 deletions(-)
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 57297fcf75d..299d56c728a 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -499,3 +499,45 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree
desc,
/* Finally set lbound to value we want. */
gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
}
+
+
+void
+gfc_copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank)
+{
+ int n;
+ tree dim;
+ tree tmp;
+ tree tmp2;
+ tree size;
+ tree offset;
+
+ offset = gfc_index_zero_node;
+
+ /* Use memcpy to copy the descriptor. The size is the minimum of
+ the sizes of 'src' and 'dst'. This avoids a non-trivial conversion. */
+ tmp = TYPE_SIZE_UNIT (TREE_TYPE (src));
+ tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst));
+ size = fold_build2_loc (input_location, MIN_EXPR,
+ TREE_TYPE (tmp), tmp, tmp2);
+ tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
+ tmp = build_call_expr_loc (input_location, tmp, 3,
+ gfc_build_addr_expr (NULL_TREE, dst),
+ gfc_build_addr_expr (NULL_TREE, src),
+ fold_convert (size_type_node, size));
+ gfc_add_expr_to_block (block, tmp);
+
+ /* Set the offset correctly. */
+ for (n = 0; n < rank; n++)
+ {
+ dim = gfc_rank_cst[n];
+ tmp = gfc_conv_descriptor_lbound_get (src, dim);
+ tmp2 = gfc_conv_descriptor_stride_get (src, dim);
+ tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
+ tmp, tmp2);
+ offset = fold_build2_loc (input_location, MINUS_EXPR,
+ TREE_TYPE (offset), offset, tmp);
+ offset = gfc_evaluate_now (offset, block);
+ }
+
+ gfc_conv_descriptor_offset_set (block, dst, offset);
+}
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index fefa152e2d7..b1623a21803 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -60,4 +60,6 @@ tree gfc_conv_descriptor_cosize (tree, int, int);
/* Shift lower bound of descriptor, updating ubound and offset. */
void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree);
+void gfc_copy_descriptor (stmtblock_t *, tree, tree, int);
+
#endif /* GFC_TRANS_DESCRIPTOR_H */
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 8f4a5f9ac8b..5eaafbbcc7e 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -1825,48 +1825,6 @@ class_has_len_component (gfc_symbol *sym)
}
-static void
-copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank)
-{
- int n;
- tree dim;
- tree tmp;
- tree tmp2;
- tree size;
- tree offset;
-
- offset = gfc_index_zero_node;
-
- /* Use memcpy to copy the descriptor. The size is the minimum of
- the sizes of 'src' and 'dst'. This avoids a non-trivial conversion. */
- tmp = TYPE_SIZE_UNIT (TREE_TYPE (src));
- tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst));
- size = fold_build2_loc (input_location, MIN_EXPR,
- TREE_TYPE (tmp), tmp, tmp2);
- tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
- tmp = build_call_expr_loc (input_location, tmp, 3,
- gfc_build_addr_expr (NULL_TREE, dst),
- gfc_build_addr_expr (NULL_TREE, src),
- fold_convert (size_type_node, size));
- gfc_add_expr_to_block (block, tmp);
-
- /* Set the offset correctly. */
- for (n = 0; n < rank; n++)
- {
- dim = gfc_rank_cst[n];
- tmp = gfc_conv_descriptor_lbound_get (src, dim);
- tmp2 = gfc_conv_descriptor_stride_get (src, dim);
- tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
- tmp, tmp2);
- offset = fold_build2_loc (input_location, MINUS_EXPR,
- TREE_TYPE (offset), offset, tmp);
- offset = gfc_evaluate_now (offset, block);
- }
-
- gfc_conv_descriptor_offset_set (block, dst, offset);
-}
-
-
/* Do proper initialization for ASSOCIATE names. */
static void
@@ -1995,7 +1953,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block
*block)
attributes so the selector descriptor must be copied in and
copied out. */
if (rank > 0)
- copy_descriptor (&se.pre, desc, se.expr, rank);
+ gfc_copy_descriptor (&se.pre, desc, se.expr, rank);
else
{
tmp = gfc_conv_descriptor_data_get (se.expr);
@@ -2024,7 +1982,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block
*block)
|| CLASS_DATA (sym)->attr.pointer)))
{
if (rank > 0)
- copy_descriptor (&se.post, se.expr, desc, rank);
+ gfc_copy_descriptor (&se.post, se.expr, desc, rank);
else
gfc_conv_descriptor_data_set (&se.post, se.expr, desc);
--
2.51.0