Commit 37311e71 by Roger Sayle Committed by Roger Sayle

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
parent 620b87b3
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
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
}
......
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
* gcc.dg/real-const-1.c: New test case.
! { 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" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment