diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch | 805 |
1 files changed, 0 insertions, 805 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch deleted file mode 100644 index ea42ad6ee..000000000 --- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106843.patch +++ /dev/null | |||
@@ -1,805 +0,0 @@ | |||
1 | 2011-11-22 Ira Rosen <ira.rosen@linaro.org> | ||
2 | Backport from mainline: | ||
3 | |||
4 | 2011-11-06 Ira Rosen <ira.rosen@linaro.org> | ||
5 | |||
6 | gcc/ | ||
7 | * tree-vectorizer.h (vectorizable_condition): Add argument. | ||
8 | * tree-vect-loop.c (vectorizable_reduction): Fail for condition | ||
9 | in SLP. Update calls to vectorizable_condition. | ||
10 | * tree-vect-stmts.c (vect_is_simple_cond): Add basic block info to | ||
11 | the arguments. Pass it to vect_is_simple_use_1. | ||
12 | (vectorizable_condition): Add slp_node to the arguments. Support | ||
13 | vectorization of basic blocks. Fail for reduction in SLP. Update | ||
14 | calls to vect_is_simple_cond and vect_is_simple_use. Support SLP: | ||
15 | call vect_get_slp_defs to get vector operands. | ||
16 | (vect_analyze_stmt): Update calls to vectorizable_condition. | ||
17 | (vect_transform_stmt): Likewise. | ||
18 | * tree-vect-slp.c (vect_create_new_slp_node): Handle COND_EXPR. | ||
19 | (vect_get_and_check_slp_defs): Handle COND_EXPR. Allow pattern | ||
20 | def stmts. | ||
21 | (vect_build_slp_tree): Handle COND_EXPR. | ||
22 | (vect_analyze_slp_instance): Push pattern statements to root node. | ||
23 | (vect_get_constant_vectors): Fix comments. Handle COND_EXPR. | ||
24 | |||
25 | gcc/testsuite/ | ||
26 | * gcc.dg/vect/bb-slp-cond-1.c: New test. | ||
27 | * gcc.dg/vect/slp-cond-1.c: New test. | ||
28 | |||
29 | === added file 'gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c' | ||
30 | --- old/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c 1970-01-01 00:00:00 +0000 | ||
31 | +++ new/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c 2011-11-20 08:24:08 +0000 | ||
32 | @@ -0,0 +1,46 @@ | ||
33 | +/* { dg-require-effective-target vect_condition } */ | ||
34 | + | ||
35 | +#include "tree-vect.h" | ||
36 | + | ||
37 | +#define N 128 | ||
38 | + | ||
39 | +__attribute__((noinline, noclone)) void | ||
40 | +foo (int *a, int stride) | ||
41 | +{ | ||
42 | + int i; | ||
43 | + | ||
44 | + for (i = 0; i < N/stride; i++, a += stride) | ||
45 | + { | ||
46 | + a[0] = a[0] ? 1 : 5; | ||
47 | + a[1] = a[1] ? 2 : 6; | ||
48 | + a[2] = a[2] ? 3 : 7; | ||
49 | + a[3] = a[3] ? 4 : 8; | ||
50 | + } | ||
51 | +} | ||
52 | + | ||
53 | + | ||
54 | +int a[N]; | ||
55 | +int main () | ||
56 | +{ | ||
57 | + int i; | ||
58 | + | ||
59 | + check_vect (); | ||
60 | + | ||
61 | + for (i = 0; i < N; i++) | ||
62 | + a[i] = i; | ||
63 | + | ||
64 | + foo (a, 4); | ||
65 | + | ||
66 | + for (i = 1; i < N; i++) | ||
67 | + if (a[i] != i%4 + 1) | ||
68 | + abort (); | ||
69 | + | ||
70 | + if (a[0] != 5) | ||
71 | + abort (); | ||
72 | + | ||
73 | + return 0; | ||
74 | +} | ||
75 | + | ||
76 | +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ | ||
77 | +/* { dg-final { cleanup-tree-dump "slp" } } */ | ||
78 | + | ||
79 | |||
80 | === added file 'gcc/testsuite/gcc.dg/vect/slp-cond-1.c' | ||
81 | --- old/gcc/testsuite/gcc.dg/vect/slp-cond-1.c 1970-01-01 00:00:00 +0000 | ||
82 | +++ new/gcc/testsuite/gcc.dg/vect/slp-cond-1.c 2011-11-20 08:24:08 +0000 | ||
83 | @@ -0,0 +1,126 @@ | ||
84 | +/* { dg-require-effective-target vect_condition } */ | ||
85 | +#include "tree-vect.h" | ||
86 | + | ||
87 | +#define N 32 | ||
88 | +int a[N], b[N]; | ||
89 | +int d[N], e[N]; | ||
90 | +int k[N]; | ||
91 | + | ||
92 | +__attribute__((noinline, noclone)) void | ||
93 | +f1 (void) | ||
94 | +{ | ||
95 | + int i; | ||
96 | + for (i = 0; i < N/4; i++) | ||
97 | + { | ||
98 | + k[4*i] = a[4*i] < b[4*i] ? 17 : 0; | ||
99 | + k[4*i+1] = a[4*i+1] < b[4*i+1] ? 17 : 0; | ||
100 | + k[4*i+2] = a[4*i+2] < b[4*i+2] ? 17 : 0; | ||
101 | + k[4*i+3] = a[4*i+3] < b[4*i+3] ? 17 : 0; | ||
102 | + } | ||
103 | +} | ||
104 | + | ||
105 | +__attribute__((noinline, noclone)) void | ||
106 | +f2 (void) | ||
107 | +{ | ||
108 | + int i; | ||
109 | + for (i = 0; i < N/2; ++i) | ||
110 | + { | ||
111 | + k[2*i] = a[2*i] < b[2*i] ? 0 : 24; | ||
112 | + k[2*i+1] = a[2*i+1] < b[2*i+1] ? 7 : 4; | ||
113 | + } | ||
114 | +} | ||
115 | + | ||
116 | +__attribute__((noinline, noclone)) void | ||
117 | +f3 (void) | ||
118 | +{ | ||
119 | + int i; | ||
120 | + for (i = 0; i < N/2; ++i) | ||
121 | + { | ||
122 | + k[2*i] = a[2*i] < b[2*i] ? 51 : 12; | ||
123 | + k[2*i+1] = a[2*i+1] > b[2*i+1] ? 51 : 12; | ||
124 | + } | ||
125 | +} | ||
126 | + | ||
127 | +__attribute__((noinline, noclone)) void | ||
128 | +f4 (void) | ||
129 | +{ | ||
130 | + int i; | ||
131 | + for (i = 0; i < N/2; ++i) | ||
132 | + { | ||
133 | + int d0 = d[2*i], e0 = e[2*i]; | ||
134 | + int d1 = d[2*i+1], e1 = e[2*i+1]; | ||
135 | + k[2*i] = a[2*i] >= b[2*i] ? d0 : e0; | ||
136 | + k[2*i+1] = a[2*i+1] >= b[2*i+1] ? d1 : e1; | ||
137 | + } | ||
138 | +} | ||
139 | + | ||
140 | +int | ||
141 | +main () | ||
142 | +{ | ||
143 | + int i; | ||
144 | + | ||
145 | + check_vect (); | ||
146 | + | ||
147 | + for (i = 0; i < N; i++) | ||
148 | + { | ||
149 | + switch (i % 9) | ||
150 | + { | ||
151 | + case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break; | ||
152 | + case 1: a[i] = 0; b[i] = 0; break; | ||
153 | + case 2: a[i] = i + 1; b[i] = - i - 1; break; | ||
154 | + case 3: a[i] = i; b[i] = i + 7; break; | ||
155 | + case 4: a[i] = i; b[i] = i; break; | ||
156 | + case 5: a[i] = i + 16; b[i] = i + 3; break; | ||
157 | + case 6: a[i] = - i - 5; b[i] = - i; break; | ||
158 | + case 7: a[i] = - i; b[i] = - i; break; | ||
159 | + case 8: a[i] = - i; b[i] = - i - 7; break; | ||
160 | + } | ||
161 | + d[i] = i; | ||
162 | + e[i] = 2 * i; | ||
163 | + } | ||
164 | + f1 (); | ||
165 | + for (i = 0; i < N; i++) | ||
166 | + if (k[i] != ((i % 3) == 0 ? 17 : 0)) | ||
167 | + abort (); | ||
168 | + | ||
169 | + f2 (); | ||
170 | + for (i = 0; i < N; i++) | ||
171 | + { | ||
172 | + switch (i % 9) | ||
173 | + { | ||
174 | + case 0: | ||
175 | + case 6: | ||
176 | + if (k[i] != ((i/9 % 2) == 0 ? 0 : 7)) | ||
177 | + abort (); | ||
178 | + break; | ||
179 | + case 1: | ||
180 | + case 5: | ||
181 | + case 7: | ||
182 | + if (k[i] != ((i/9 % 2) == 0 ? 4 : 24)) | ||
183 | + abort (); | ||
184 | + break; | ||
185 | + case 2: | ||
186 | + case 4: | ||
187 | + case 8: | ||
188 | + if (k[i] != ((i/9 % 2) == 0 ? 24 : 4)) | ||
189 | + abort (); | ||
190 | + break; | ||
191 | + case 3: | ||
192 | + if (k[i] != ((i/9 % 2) == 0 ? 7 : 0)) | ||
193 | + abort (); | ||
194 | + break; | ||
195 | + } | ||
196 | + } | ||
197 | + | ||
198 | + f3 (); | ||
199 | + | ||
200 | + f4 (); | ||
201 | + for (i = 0; i < N; i++) | ||
202 | + if (k[i] != ((i % 3) == 0 ? e[i] : d[i])) | ||
203 | + abort (); | ||
204 | + | ||
205 | + return 0; | ||
206 | +} | ||
207 | + | ||
208 | +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ | ||
209 | +/* { dg-final { cleanup-tree-dump "vect" } } */ | ||
210 | |||
211 | === modified file 'gcc/tree-vect-loop.c' | ||
212 | --- old/gcc/tree-vect-loop.c 2011-11-14 11:38:08 +0000 | ||
213 | +++ new/gcc/tree-vect-loop.c 2011-11-20 08:24:08 +0000 | ||
214 | @@ -4087,6 +4087,9 @@ | ||
215 | gcc_unreachable (); | ||
216 | } | ||
217 | |||
218 | + if (code == COND_EXPR && slp_node) | ||
219 | + return false; | ||
220 | + | ||
221 | scalar_dest = gimple_assign_lhs (stmt); | ||
222 | scalar_type = TREE_TYPE (scalar_dest); | ||
223 | if (!POINTER_TYPE_P (scalar_type) && !INTEGRAL_TYPE_P (scalar_type) | ||
224 | @@ -4161,7 +4164,7 @@ | ||
225 | |||
226 | if (code == COND_EXPR) | ||
227 | { | ||
228 | - if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0)) | ||
229 | + if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0, NULL)) | ||
230 | { | ||
231 | if (vect_print_dump_info (REPORT_DETAILS)) | ||
232 | fprintf (vect_dump, "unsupported condition in reduction"); | ||
233 | @@ -4433,7 +4436,7 @@ | ||
234 | gcc_assert (!slp_node); | ||
235 | vectorizable_condition (stmt, gsi, vec_stmt, | ||
236 | PHI_RESULT (VEC_index (gimple, phis, 0)), | ||
237 | - reduc_index); | ||
238 | + reduc_index, NULL); | ||
239 | /* Multiple types are not supported for condition. */ | ||
240 | break; | ||
241 | } | ||
242 | |||
243 | === modified file 'gcc/tree-vect-slp.c' | ||
244 | --- old/gcc/tree-vect-slp.c 2011-11-14 11:38:08 +0000 | ||
245 | +++ new/gcc/tree-vect-slp.c 2011-11-21 06:58:40 +0000 | ||
246 | @@ -109,7 +109,11 @@ | ||
247 | if (is_gimple_call (stmt)) | ||
248 | nops = gimple_call_num_args (stmt); | ||
249 | else if (is_gimple_assign (stmt)) | ||
250 | - nops = gimple_num_ops (stmt) - 1; | ||
251 | + { | ||
252 | + nops = gimple_num_ops (stmt) - 1; | ||
253 | + if (gimple_assign_rhs_code (stmt) == COND_EXPR) | ||
254 | + nops = 4; | ||
255 | + } | ||
256 | else | ||
257 | return NULL; | ||
258 | |||
259 | @@ -190,20 +194,51 @@ | ||
260 | bool different_types = false; | ||
261 | bool pattern = false; | ||
262 | slp_oprnd_info oprnd_info, oprnd0_info, oprnd1_info; | ||
263 | + int op_idx = 1; | ||
264 | + tree compare_rhs = NULL_TREE, rhs = NULL_TREE; | ||
265 | + int cond_idx = -1; | ||
266 | |||
267 | if (loop_vinfo) | ||
268 | loop = LOOP_VINFO_LOOP (loop_vinfo); | ||
269 | |||
270 | if (is_gimple_call (stmt)) | ||
271 | number_of_oprnds = gimple_call_num_args (stmt); | ||
272 | + else if (is_gimple_assign (stmt)) | ||
273 | + { | ||
274 | + number_of_oprnds = gimple_num_ops (stmt) - 1; | ||
275 | + if (gimple_assign_rhs_code (stmt) == COND_EXPR) | ||
276 | + { | ||
277 | + number_of_oprnds = 4; | ||
278 | + cond_idx = 0; | ||
279 | + rhs = gimple_assign_rhs1 (stmt); | ||
280 | + } | ||
281 | + } | ||
282 | else | ||
283 | - number_of_oprnds = gimple_num_ops (stmt) - 1; | ||
284 | + return false; | ||
285 | |||
286 | for (i = 0; i < number_of_oprnds; i++) | ||
287 | { | ||
288 | - oprnd = gimple_op (stmt, i + 1); | ||
289 | + if (compare_rhs) | ||
290 | + oprnd = compare_rhs; | ||
291 | + else | ||
292 | + oprnd = gimple_op (stmt, op_idx++); | ||
293 | + | ||
294 | oprnd_info = VEC_index (slp_oprnd_info, *oprnds_info, i); | ||
295 | |||
296 | + if (-1 < cond_idx && cond_idx < 4) | ||
297 | + { | ||
298 | + if (compare_rhs) | ||
299 | + compare_rhs = NULL_TREE; | ||
300 | + else | ||
301 | + oprnd = TREE_OPERAND (rhs, cond_idx++); | ||
302 | + } | ||
303 | + | ||
304 | + if (COMPARISON_CLASS_P (oprnd)) | ||
305 | + { | ||
306 | + compare_rhs = TREE_OPERAND (oprnd, 1); | ||
307 | + oprnd = TREE_OPERAND (oprnd, 0); | ||
308 | + } | ||
309 | + | ||
310 | if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def, | ||
311 | &dt) | ||
312 | || (!def_stmt && dt != vect_constant_def)) | ||
313 | @@ -243,8 +278,7 @@ | ||
314 | def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); | ||
315 | dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); | ||
316 | |||
317 | - if (dt == vect_unknown_def_type | ||
318 | - || STMT_VINFO_PATTERN_DEF_STMT (vinfo_for_stmt (def_stmt))) | ||
319 | + if (dt == vect_unknown_def_type) | ||
320 | { | ||
321 | if (vect_print_dump_info (REPORT_DETAILS)) | ||
322 | fprintf (vect_dump, "Unsupported pattern."); | ||
323 | @@ -423,6 +457,7 @@ | ||
324 | VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node); | ||
325 | gimple stmt = VEC_index (gimple, stmts, 0); | ||
326 | enum tree_code first_stmt_code = ERROR_MARK, rhs_code = ERROR_MARK; | ||
327 | + enum tree_code first_cond_code = ERROR_MARK; | ||
328 | tree lhs; | ||
329 | bool stop_recursion = false, need_same_oprnds = false; | ||
330 | tree vectype, scalar_type, first_op1 = NULL_TREE; | ||
331 | @@ -439,11 +474,18 @@ | ||
332 | VEC (slp_oprnd_info, heap) *oprnds_info; | ||
333 | unsigned int nops; | ||
334 | slp_oprnd_info oprnd_info; | ||
335 | + tree cond; | ||
336 | |||
337 | if (is_gimple_call (stmt)) | ||
338 | nops = gimple_call_num_args (stmt); | ||
339 | + else if (is_gimple_assign (stmt)) | ||
340 | + { | ||
341 | + nops = gimple_num_ops (stmt) - 1; | ||
342 | + if (gimple_assign_rhs_code (stmt) == COND_EXPR) | ||
343 | + nops = 4; | ||
344 | + } | ||
345 | else | ||
346 | - nops = gimple_num_ops (stmt) - 1; | ||
347 | + return false; | ||
348 | |||
349 | oprnds_info = vect_create_oprnd_info (nops, group_size); | ||
350 | |||
351 | @@ -484,6 +526,22 @@ | ||
352 | return false; | ||
353 | } | ||
354 | |||
355 | + if (is_gimple_assign (stmt) | ||
356 | + && gimple_assign_rhs_code (stmt) == COND_EXPR | ||
357 | + && (cond = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)) | ||
358 | + && !COMPARISON_CLASS_P (cond)) | ||
359 | + { | ||
360 | + if (vect_print_dump_info (REPORT_SLP)) | ||
361 | + { | ||
362 | + fprintf (vect_dump, | ||
363 | + "Build SLP failed: condition is not comparison "); | ||
364 | + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
365 | + } | ||
366 | + | ||
367 | + vect_free_oprnd_info (&oprnds_info); | ||
368 | + return false; | ||
369 | + } | ||
370 | + | ||
371 | scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy); | ||
372 | vectype = get_vectype_for_scalar_type (scalar_type); | ||
373 | if (!vectype) | ||
374 | @@ -737,7 +795,8 @@ | ||
375 | |||
376 | /* Not memory operation. */ | ||
377 | if (TREE_CODE_CLASS (rhs_code) != tcc_binary | ||
378 | - && TREE_CODE_CLASS (rhs_code) != tcc_unary) | ||
379 | + && TREE_CODE_CLASS (rhs_code) != tcc_unary | ||
380 | + && rhs_code != COND_EXPR) | ||
381 | { | ||
382 | if (vect_print_dump_info (REPORT_SLP)) | ||
383 | { | ||
384 | @@ -750,6 +809,26 @@ | ||
385 | return false; | ||
386 | } | ||
387 | |||
388 | + if (rhs_code == COND_EXPR) | ||
389 | + { | ||
390 | + tree cond_expr = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); | ||
391 | + | ||
392 | + if (i == 0) | ||
393 | + first_cond_code = TREE_CODE (cond_expr); | ||
394 | + else if (first_cond_code != TREE_CODE (cond_expr)) | ||
395 | + { | ||
396 | + if (vect_print_dump_info (REPORT_SLP)) | ||
397 | + { | ||
398 | + fprintf (vect_dump, "Build SLP failed: different" | ||
399 | + " operation"); | ||
400 | + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
401 | + } | ||
402 | + | ||
403 | + vect_free_oprnd_info (&oprnds_info); | ||
404 | + return false; | ||
405 | + } | ||
406 | + } | ||
407 | + | ||
408 | /* Find the def-stmts. */ | ||
409 | if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, stmt, | ||
410 | ncopies_for_cost, (i == 0), | ||
411 | @@ -1395,7 +1474,12 @@ | ||
412 | /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */ | ||
413 | while (next) | ||
414 | { | ||
415 | - VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
416 | + if (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (next)) | ||
417 | + && STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next))) | ||
418 | + VEC_safe_push (gimple, heap, scalar_stmts, | ||
419 | + STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next))); | ||
420 | + else | ||
421 | + VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
422 | next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next)); | ||
423 | } | ||
424 | } | ||
425 | @@ -1404,7 +1488,7 @@ | ||
426 | /* Collect reduction statements. */ | ||
427 | VEC (gimple, heap) *reductions = LOOP_VINFO_REDUCTIONS (loop_vinfo); | ||
428 | for (i = 0; VEC_iterate (gimple, reductions, i, next); i++) | ||
429 | - VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
430 | + VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
431 | } | ||
432 | |||
433 | node = vect_create_new_slp_node (scalar_stmts); | ||
434 | @@ -2160,15 +2244,15 @@ | ||
435 | |||
436 | For example, we have two scalar operands, s1 and s2 (e.g., group of | ||
437 | strided accesses of size two), while NUNITS is four (i.e., four scalars | ||
438 | - of this type can be packed in a vector). The output vector will contain | ||
439 | - two copies of each scalar operand: {s1, s2, s1, s2}. (NUMBER_OF_COPIES | ||
440 | + of this type can be packed in a vector). The output vector will contain | ||
441 | + two copies of each scalar operand: {s1, s2, s1, s2}. (NUMBER_OF_COPIES | ||
442 | will be 2). | ||
443 | |||
444 | If GROUP_SIZE > NUNITS, the scalars will be split into several vectors | ||
445 | containing the operands. | ||
446 | |||
447 | For example, NUNITS is four as before, and the group size is 8 | ||
448 | - (s1, s2, ..., s8). We will create two vectors {s1, s2, s3, s4} and | ||
449 | + (s1, s2, ..., s8). We will create two vectors {s1, s2, s3, s4} and | ||
450 | {s5, s6, s7, s8}. */ | ||
451 | |||
452 | number_of_copies = least_common_multiple (nunits, group_size) / group_size; | ||
453 | @@ -2180,8 +2264,18 @@ | ||
454 | { | ||
455 | if (is_store) | ||
456 | op = gimple_assign_rhs1 (stmt); | ||
457 | - else | ||
458 | + else if (gimple_assign_rhs_code (stmt) != COND_EXPR) | ||
459 | op = gimple_op (stmt, op_num + 1); | ||
460 | + else | ||
461 | + { | ||
462 | + if (op_num == 0 || op_num == 1) | ||
463 | + { | ||
464 | + tree cond = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); | ||
465 | + op = TREE_OPERAND (cond, op_num); | ||
466 | + } | ||
467 | + else | ||
468 | + op = TREE_OPERAND (gimple_assign_rhs1 (stmt), op_num - 1); | ||
469 | + } | ||
470 | |||
471 | if (reduc_index != -1) | ||
472 | { | ||
473 | |||
474 | === modified file 'gcc/tree-vect-stmts.c' | ||
475 | --- old/gcc/tree-vect-stmts.c 2011-11-22 16:52:23 +0000 | ||
476 | +++ new/gcc/tree-vect-stmts.c 2011-11-22 17:10:17 +0000 | ||
477 | @@ -4816,7 +4816,7 @@ | ||
478 | condition operands are supportable using vec_is_simple_use. */ | ||
479 | |||
480 | static bool | ||
481 | -vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) | ||
482 | +vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) | ||
483 | { | ||
484 | tree lhs, rhs; | ||
485 | tree def; | ||
486 | @@ -4831,7 +4831,7 @@ | ||
487 | if (TREE_CODE (lhs) == SSA_NAME) | ||
488 | { | ||
489 | gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); | ||
490 | - if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def, | ||
491 | + if (!vect_is_simple_use (lhs, loop_vinfo, bb_vinfo, &lhs_def_stmt, &def, | ||
492 | &dt)) | ||
493 | return false; | ||
494 | } | ||
495 | @@ -4842,7 +4842,7 @@ | ||
496 | if (TREE_CODE (rhs) == SSA_NAME) | ||
497 | { | ||
498 | gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); | ||
499 | - if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def, | ||
500 | + if (!vect_is_simple_use (rhs, loop_vinfo, bb_vinfo, &rhs_def_stmt, &def, | ||
501 | &dt)) | ||
502 | return false; | ||
503 | } | ||
504 | @@ -4868,7 +4868,8 @@ | ||
505 | |||
506 | bool | ||
507 | vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, | ||
508 | - gimple *vec_stmt, tree reduc_def, int reduc_index) | ||
509 | + gimple *vec_stmt, tree reduc_def, int reduc_index, | ||
510 | + slp_tree slp_node) | ||
511 | { | ||
512 | tree scalar_dest = NULL_TREE; | ||
513 | tree vec_dest = NULL_TREE; | ||
514 | @@ -4885,19 +4886,24 @@ | ||
515 | tree def; | ||
516 | enum vect_def_type dt, dts[4]; | ||
517 | int nunits = TYPE_VECTOR_SUBPARTS (vectype); | ||
518 | - int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; | ||
519 | + int ncopies; | ||
520 | enum tree_code code; | ||
521 | stmt_vec_info prev_stmt_info = NULL; | ||
522 | - int j; | ||
523 | + int i, j; | ||
524 | + bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); | ||
525 | + VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL; | ||
526 | + VEC (tree, heap) *vec_oprnds2 = NULL, *vec_oprnds3 = NULL; | ||
527 | |||
528 | - /* FORNOW: unsupported in basic block SLP. */ | ||
529 | - gcc_assert (loop_vinfo); | ||
530 | + if (slp_node || PURE_SLP_STMT (stmt_info)) | ||
531 | + ncopies = 1; | ||
532 | + else | ||
533 | + ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; | ||
534 | |||
535 | gcc_assert (ncopies >= 1); | ||
536 | - if (reduc_index && ncopies > 1) | ||
537 | + if (reduc_index && (ncopies > 1 || STMT_SLP_TYPE (stmt_info))) | ||
538 | return false; /* FORNOW */ | ||
539 | |||
540 | - if (!STMT_VINFO_RELEVANT_P (stmt_info)) | ||
541 | + if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo) | ||
542 | return false; | ||
543 | |||
544 | if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def | ||
545 | @@ -4905,10 +4911,6 @@ | ||
546 | && reduc_def)) | ||
547 | return false; | ||
548 | |||
549 | - /* FORNOW: SLP not supported. */ | ||
550 | - if (STMT_SLP_TYPE (stmt_info)) | ||
551 | - return false; | ||
552 | - | ||
553 | /* FORNOW: not yet supported. */ | ||
554 | if (STMT_VINFO_LIVE_P (stmt_info)) | ||
555 | { | ||
556 | @@ -4932,7 +4934,7 @@ | ||
557 | then_clause = TREE_OPERAND (op, 1); | ||
558 | else_clause = TREE_OPERAND (op, 2); | ||
559 | |||
560 | - if (!vect_is_simple_cond (cond_expr, loop_vinfo)) | ||
561 | + if (!vect_is_simple_cond (cond_expr, loop_vinfo, bb_vinfo)) | ||
562 | return false; | ||
563 | |||
564 | /* We do not handle two different vector types for the condition | ||
565 | @@ -4944,7 +4946,7 @@ | ||
566 | if (TREE_CODE (then_clause) == SSA_NAME) | ||
567 | { | ||
568 | gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause); | ||
569 | - if (!vect_is_simple_use (then_clause, loop_vinfo, NULL, | ||
570 | + if (!vect_is_simple_use (then_clause, loop_vinfo, bb_vinfo, | ||
571 | &then_def_stmt, &def, &dt)) | ||
572 | return false; | ||
573 | } | ||
574 | @@ -4956,7 +4958,7 @@ | ||
575 | if (TREE_CODE (else_clause) == SSA_NAME) | ||
576 | { | ||
577 | gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause); | ||
578 | - if (!vect_is_simple_use (else_clause, loop_vinfo, NULL, | ||
579 | + if (!vect_is_simple_use (else_clause, loop_vinfo, bb_vinfo, | ||
580 | &else_def_stmt, &def, &dt)) | ||
581 | return false; | ||
582 | } | ||
583 | @@ -4974,7 +4976,15 @@ | ||
584 | return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode); | ||
585 | } | ||
586 | |||
587 | - /* Transform */ | ||
588 | + /* Transform. */ | ||
589 | + | ||
590 | + if (!slp_node) | ||
591 | + { | ||
592 | + vec_oprnds0 = VEC_alloc (tree, heap, 1); | ||
593 | + vec_oprnds1 = VEC_alloc (tree, heap, 1); | ||
594 | + vec_oprnds2 = VEC_alloc (tree, heap, 1); | ||
595 | + vec_oprnds3 = VEC_alloc (tree, heap, 1); | ||
596 | + } | ||
597 | |||
598 | /* Handle def. */ | ||
599 | scalar_dest = gimple_assign_lhs (stmt); | ||
600 | @@ -4983,67 +4993,118 @@ | ||
601 | /* Handle cond expr. */ | ||
602 | for (j = 0; j < ncopies; j++) | ||
603 | { | ||
604 | - gimple new_stmt; | ||
605 | + gimple new_stmt = NULL; | ||
606 | if (j == 0) | ||
607 | { | ||
608 | - gimple gtemp; | ||
609 | - vec_cond_lhs = | ||
610 | + if (slp_node) | ||
611 | + { | ||
612 | + VEC (tree, heap) *ops = VEC_alloc (tree, heap, 4); | ||
613 | + VEC (slp_void_p, heap) *vec_defs; | ||
614 | + | ||
615 | + vec_defs = VEC_alloc (slp_void_p, heap, 4); | ||
616 | + VEC_safe_push (tree, heap, ops, TREE_OPERAND (cond_expr, 0)); | ||
617 | + VEC_safe_push (tree, heap, ops, TREE_OPERAND (cond_expr, 1)); | ||
618 | + VEC_safe_push (tree, heap, ops, then_clause); | ||
619 | + VEC_safe_push (tree, heap, ops, else_clause); | ||
620 | + vect_get_slp_defs (ops, slp_node, &vec_defs, -1); | ||
621 | + vec_oprnds3 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs); | ||
622 | + vec_oprnds2 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs); | ||
623 | + vec_oprnds1 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs); | ||
624 | + vec_oprnds0 = (VEC (tree, heap) *) VEC_pop (slp_void_p, vec_defs); | ||
625 | + | ||
626 | + VEC_free (tree, heap, ops); | ||
627 | + VEC_free (slp_void_p, heap, vec_defs); | ||
628 | + } | ||
629 | + else | ||
630 | + { | ||
631 | + gimple gtemp; | ||
632 | + vec_cond_lhs = | ||
633 | vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), | ||
634 | stmt, NULL); | ||
635 | - vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo, | ||
636 | + vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo, | ||
637 | NULL, >emp, &def, &dts[0]); | ||
638 | - vec_cond_rhs = | ||
639 | - vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), | ||
640 | - stmt, NULL); | ||
641 | - vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo, | ||
642 | - NULL, >emp, &def, &dts[1]); | ||
643 | - if (reduc_index == 1) | ||
644 | - vec_then_clause = reduc_def; | ||
645 | - else | ||
646 | - { | ||
647 | - vec_then_clause = vect_get_vec_def_for_operand (then_clause, | ||
648 | - stmt, NULL); | ||
649 | - vect_is_simple_use (then_clause, loop_vinfo, | ||
650 | - NULL, >emp, &def, &dts[2]); | ||
651 | - } | ||
652 | - if (reduc_index == 2) | ||
653 | - vec_else_clause = reduc_def; | ||
654 | - else | ||
655 | - { | ||
656 | - vec_else_clause = vect_get_vec_def_for_operand (else_clause, | ||
657 | - stmt, NULL); | ||
658 | - vect_is_simple_use (else_clause, loop_vinfo, | ||
659 | + | ||
660 | + vec_cond_rhs = | ||
661 | + vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), | ||
662 | + stmt, NULL); | ||
663 | + vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo, | ||
664 | + NULL, >emp, &def, &dts[1]); | ||
665 | + if (reduc_index == 1) | ||
666 | + vec_then_clause = reduc_def; | ||
667 | + else | ||
668 | + { | ||
669 | + vec_then_clause = vect_get_vec_def_for_operand (then_clause, | ||
670 | + stmt, NULL); | ||
671 | + vect_is_simple_use (then_clause, loop_vinfo, | ||
672 | + NULL, >emp, &def, &dts[2]); | ||
673 | + } | ||
674 | + if (reduc_index == 2) | ||
675 | + vec_else_clause = reduc_def; | ||
676 | + else | ||
677 | + { | ||
678 | + vec_else_clause = vect_get_vec_def_for_operand (else_clause, | ||
679 | + stmt, NULL); | ||
680 | + vect_is_simple_use (else_clause, loop_vinfo, | ||
681 | NULL, >emp, &def, &dts[3]); | ||
682 | + } | ||
683 | } | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | - vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs); | ||
688 | - vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs); | ||
689 | + vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], | ||
690 | + VEC_pop (tree, vec_oprnds0)); | ||
691 | + vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], | ||
692 | + VEC_pop (tree, vec_oprnds1)); | ||
693 | vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2], | ||
694 | - vec_then_clause); | ||
695 | + VEC_pop (tree, vec_oprnds2)); | ||
696 | vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3], | ||
697 | - vec_else_clause); | ||
698 | + VEC_pop (tree, vec_oprnds3)); | ||
699 | + } | ||
700 | + | ||
701 | + if (!slp_node) | ||
702 | + { | ||
703 | + VEC_quick_push (tree, vec_oprnds0, vec_cond_lhs); | ||
704 | + VEC_quick_push (tree, vec_oprnds1, vec_cond_rhs); | ||
705 | + VEC_quick_push (tree, vec_oprnds2, vec_then_clause); | ||
706 | + VEC_quick_push (tree, vec_oprnds3, vec_else_clause); | ||
707 | } | ||
708 | |||
709 | /* Arguments are ready. Create the new vector stmt. */ | ||
710 | - vec_compare = build2 (TREE_CODE (cond_expr), vectype, | ||
711 | - vec_cond_lhs, vec_cond_rhs); | ||
712 | - vec_cond_expr = build3 (VEC_COND_EXPR, vectype, | ||
713 | - vec_compare, vec_then_clause, vec_else_clause); | ||
714 | - | ||
715 | - new_stmt = gimple_build_assign (vec_dest, vec_cond_expr); | ||
716 | - new_temp = make_ssa_name (vec_dest, new_stmt); | ||
717 | - gimple_assign_set_lhs (new_stmt, new_temp); | ||
718 | - vect_finish_stmt_generation (stmt, new_stmt, gsi); | ||
719 | - if (j == 0) | ||
720 | - STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; | ||
721 | - else | ||
722 | - STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; | ||
723 | - | ||
724 | - prev_stmt_info = vinfo_for_stmt (new_stmt); | ||
725 | + FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vec_cond_lhs) | ||
726 | + { | ||
727 | + vec_cond_rhs = VEC_index (tree, vec_oprnds1, i); | ||
728 | + vec_then_clause = VEC_index (tree, vec_oprnds2, i); | ||
729 | + vec_else_clause = VEC_index (tree, vec_oprnds3, i); | ||
730 | + | ||
731 | + vec_compare = build2 (TREE_CODE (cond_expr), vectype, | ||
732 | + vec_cond_lhs, vec_cond_rhs); | ||
733 | + vec_cond_expr = build3 (VEC_COND_EXPR, vectype, | ||
734 | + vec_compare, vec_then_clause, vec_else_clause); | ||
735 | + | ||
736 | + new_stmt = gimple_build_assign (vec_dest, vec_cond_expr); | ||
737 | + new_temp = make_ssa_name (vec_dest, new_stmt); | ||
738 | + gimple_assign_set_lhs (new_stmt, new_temp); | ||
739 | + vect_finish_stmt_generation (stmt, new_stmt, gsi); | ||
740 | + if (slp_node) | ||
741 | + VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt); | ||
742 | + } | ||
743 | + | ||
744 | + if (slp_node) | ||
745 | + continue; | ||
746 | + | ||
747 | + if (j == 0) | ||
748 | + STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; | ||
749 | + else | ||
750 | + STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; | ||
751 | + | ||
752 | + prev_stmt_info = vinfo_for_stmt (new_stmt); | ||
753 | } | ||
754 | |||
755 | + VEC_free (tree, heap, vec_oprnds0); | ||
756 | + VEC_free (tree, heap, vec_oprnds1); | ||
757 | + VEC_free (tree, heap, vec_oprnds2); | ||
758 | + VEC_free (tree, heap, vec_oprnds3); | ||
759 | + | ||
760 | return true; | ||
761 | } | ||
762 | |||
763 | @@ -5217,7 +5278,7 @@ | ||
764 | || vectorizable_call (stmt, NULL, NULL) | ||
765 | || vectorizable_store (stmt, NULL, NULL, NULL) | ||
766 | || vectorizable_reduction (stmt, NULL, NULL, NULL) | ||
767 | - || vectorizable_condition (stmt, NULL, NULL, NULL, 0)); | ||
768 | + || vectorizable_condition (stmt, NULL, NULL, NULL, 0, NULL)); | ||
769 | else | ||
770 | { | ||
771 | if (bb_vinfo) | ||
772 | @@ -5227,7 +5288,8 @@ | ||
773 | || vectorizable_operation (stmt, NULL, NULL, node) | ||
774 | || vectorizable_assignment (stmt, NULL, NULL, node) | ||
775 | || vectorizable_load (stmt, NULL, NULL, node, NULL) | ||
776 | - || vectorizable_store (stmt, NULL, NULL, node)); | ||
777 | + || vectorizable_store (stmt, NULL, NULL, node) | ||
778 | + || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)); | ||
779 | } | ||
780 | |||
781 | if (!ok) | ||
782 | @@ -5343,8 +5405,7 @@ | ||
783 | break; | ||
784 | |||
785 | case condition_vec_info_type: | ||
786 | - gcc_assert (!slp_node); | ||
787 | - done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0); | ||
788 | + done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0, slp_node); | ||
789 | gcc_assert (done); | ||
790 | break; | ||
791 | |||
792 | |||
793 | === modified file 'gcc/tree-vectorizer.h' | ||
794 | --- old/gcc/tree-vectorizer.h 2011-11-22 16:52:23 +0000 | ||
795 | +++ new/gcc/tree-vectorizer.h 2011-11-22 17:10:17 +0000 | ||
796 | @@ -832,7 +832,7 @@ | ||
797 | extern void vect_remove_stores (gimple); | ||
798 | extern bool vect_analyze_stmt (gimple, bool *, slp_tree); | ||
799 | extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *, | ||
800 | - tree, int); | ||
801 | + tree, int, slp_tree); | ||
802 | extern void vect_get_load_cost (struct data_reference *, int, bool, | ||
803 | unsigned int *, unsigned int *); | ||
804 | extern void vect_get_store_cost (struct data_reference *, int, unsigned int *); | ||
805 | |||