aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-26 20:49:07 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-26 20:49:07 +0000
commita5c09be2d509aeba1efb986f8996d4847883cc5a (patch)
tree5fd7f043a01ee8f57edc669bddc40ed90dbc0c88
parentd51320157aee7ce2a4e2478c8457eae2022192fb (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/ChangeLog15
-rw-r--r--gcc/fortran/dependency.c33
-rw-r--r--gcc/fortran/gfortran.h6
-rw-r--r--gcc/fortran/trans-array.c2
-rw-r--r--gcc/fortran/trans-expr.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/dependency_40.f9029
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