trans.h (struct gfc_loopinfo): New field parent.
authorMikael Morin <mikael@gcc.gnu.org>
Thu, 3 Nov 2011 23:45:19 +0000 (23:45 +0000)
committerMikael Morin <mikael@gcc.gnu.org>
Thu, 3 Nov 2011 23:45:19 +0000 (23:45 +0000)
* trans.h (struct gfc_loopinfo): New field parent.
* trans-array.c (gfc_cleanup_loop): Free nested loops.
(gfc_add_ss_to_loop): Set nested_loop's parent loop.
(gfc_trans_array_constructor): Update assertion.
(gfc_conv_loop_setup): Ditto.

From-SVN: r180899

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/fortran/trans.h

index 653b262b81d5c8b7a1c399c1e5c3015e6984f663..89ba5847fde3b4491e2f0114e644ce87cce30c70 100644 (file)
@@ -1,3 +1,11 @@
+2011-11-03  Mikael Morin  <mikael@gcc.gnu.org>
+
+       * trans.h (struct gfc_loopinfo): New field parent.
+       * trans-array.c (gfc_cleanup_loop): Free nested loops.
+       (gfc_add_ss_to_loop): Set nested_loop's parent loop.
+       (gfc_trans_array_constructor): Update assertion.
+       (gfc_conv_loop_setup): Ditto.
+
 2011-11-03  Mikael Morin  <mikael@gcc.gnu.org>
 
        * trans-array.c (gfc_add_loop_ss_code): Skip non-nestedmost ss.
index 27356a1a1d33afed8dc8f0339beb8a4f1ab4824d..5659b70846e1949ad2a9f9d5322c5ab606d39b46 100644 (file)
@@ -604,6 +604,7 @@ gfc_get_scalar_ss (gfc_ss *next, gfc_expr *expr)
 void
 gfc_cleanup_loop (gfc_loopinfo * loop)
 {
+  gfc_loopinfo *loop_next, **ploop;
   gfc_ss *ss;
   gfc_ss *next;
 
@@ -615,6 +616,23 @@ gfc_cleanup_loop (gfc_loopinfo * loop)
       gfc_free_ss (ss);
       ss = next;
     }
+
+  /* Remove reference to self in the parent loop.  */
+  if (loop->parent)
+    for (ploop = &loop->parent->nested; *ploop; ploop = &(*ploop)->next)
+      if (*ploop == loop)
+       {
+         *ploop = loop->next;
+         break;
+       }
+
+  /* Free non-freed nested loops.  */
+  for (loop = loop->nested; loop; loop = loop_next)
+    {
+      loop_next = loop->next;
+      gfc_cleanup_loop (loop);
+      free (loop);
+    }
 }
 
 
@@ -664,10 +682,15 @@ gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
             added one, to avoid duplicate nested loops.  */
          if (nested_loop != loop->nested)
            {
+             gcc_assert (nested_loop->parent == NULL);
+             nested_loop->parent = loop;
+
              gcc_assert (nested_loop->next == NULL);
              nested_loop->next = loop->nested;
              loop->nested = nested_loop;
            }
+         else
+           gcc_assert (nested_loop->parent == loop);
        }
 
       if (ss->next == gfc_ss_terminator)
@@ -2158,6 +2181,7 @@ trans_array_constructor (gfc_ss * ss, locus * where)
       mpz_t size;
 
       /* We should have a 1-dimensional, zero-based loop.  */
+      gcc_assert (loop->parent == NULL && loop->nested == NULL);
       gcc_assert (loop->dimen == 1);
       gcc_assert (integer_zerop (loop->from[0]));
 
@@ -4302,6 +4326,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
 
       tmp_ss_info = tmp_ss->info;
       gcc_assert (tmp_ss_info->type == GFC_SS_TEMP);
+      gcc_assert (loop->parent == NULL);
 
       /* Make absolutely sure that this is a complete type.  */
       if (tmp_ss_info->string_length)
index 0549aa7930132a0de8dba3c3ce237cb3a6fe9409..4d745f144ceb205db9c6aec76ad08c815a654e23 100644 (file)
@@ -279,6 +279,9 @@ typedef struct gfc_loopinfo
   /* The SS describing the temporary used in an assignment.  */
   gfc_ss *temp_ss;
 
+  /* Non-null if this loop is nested in another one.  */
+  struct gfc_loopinfo *parent;
+
   /* Chain of nested loops.  */
   struct gfc_loopinfo *nested, *next;