From 4616ef9b8517396fc1b4edd6d1fcdbe3705c0892 Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Thu, 3 Nov 2011 23:45:19 +0000 Subject: [PATCH] trans.h (struct gfc_loopinfo): New field parent. * 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 | 8 ++++++++ gcc/fortran/trans-array.c | 25 +++++++++++++++++++++++++ gcc/fortran/trans.h | 3 +++ 3 files changed, 36 insertions(+) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 653b262b81d..89ba5847fde 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2011-11-03 Mikael Morin + + * 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 * trans-array.c (gfc_add_loop_ss_code): Skip non-nestedmost ss. diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 27356a1a1d3..5659b70846e 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -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) diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 0549aa79301..4d745f144ce 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -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; -- 2.30.2