diff options
author | pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-26 20:49:07 +0000 |
---|---|---|
committer | pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-26 20:49:07 +0000 |
commit | a5c09be2d509aeba1efb986f8996d4847883cc5a (patch) | |
tree | 5fd7f043a01ee8f57edc669bddc40ed90dbc0c88 | |
parent | d51320157aee7ce2a4e2478c8457eae2022192fb (diff) |
2011-05-26 Paul Thomas <pault@gcc.gnu.org>
Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/48955
* trans-expr.c (gfc_trans_assignment_1): GFC_REVERSE_NOT_SET
changed to GFC_ENABLE_REVERSE.
* trans-array.c (gfc_init_loopinfo): GFC_CANNOT_REVERSE changed
to GFC_INHIBIT_REVERSE.
* gfortran.h : Enum gfc_reverse is now GFC_ENABLE_REVERSE,
GFC_FORWARD_SET, GFC_REVERSE_SET and GFC_INHIBIT_REVERSE.
* dependency.c (gfc_dep_resolver): Change names for elements of
gfc_reverse as necessary. Change the logic so that forward
dependences are remembered as well as backward ones. When both
have appeared, force a temporary.
2011-05-26 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/48955
* gfortran.dg/dependency_40.f90 : New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174308 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/fortran/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/fortran/dependency.c | 33 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 2 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/dependency_40.f90 | 29 |
7 files changed, 76 insertions, 18 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0a5b8ced0bc..58360dd195b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2011-05-26 Paul Thomas <pault@gcc.gnu.org> + Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/48955 + * trans-expr.c (gfc_trans_assignment_1): GFC_REVERSE_NOT_SET + changed to GFC_ENABLE_REVERSE. + * trans-array.c (gfc_init_loopinfo): GFC_CANNOT_REVERSE changed + to GFC_INHIBIT_REVERSE. + * gfortran.h : Enum gfc_reverse is now GFC_ENABLE_REVERSE, + GFC_FORWARD_SET, GFC_REVERSE_SET and GFC_INHIBIT_REVERSE. + * dependency.c (gfc_dep_resolver): Change names for elements of + gfc_reverse as necessary. Change the logic so that forward + dependences are remembered as well as backward ones. When both + have appeared, force a temporary. + 2011-05-11 Tobias Burnus <burnus@net-b.de> PR fortran/48889 diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index 77e8df72b68..58cfb65bce1 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -1793,7 +1793,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) /* Now deal with the loop reversal logic: This only works on ranges and is activated by setting - reverse[n] == GFC_CAN_REVERSE + reverse[n] == GFC_ENABLE_REVERSE The ability to reverse or not is set by previous conditions in this dimension. If reversal is not activated, the value GFC_DEP_BACKWARD is reset to GFC_DEP_OVERLAP. */ @@ -1801,25 +1801,34 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) && lref->u.ar.dimen_type[n] == DIMEN_RANGE) { /* Set reverse if backward dependence and not inhibited. */ - if (reverse && reverse[n] != GFC_CANNOT_REVERSE) + if (reverse && reverse[n] == GFC_ENABLE_REVERSE) reverse[n] = (this_dep == GFC_DEP_BACKWARD) ? GFC_REVERSE_SET : reverse[n]; - /* Inhibit loop reversal if dependence not compatible. */ - if (reverse && reverse[n] != GFC_REVERSE_NOT_SET - && this_dep != GFC_DEP_EQUAL - && this_dep != GFC_DEP_BACKWARD - && this_dep != GFC_DEP_NODEP) + /* Set forward if forward dependence and not inhibited. */ + if (reverse && reverse[n] == GFC_ENABLE_REVERSE) + reverse[n] = (this_dep == GFC_DEP_FORWARD) ? + GFC_FORWARD_SET : reverse[n]; + + /* Flag up overlap if dependence not compatible with + the overall state of the expression. */ + if (reverse && reverse[n] == GFC_REVERSE_SET + && this_dep == GFC_DEP_FORWARD) + { + reverse[n] = GFC_INHIBIT_REVERSE; + this_dep = GFC_DEP_OVERLAP; + } + else if (reverse && reverse[n] == GFC_FORWARD_SET + && this_dep == GFC_DEP_BACKWARD) { - reverse[n] = GFC_CANNOT_REVERSE; - if (this_dep != GFC_DEP_FORWARD) - this_dep = GFC_DEP_OVERLAP; + reverse[n] = GFC_INHIBIT_REVERSE; + this_dep = GFC_DEP_OVERLAP; } /* If no intention of reversing or reversing is explicitly inhibited, convert backward dependence to overlap. */ - if (this_dep == GFC_DEP_BACKWARD - && (reverse == NULL || reverse[n] == GFC_CANNOT_REVERSE)) + if ((reverse == NULL && this_dep == GFC_DEP_BACKWARD) + || (reverse != NULL && reverse[n] == GFC_INHIBIT_REVERSE)) this_dep = GFC_DEP_OVERLAP; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 165bd2f23a3..f20a29bc7fa 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -578,10 +578,10 @@ gfc_fcoarray; typedef enum { - GFC_REVERSE_NOT_SET, + GFC_ENABLE_REVERSE, + GFC_FORWARD_SET, GFC_REVERSE_SET, - GFC_CAN_REVERSE, - GFC_CANNOT_REVERSE + GFC_INHIBIT_REVERSE } gfc_reverse; diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 3d4a52a7ebe..b64e10d6a10 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2223,7 +2223,7 @@ gfc_init_loopinfo (gfc_loopinfo * loop) for (n = 0; n < GFC_MAX_DIMENSIONS; n++) { loop->order[n] = n; - loop->reverse[n] = GFC_CANNOT_REVERSE; + loop->reverse[n] = GFC_INHIBIT_REVERSE; } loop->ss = gfc_ss_terminator; diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 1d678e63f5c..ade7e548522 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -6067,8 +6067,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, /* Calculate the bounds of the scalarization. */ gfc_conv_ss_startstride (&loop); /* Enable loop reversal. */ - for (n = 0; n < loop.dimen; n++) - loop.reverse[n] = GFC_REVERSE_NOT_SET; + for (n = 0; n < GFC_MAX_DIMENSIONS; n++) + loop.reverse[n] = GFC_ENABLE_REVERSE; /* Resolve any data dependencies in the statement. */ gfc_conv_resolve_dependencies (&loop, lss, rss); /* Setup the scalarizing loops. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b91e7e53624..1b3827802b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-05-26 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/48955 + * gfortran.dg/dependency_40.f90 : New test. + 2011-05-26 Jason Merrill <jason@redhat.com> * g++.dg/cpp0x/variadic111.C: New. diff --git a/gcc/testsuite/gfortran.dg/dependency_40.f90 b/gcc/testsuite/gfortran.dg/dependency_40.f90 new file mode 100644 index 00000000000..b7bd4f91184 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_40.f90 @@ -0,0 +1,29 @@ +! { dg-do run } +! PR 48955 - missing array temporary when there was both a forward +! and a backward dependency. +! Test case slightly modified from the original one by Kacper Kowalik. +program ala + implicit none + + integer, parameter :: n = 6 + real, dimension(n), parameter :: result = [1.,10.,30.,90.,270., 243.]; + real, dimension(n) :: v0, v1 + character(len=80) :: line1, line2 + + v0 = [1.0, 3.0, 9.0, 27.0, 81.0, 243.0] + v1 = v0 + + v1(2:n-1) = v1(1:n-2) + v1(3:n) + if (any(v1 /= result)) call abort + v1 = v0 + v1(2:n-1) = v0(1:n-2) + v0(3:n) + if (any(v1 /= result)) call abort + + v1 = v0 + v1(2:n-1) = v1(3:n) + v1(1:n-2) + if (any(v1 /= result)) call abort + v1 = v0 + v1(2:n-1) = v0(3:n) + v0(1:n-2) + if (any(v1 /= result)) call abort + +end program ala |