https://gcc.gnu.org/g:392e0d0281e160b600877d1874a316bc4a9dcc80

commit 392e0d0281e160b600877d1874a316bc4a9dcc80
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Jul 11 15:46:06 2025 +0200

    Sauvegarde 2

Diff:
---
 gcc/fortran/trans-array.cc | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 8d619022d9ef..9bdf60b7aeb5 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3474,31 +3474,38 @@ replace_tree_in_expr (tree t, tree expr, tree 
replacement)
    them by evaluating the leading part of the data reference to a variable,
    adding extra code to BLOCK.
 
-   To avoid copying large amounts of data we only save pointers in the 
reference
-   chain, and as late in the chain as possible.    */
+   The candidate references for factoring are dereferenced pointers because 
they
+   are cheap to copy and array descriptors because they are often the base of
+   multiple subreferences.    */
 
 static void
 set_factored_descriptor_value (stmtblock_t *block, tree *desc_ptr, tree value)
 {
-  /* As the reference is processed from last to first, statements will be
-     generated in reversed order, so can't be put directly in BLOCK.  We use
-     TMP_BLOCK instead.  */
+  /* As the reference is processed from outer to inner, variable definitions
+     will be generated in reversed order, so can't be put directly in BLOCK.
+     We use TMP_BLOCK instead.  */
   stmtblock_t tmp_block;
   tree accumulated_code = NULL_TREE;
 
   gfc_init_block (&tmp_block);
 
-  tree saveable_ref = nullptr;
+  tree saveable_ref = NULL_TREE;
 
   auto_vec<tree> replacement_roots;
   replacement_roots.safe_push (value);
 
   tree data_ref = value;
-  tree next_ref = nullptr;
-  bool seen_component = false;
+  tree next_ref = NULL_TREE;
+
+  /* If the candidate reference is not followed by a subreference, it can't be
+     saved to a variable as it may be reallocatable, and we have to keep the
+     parent reference to be able to store the new pointer value in case of
+     reallocation.  Otherwise it can be saved to a variable.  */
+  bool maybe_reallocatable = true;
+
   while (true)
     {
-      if (seen_component
+      if (!maybe_reallocatable
          && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (data_ref)))
        saveable_ref = data_ref;
 
@@ -3506,23 +3513,18 @@ set_factored_descriptor_value (stmtblock_t *block, tree 
*desc_ptr, tree value)
        {
          next_ref = TREE_OPERAND (data_ref, 0);
 
-         /* If there is no component reference after the pointer dereference in
-            the reference chain, the pointer can't be saved to a variable as 
-            it may be a pointer or allocatable, and we have to keep the parent
-            reference to be able to update the pointer value.  Otherwise the
-            pointer can be saved to a variable.  */
-         if (seen_component)
+         if (!maybe_reallocatable)
            {
              /* Don't evaluate the pointer to a variable yet; do it only if the
                 variable would be significantly more simple than the reference
                 it replaces.  That is if the reference contains anything
-                different from a NOP, a COMPONENT or a DECL.  */
+                different from a NOP, a COMPONENT and a DECL.  */
              saveable_ref = next_ref;
            }
        }
       else if (TREE_CODE (data_ref) == COMPONENT_REF)
        {
-         seen_component = true;
+         maybe_reallocatable = false;
          next_ref = TREE_OPERAND (data_ref, 0);
        }
       else if (TREE_CODE (data_ref) == NOP_EXPR)
@@ -3533,7 +3535,10 @@ set_factored_descriptor_value (stmtblock_t *block, tree 
*desc_ptr, tree value)
            break;
 
          if (TREE_CODE (data_ref) == ARRAY_REF)
-           next_ref = TREE_OPERAND (data_ref, 0);
+           {
+             maybe_reallocatable = false;
+             next_ref = TREE_OPERAND (data_ref, 0);
+           }
 
          if (saveable_ref != NULL_TREE)
            {

Reply via email to