summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0355-2011-05-26-Paul-Thomas-pault-gcc.gnu.org.patch
blob: 7f0518a1bd9a75b689db0b370a5965e52ae9cc3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
From a5c09be2d509aeba1efb986f8996d4847883cc5a Mon Sep 17 00:00:00 2001
From: pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 26 May 2011 20:49:07 +0000
Subject: [PATCH] 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

index 77e8df7..58cfb65 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 165bd2f..f20a29b 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 3d4a52a..b64e10d 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 1d678e6..ade7e54 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.  */
new file mode 100644
index 0000000..b7bd4f9
--- /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
-- 
1.7.0.4