From 37311e710c998b30f5d535b0cd98b5aa88db14cc Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 17 Mar 2006 00:02:53 +0000 Subject: [PATCH] gfortran.h (gfc_equiv_info): Add length field. * gfortran.h (gfc_equiv_info): Add length field. * trans-common.c (copy_equiv_list_to_ns): Set the length field. * dependency.c (gfc_are_equivalenced_arrays): Use both the offset and length fields to determine whether the two equivalenced symbols overlap in memory. * gfortran.dg/dependency_13.f90: New test case. From-SVN: r112162 --- gcc/fortran/ChangeLog | 8 +++++ gcc/fortran/dependency.c | 38 ++++++++++++++++----- gcc/fortran/gfortran.h | 1 + gcc/fortran/trans-common.c | 1 + gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gfortran.dg/dependency_13.f90 | 13 +++++++ 6 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/dependency_13.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b09d32e3801..61bbcfdd41b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2006-03-16 Roger Sayle + + * gfortran.h (gfc_equiv_info): Add length field. + * trans-common.c (copy_equiv_list_to_ns): Set the length field. + * dependency.c (gfc_are_equivalenced_arrays): Use both the offset + and length fields to determine whether the two equivalenced symbols + overlap in memory. + 2006-03-14 Jerry DeLisle PR fortran/19101 diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index d60b7ebbceb..03cabf05be9 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -414,10 +414,13 @@ gfc_check_fncall_dependency (gfc_expr * other, sym_intent intent, directly or indirectly; ie. equivalence (a,b) for a and b or equivalence (a,c),(b,c). This function uses the equiv_ lists, generated in trans-common(add_equivalences), that are - guaranteed to pick up indirect equivalences. A rudimentary - use is made of the offset to ensure that cases where the - source elements are moved down to the destination are not - identified as dependencies. */ + guaranteed to pick up indirect equivalences. We explicitly + check for overlap using the offset and length of the equivalence. + This function is symmetric. + TODO: This function only checks whether the full top-level + symbols overlap. An improved implementation could inspect + e1->ref and e2->ref to determine whether the actually accessed + portions of these variables/arrays potentially overlap. */ int gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2) @@ -444,14 +447,33 @@ gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2) for (s = l->equiv; s; s = s->next) { if (s->sym == e1->symtree->n.sym) - fl1 = s; + { + fl1 = s; + if (fl2) + break; + } if (s->sym == e2->symtree->n.sym) - fl2 = s; - if (fl1 && fl2 && (fl1->offset > fl2->offset)) + { + fl2 = s; + if (fl1) + break; + } + } + + if (s) + { + /* Can these lengths be zero? */ + if (fl1->length <= 0 || fl2->length <= 0) + return 1; + /* These can't overlap if [f11,fl1+length] is before + [fl2,fl2+length], or [fl2,fl2+length] is before + [fl1,fl1+length], otherwise they do overlap. */ + if (fl1->offset + fl1->length > fl2->offset + && fl2->offset + fl2->length > fl1->offset) return 1; } } -return 0; + return 0; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 2a5d01c344e..24c92b3e0eb 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1352,6 +1352,7 @@ typedef struct gfc_equiv_info { gfc_symbol *sym; HOST_WIDE_INT offset; + HOST_WIDE_INT length; struct gfc_equiv_info *next; } gfc_equiv_info; diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 3b34b334c2c..3b16e5e0065 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -169,6 +169,7 @@ copy_equiv_list_to_ns (segment_info *c) l->equiv = s; s->sym = f->sym; s->offset = f->offset; + s->length = f->length; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 90dc7004ae1..63fa39dbf52 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-03-16 Roger Sayle + + * gfortran.dg/dependency_13.f90: New test case. + 2006-03-16 Roger Sayle PR middle-end/21781 diff --git a/gcc/testsuite/gfortran.dg/dependency_13.f90 b/gcc/testsuite/gfortran.dg/dependency_13.f90 new file mode 100644 index 00000000000..85fb9779510 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_13.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } + integer :: i(5) + real(4) :: x(5) + equivalence(x,i) + + i = (/ 1, 0, 3, 5, 0 /) + where (i(1:4) .ne. 0) + x(2:5) = -42. + end where + end +! { dg-final { scan-tree-dump-times "malloc" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } } -- 2.30.2