diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 81f27ecdcb2..07350f469cc 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,14 @@ +2006-03-03 Roger Sayle + + * dependency.c (gfc_check_dependency): Call gfc_dep_resolver to + check whether two array references have a dependency. + (gfc_check_element_vs_element): Assume lref and rref must be + REF_ARRAYs. If gfc_dep_compare_expr returns -2, assume these + references could potentially overlap. + (gfc_dep_resolver): Whitespace and comment tweaks. Assume a + dependency if the references have different depths. Rewrite + final term to clarrify we only have a dependency for overlaps. + 2006-03-03 Thomas Koenig PR fortran/25031 @@ -28,7 +39,7 @@ (gfc_trans_where_assign): Likewise. (gfc_trans_where_2): Likewise. Restructure code that decides whether we need to allocate zero, one or two temporary masks. - If this is a top-level WHERE (i.e. the incoming MAKS is NULL), + If this is a top-level WHERE (i.e. the incoming MASK is NULL), we only need to allocate at most one temporary mask, and can invert it's sense to provide the complementary pending execution mask. Only calculate the size of the required temporary arrays diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index f764873dc07..187b2077716 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -460,16 +460,11 @@ gfc_check_dependency (gfc_expr * expr1, gfc_expr * expr2, bool identical) if (identical) return 1; - /* Identical ranges return 0, overlapping ranges return 1. */ - + /* Identical and disjoint ranges return 0, + overlapping ranges return 1. */ /* Return zero if we refer to the same full arrays. */ - if (expr1->ref->type == REF_ARRAY - && expr2->ref->type == REF_ARRAY - && expr1->ref->u.ar.type == AR_FULL - && expr2->ref->u.ar.type == AR_FULL - && !expr1->ref->next - && !expr2->ref->next) - return 0; + if (expr1->ref->type == REF_ARRAY && expr2->ref->type == REF_ARRAY) + return gfc_dep_resolver (expr1->ref, expr2->ref); return 1; @@ -735,30 +730,25 @@ gfc_check_element_vs_element (gfc_ref * lref, gfc_ref * rref, int n) gfc_array_ref r_ar; gfc_expr *l_start; gfc_expr *r_start; - gfc_dependency nIsDep; + int i; - if (lref->type == REF_ARRAY && rref->type == REF_ARRAY) - { - l_ar = lref->u.ar; - r_ar = rref->u.ar; - l_start = l_ar.start[n] ; - r_start = r_ar.start[n] ; - if (gfc_dep_compare_expr (r_start, l_start) == 0) - nIsDep = GFC_DEP_EQUAL; - else - nIsDep = GFC_DEP_NODEP; - } - else - nIsDep = GFC_DEP_NODEP; - - return nIsDep; + l_ar = lref->u.ar; + r_ar = rref->u.ar; + l_start = l_ar.start[n] ; + r_start = r_ar.start[n] ; + i = gfc_dep_compare_expr (r_start, l_start); + if (i == 0) + return GFC_DEP_EQUAL; + if (i == -2) + return GFC_DEP_OVERLAP; + return GFC_DEP_NODEP; } /* Finds if two array references are overlapping or not. Return value 1 : array references are overlapping. - 0 : array references are not overlapping. */ + 0 : array references are identical or not overlapping. */ int gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref) @@ -792,7 +782,6 @@ gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref) return 0; case REF_ARRAY: - for (n=0; n < lref->u.ar.dimen; n++) { /* Assume dependency when either of array reference is vector @@ -844,9 +833,10 @@ gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref) /* If we haven't seen any array refs then something went wrong. */ gcc_assert (fin_dep != GFC_DEP_ERROR); - if (fin_dep < GFC_DEP_OVERLAP) - return 0; - else + /* Assume the worst if we nest to different depths. */ + if (lref || rref) return 1; + + return fin_dep == GFC_DEP_OVERLAP; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f2c1d6a807c..c56b0f935f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-03-03 Roger Sayle + + * gfortran.dg/dependency_4.f90: New test case. + * gfortran.dg/dependency_5.f90: New test case. + * gfortran.dg/dependency_6.f90: New test case. + * gfortran.dg/dependency_7.f90: New test case. + * gfortran.dg/dependency_8.f90: New test case. + 2006-03-03 Paul Brook * gcc/testsuite/lib/target-supports.exp (check_profiling_available): diff --git a/gcc/testsuite/gfortran.dg/dependency_4.f90 b/gcc/testsuite/gfortran.dg/dependency_4.f90 new file mode 100644 index 00000000000..9eabaf1e587 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_4.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } +subroutine foo(a) + integer, dimension (4) :: a + + where (a .ne. 0) + a = 1 + endwhere +end subroutine +! { dg-final { scan-tree-dump-times "malloc" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/dependency_5.f90 b/gcc/testsuite/gfortran.dg/dependency_5.f90 new file mode 100644 index 00000000000..307fbd74868 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_5.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } +subroutine foo(a) + integer, dimension (4) :: a + + where (a(:) .ne. 0) + a(:) = 1 + endwhere +end subroutine +! { dg-final { scan-tree-dump-times "malloc" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/dependency_6.f90 b/gcc/testsuite/gfortran.dg/dependency_6.f90 new file mode 100644 index 00000000000..e90571ea978 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_6.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } +subroutine foo(a) + integer, dimension (4) :: a + + where (a(:4) .ne. 0) + a(:4) = 1 + endwhere +end subroutine +! { dg-final { scan-tree-dump-times "malloc" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/dependency_7.f90 b/gcc/testsuite/gfortran.dg/dependency_7.f90 new file mode 100644 index 00000000000..52bac8f9f61 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_7.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } +subroutine foo(a) + integer, dimension (4) :: a + + where (a(1:4) .ne. 0) + a(1:4) = 1 + endwhere +end subroutine +! { dg-final { scan-tree-dump-times "malloc" 0 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/dependency_8.f90 b/gcc/testsuite/gfortran.dg/dependency_8.f90 new file mode 100644 index 00000000000..e27f85a946f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_8.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-original" } +subroutine foo(a,i,j) + integer, dimension (4,4) :: a + integer :: i + integer :: j + + where (a(i,1:3) .ne. 0) + a(j,2:4) = 1 + endwhere +end subroutine +! { dg-final { scan-tree-dump-times "malloc" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } }