gfortran.h (gfc_equiv_info): Add length field.
authorRoger Sayle <roger@eyesopen.com>
Fri, 17 Mar 2006 00:02:53 +0000 (00:02 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 17 Mar 2006 00:02:53 +0000 (00:02 +0000)
* 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
gcc/fortran/dependency.c
gcc/fortran/gfortran.h
gcc/fortran/trans-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dependency_13.f90 [new file with mode: 0644]

index b09d32e3801dfba5955c034243563368d58e6029..61bbcfdd41b4f2e464b29954e05561d54e3b8495 100644 (file)
@@ -1,3 +1,11 @@
+2006-03-16  Roger Sayle  <roger@eyesopen.com>
+
+       * 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  <jvdelisle@gcc.gnu.org>
 
        PR fortran/19101
index d60b7ebbcebcfc2e9b26863e9dd7826c95d80425..03cabf05be925c8e530f7c94f16a64f9768589ca 100644 (file)
@@ -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;
 }
 
 
index 2a5d01c344e59be8482426a98426093ef15ce249..24c92b3e0eb02eddb63d4f724d8a615fe75fa32a 100644 (file)
@@ -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;
 
index 3b34b334c2c7fd2a9ad531518ab07ae783954242..3b16e5e006554ccad5141eb60dec644ff781bba9 100644 (file)
@@ -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;
     }
 }
 
index 90dc7004ae1085e8f6629ee97af489a61f2984ba..63fa39dbf52d9f55b0c7eb4755156e9820647c4f 100644 (file)
@@ -1,3 +1,7 @@
+2006-03-16  Roger Sayle  <roger@eyesopen.com>
+
+       * gfortran.dg/dependency_13.f90: New test case.
+
 2006-03-16  Roger Sayle  <roger@eyesopen.com>
 
        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 (file)
index 0000000..85fb977
--- /dev/null
@@ -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" } }