diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106733.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106733.patch | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106733.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106733.patch deleted file mode 100644 index 4b0079e1dc..0000000000 --- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106733.patch +++ /dev/null | |||
@@ -1,653 +0,0 @@ | |||
1 | 2011-03-27 Ira Rosen <ira.rosen@linaro.org> | ||
2 | |||
3 | gcc/ | ||
4 | * doc/invoke.texi (max-stores-to-sink): Document. | ||
5 | * params.h (MAX_STORES_TO_SINK): Define. | ||
6 | * opts.c (finish_options): Set MAX_STORES_TO_SINK to 0 | ||
7 | if either vectorization or if-conversion is disabled. | ||
8 | * tree-data-ref.c (dr_equal_offsets_p1): Moved and renamed from | ||
9 | tree-vect-data-refs.c vect_equal_offsets. | ||
10 | (dr_equal_offsets_p): New function. | ||
11 | (find_data_references_in_bb): Remove static. | ||
12 | * tree-data-ref.h (find_data_references_in_bb): Declare. | ||
13 | (dr_equal_offsets_p): Likewise. | ||
14 | * tree-vect-data-refs.c (vect_equal_offsets): Move to tree-data-ref.c. | ||
15 | (vect_drs_dependent_in_basic_block): Update calls to | ||
16 | vect_equal_offsets. | ||
17 | (vect_check_interleaving): Likewise. | ||
18 | * tree-ssa-phiopt.c: Include cfgloop.h and tree-data-ref.h. | ||
19 | (cond_if_else_store_replacement): Rename to... | ||
20 | (cond_if_else_store_replacement_1): ... this. Change arguments and | ||
21 | documentation. | ||
22 | (cond_if_else_store_replacement): New function. | ||
23 | * Makefile.in (tree-ssa-phiopt.o): Adjust dependencies. | ||
24 | * params.def (PARAM_MAX_STORES_TO_SINK): Define. | ||
25 | |||
26 | gcc/testsuite/ | ||
27 | * gcc.dg/vect/vect-cselim-1.c: New test. | ||
28 | * gcc.dg/vect/vect-cselim-2.c: New test. | ||
29 | |||
30 | === modified file 'gcc/Makefile.in' | ||
31 | --- old/gcc/Makefile.in 2011-03-26 09:20:34 +0000 | ||
32 | +++ new/gcc/Makefile.in 2011-04-18 11:31:29 +0000 | ||
33 | @@ -2422,7 +2422,8 @@ | ||
34 | tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ | ||
35 | $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ | ||
36 | $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \ | ||
37 | - $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h | ||
38 | + $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ | ||
39 | + $(TREE_DATA_REF_H) | ||
40 | tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ | ||
41 | $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ | ||
42 | $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) $(TREE_PASS_H) \ | ||
43 | |||
44 | === modified file 'gcc/doc/invoke.texi' | ||
45 | --- old/gcc/doc/invoke.texi 2011-03-29 14:24:42 +0000 | ||
46 | +++ new/gcc/doc/invoke.texi 2011-04-18 11:31:29 +0000 | ||
47 | @@ -8909,6 +8909,11 @@ | ||
48 | The maximum number of namespaces to consult for suggestions when C++ | ||
49 | name lookup fails for an identifier. The default is 1000. | ||
50 | |||
51 | +@item max-stores-to-sink | ||
52 | +The maximum number of conditional stores paires that can be sunk. Set to 0 | ||
53 | +if either vectorization (@option{-ftree-vectorize}) or if-conversion | ||
54 | +(@option{-ftree-loop-if-convert}) is disabled. The default is 2. | ||
55 | + | ||
56 | @end table | ||
57 | @end table | ||
58 | |||
59 | |||
60 | === modified file 'gcc/opts.c' | ||
61 | --- old/gcc/opts.c 2011-02-17 22:51:57 +0000 | ||
62 | +++ new/gcc/opts.c 2011-03-27 09:38:18 +0000 | ||
63 | @@ -823,6 +823,12 @@ | ||
64 | opts->x_flag_split_stack = 0; | ||
65 | } | ||
66 | } | ||
67 | + | ||
68 | + /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion | ||
69 | + is disabled. */ | ||
70 | + if (!opts->x_flag_tree_vectorize || !opts->x_flag_tree_loop_if_convert) | ||
71 | + maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0, | ||
72 | + opts->x_param_values, opts_set->x_param_values); | ||
73 | } | ||
74 | |||
75 | #define LEFT_COLUMN 27 | ||
76 | |||
77 | === modified file 'gcc/params.def' | ||
78 | --- old/gcc/params.def 2011-03-26 09:20:34 +0000 | ||
79 | +++ new/gcc/params.def 2011-04-18 11:31:29 +0000 | ||
80 | @@ -883,6 +883,13 @@ | ||
81 | "name lookup fails", | ||
82 | 1000, 0, 0) | ||
83 | |||
84 | +/* Maximum number of conditional store pairs that can be sunk. */ | ||
85 | +DEFPARAM (PARAM_MAX_STORES_TO_SINK, | ||
86 | + "max-stores-to-sink", | ||
87 | + "Maximum number of conditional store pairs that can be sunk", | ||
88 | + 2, 0, 0) | ||
89 | + | ||
90 | + | ||
91 | /* | ||
92 | Local variables: | ||
93 | mode:c | ||
94 | |||
95 | === modified file 'gcc/params.h' | ||
96 | --- old/gcc/params.h 2011-01-13 13:41:03 +0000 | ||
97 | +++ new/gcc/params.h 2011-03-27 09:38:18 +0000 | ||
98 | @@ -206,4 +206,6 @@ | ||
99 | PARAM_VALUE (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO) | ||
100 | #define MIN_NONDEBUG_INSN_UID \ | ||
101 | PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID) | ||
102 | +#define MAX_STORES_TO_SINK \ | ||
103 | + PARAM_VALUE (PARAM_MAX_STORES_TO_SINK) | ||
104 | #endif /* ! GCC_PARAMS_H */ | ||
105 | |||
106 | === added file 'gcc/testsuite/gcc.dg/vect/vect-cselim-1.c' | ||
107 | --- old/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c 1970-01-01 00:00:00 +0000 | ||
108 | +++ new/gcc/testsuite/gcc.dg/vect/vect-cselim-1.c 2011-03-27 09:38:18 +0000 | ||
109 | @@ -0,0 +1,86 @@ | ||
110 | +/* { dg-require-effective-target vect_int } */ | ||
111 | + | ||
112 | +#include <stdarg.h> | ||
113 | +#include "tree-vect.h" | ||
114 | + | ||
115 | +#define N 50 | ||
116 | + | ||
117 | +typedef struct { | ||
118 | + short a; | ||
119 | + short b; | ||
120 | +} data; | ||
121 | + | ||
122 | +data in1[N], in2[N], out[N]; | ||
123 | +short result[N*2] = {7,-7,9,-6,11,-5,13,-4,15,-3,17,-2,19,-1,21,0,23,1,25,2,27,3,29,4,31,5,33,6,35,7,37,8,39,9,41,10,43,11,45,12,47,13,49,14,51,15,53,16,55,17,57,18,59,19,61,20,63,21,65,22,67,23,69,24,71,25,73,26,75,27,77,28,79,29,81,30,83,31,85,32,87,33,89,34,91,35,93,36,95,37,97,38,99,39,101,40,103,41,105,42}; | ||
124 | +short out1[N], out2[N]; | ||
125 | + | ||
126 | +__attribute__ ((noinline)) void | ||
127 | +foo () | ||
128 | +{ | ||
129 | + int i; | ||
130 | + short c, d; | ||
131 | + | ||
132 | + /* Vectorizable with conditional store sinking. */ | ||
133 | + for (i = 0; i < N; i++) | ||
134 | + { | ||
135 | + c = in1[i].b; | ||
136 | + d = in2[i].b; | ||
137 | + | ||
138 | + if (c >= d) | ||
139 | + { | ||
140 | + out[i].b = c; | ||
141 | + out[i].a = d + 5; | ||
142 | + } | ||
143 | + else | ||
144 | + { | ||
145 | + out[i].b = d - 12; | ||
146 | + out[i].a = c + d; | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + /* Not vectorizable. */ | ||
151 | + for (i = 0; i < N; i++) | ||
152 | + { | ||
153 | + c = in1[i].b; | ||
154 | + d = in2[i].b; | ||
155 | + | ||
156 | + if (c >= d) | ||
157 | + { | ||
158 | + out1[i] = c; | ||
159 | + } | ||
160 | + else | ||
161 | + { | ||
162 | + out2[i] = c + d; | ||
163 | + } | ||
164 | + } | ||
165 | +} | ||
166 | + | ||
167 | +int | ||
168 | +main (void) | ||
169 | +{ | ||
170 | + int i; | ||
171 | + | ||
172 | + check_vect (); | ||
173 | + | ||
174 | + for (i = 0; i < N; i++) | ||
175 | + { | ||
176 | + in1[i].a = i; | ||
177 | + in1[i].b = i + 2; | ||
178 | + in2[i].a = 5; | ||
179 | + in2[i].b = i + 5; | ||
180 | + __asm__ volatile (""); | ||
181 | + } | ||
182 | + | ||
183 | + foo (); | ||
184 | + | ||
185 | + for (i = 0; i < N; i++) | ||
186 | + { | ||
187 | + if (out[i].a != result[2*i] || out[i].b != result[2*i+1]) | ||
188 | + abort (); | ||
189 | + } | ||
190 | + | ||
191 | + return 0; | ||
192 | +} | ||
193 | + | ||
194 | +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || {! vect_strided } } } } } */ | ||
195 | +/* { dg-final { cleanup-tree-dump "vect" } } */ | ||
196 | |||
197 | === added file 'gcc/testsuite/gcc.dg/vect/vect-cselim-2.c' | ||
198 | --- old/gcc/testsuite/gcc.dg/vect/vect-cselim-2.c 1970-01-01 00:00:00 +0000 | ||
199 | +++ new/gcc/testsuite/gcc.dg/vect/vect-cselim-2.c 2011-03-27 09:38:18 +0000 | ||
200 | @@ -0,0 +1,65 @@ | ||
201 | +/* { dg-require-effective-target vect_int } */ | ||
202 | + | ||
203 | +#include <stdarg.h> | ||
204 | +#include "tree-vect.h" | ||
205 | + | ||
206 | +#define N 50 | ||
207 | + | ||
208 | +int a[N], b[N], in1[N], in2[N]; | ||
209 | +int result[2*N] = {5,-7,7,-6,9,-5,11,-4,13,-3,15,-2,17,-1,19,0,21,1,23,2,25,3,27,4,29,5,31,6,33,7,35,8,37,9,39,10,41,11,43,12,45,13,47,14,49,15,51,16,53,17,55,18,57,19,59,20,61,21,63,22,65,23,67,24,69,25,71,26,73,27,75,28,77,29,79,30,81,31,83,32,85,33,87,34,89,35,91,36,93,37,95,38,97,39,99,40,101,41,103,42}; | ||
210 | + | ||
211 | +__attribute__ ((noinline)) void | ||
212 | +foo (int *pa, int *pb) | ||
213 | +{ | ||
214 | + int i; | ||
215 | + int c, d; | ||
216 | + | ||
217 | + /* Store sinking should not work here since the pointers may alias. */ | ||
218 | + for (i = 0; i < N; i++) | ||
219 | + { | ||
220 | + c = in1[i]; | ||
221 | + d = in2[i]; | ||
222 | + | ||
223 | + if (c >= d) | ||
224 | + { | ||
225 | + *pa = c; | ||
226 | + *pb = d + 5; | ||
227 | + } | ||
228 | + else | ||
229 | + { | ||
230 | + *pb = d - 12; | ||
231 | + *pa = c + d; | ||
232 | + } | ||
233 | + | ||
234 | + pa++; | ||
235 | + pb++; | ||
236 | + } | ||
237 | +} | ||
238 | + | ||
239 | +int | ||
240 | +main (void) | ||
241 | +{ | ||
242 | + int i; | ||
243 | + | ||
244 | + check_vect (); | ||
245 | + | ||
246 | + for (i = 0; i < N; i++) | ||
247 | + { | ||
248 | + in1[i] = i; | ||
249 | + in2[i] = i + 5; | ||
250 | + __asm__ volatile (""); | ||
251 | + } | ||
252 | + | ||
253 | + foo (a, b); | ||
254 | + | ||
255 | + for (i = 0; i < N; i++) | ||
256 | + { | ||
257 | + if (a[i] != result[2*i] || b[i] != result[2*i+1]) | ||
258 | + abort (); | ||
259 | + } | ||
260 | + | ||
261 | + return 0; | ||
262 | +} | ||
263 | + | ||
264 | +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ | ||
265 | +/* { dg-final { cleanup-tree-dump "vect" } } */ | ||
266 | |||
267 | === modified file 'gcc/tree-data-ref.c' | ||
268 | --- old/gcc/tree-data-ref.c 2011-02-05 01:39:20 +0000 | ||
269 | +++ new/gcc/tree-data-ref.c 2011-03-27 09:38:18 +0000 | ||
270 | @@ -991,6 +991,48 @@ | ||
271 | return dr; | ||
272 | } | ||
273 | |||
274 | +/* Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical | ||
275 | + expressions. */ | ||
276 | +static bool | ||
277 | +dr_equal_offsets_p1 (tree offset1, tree offset2) | ||
278 | +{ | ||
279 | + bool res; | ||
280 | + | ||
281 | + STRIP_NOPS (offset1); | ||
282 | + STRIP_NOPS (offset2); | ||
283 | + | ||
284 | + if (offset1 == offset2) | ||
285 | + return true; | ||
286 | + | ||
287 | + if (TREE_CODE (offset1) != TREE_CODE (offset2) | ||
288 | + || (!BINARY_CLASS_P (offset1) && !UNARY_CLASS_P (offset1))) | ||
289 | + return false; | ||
290 | + | ||
291 | + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 0), | ||
292 | + TREE_OPERAND (offset2, 0)); | ||
293 | + | ||
294 | + if (!res || !BINARY_CLASS_P (offset1)) | ||
295 | + return res; | ||
296 | + | ||
297 | + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 1), | ||
298 | + TREE_OPERAND (offset2, 1)); | ||
299 | + | ||
300 | + return res; | ||
301 | +} | ||
302 | + | ||
303 | +/* Check if DRA and DRB have equal offsets. */ | ||
304 | +bool | ||
305 | +dr_equal_offsets_p (struct data_reference *dra, | ||
306 | + struct data_reference *drb) | ||
307 | +{ | ||
308 | + tree offset1, offset2; | ||
309 | + | ||
310 | + offset1 = DR_OFFSET (dra); | ||
311 | + offset2 = DR_OFFSET (drb); | ||
312 | + | ||
313 | + return dr_equal_offsets_p1 (offset1, offset2); | ||
314 | +} | ||
315 | + | ||
316 | /* Returns true if FNA == FNB. */ | ||
317 | |||
318 | static bool | ||
319 | @@ -4294,7 +4336,7 @@ | ||
320 | DATAREFS. Returns chrec_dont_know when failing to analyze a | ||
321 | difficult case, returns NULL_TREE otherwise. */ | ||
322 | |||
323 | -static tree | ||
324 | +tree | ||
325 | find_data_references_in_bb (struct loop *loop, basic_block bb, | ||
326 | VEC (data_reference_p, heap) **datarefs) | ||
327 | { | ||
328 | |||
329 | === modified file 'gcc/tree-data-ref.h' | ||
330 | --- old/gcc/tree-data-ref.h 2011-01-25 21:24:23 +0000 | ||
331 | +++ new/gcc/tree-data-ref.h 2011-03-27 09:38:18 +0000 | ||
332 | @@ -426,10 +426,14 @@ | ||
333 | extern void compute_all_dependences (VEC (data_reference_p, heap) *, | ||
334 | VEC (ddr_p, heap) **, VEC (loop_p, heap) *, | ||
335 | bool); | ||
336 | +extern tree find_data_references_in_bb (struct loop *, basic_block, | ||
337 | + VEC (data_reference_p, heap) **); | ||
338 | |||
339 | extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); | ||
340 | extern bool dr_may_alias_p (const struct data_reference *, | ||
341 | const struct data_reference *); | ||
342 | +extern bool dr_equal_offsets_p (struct data_reference *, | ||
343 | + struct data_reference *); | ||
344 | |||
345 | |||
346 | /* Return true when the base objects of data references A and B are | ||
347 | |||
348 | === modified file 'gcc/tree-ssa-phiopt.c' | ||
349 | --- old/gcc/tree-ssa-phiopt.c 2010-11-03 15:18:50 +0000 | ||
350 | +++ new/gcc/tree-ssa-phiopt.c 2011-03-27 09:38:18 +0000 | ||
351 | @@ -34,6 +34,8 @@ | ||
352 | #include "langhooks.h" | ||
353 | #include "pointer-set.h" | ||
354 | #include "domwalk.h" | ||
355 | +#include "cfgloop.h" | ||
356 | +#include "tree-data-ref.h" | ||
357 | |||
358 | static unsigned int tree_ssa_phiopt (void); | ||
359 | static unsigned int tree_ssa_phiopt_worker (bool); | ||
360 | @@ -1292,35 +1294,18 @@ | ||
361 | return true; | ||
362 | } | ||
363 | |||
364 | -/* Do the main work of conditional store replacement. We already know | ||
365 | - that the recognized pattern looks like so: | ||
366 | - | ||
367 | - split: | ||
368 | - if (cond) goto THEN_BB; else goto ELSE_BB (edge E1) | ||
369 | - THEN_BB: | ||
370 | - X = Y; | ||
371 | - goto JOIN_BB; | ||
372 | - ELSE_BB: | ||
373 | - X = Z; | ||
374 | - fallthrough (edge E0) | ||
375 | - JOIN_BB: | ||
376 | - some more | ||
377 | - | ||
378 | - We check that THEN_BB and ELSE_BB contain only one store | ||
379 | - that the stores have a "simple" RHS. */ | ||
380 | +/* Do the main work of conditional store replacement. */ | ||
381 | |||
382 | static bool | ||
383 | -cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, | ||
384 | - basic_block join_bb) | ||
385 | +cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, | ||
386 | + basic_block join_bb, gimple then_assign, | ||
387 | + gimple else_assign) | ||
388 | { | ||
389 | - gimple then_assign = last_and_only_stmt (then_bb); | ||
390 | - gimple else_assign = last_and_only_stmt (else_bb); | ||
391 | tree lhs_base, lhs, then_rhs, else_rhs; | ||
392 | source_location then_locus, else_locus; | ||
393 | gimple_stmt_iterator gsi; | ||
394 | gimple newphi, new_stmt; | ||
395 | |||
396 | - /* Check if then_bb and else_bb contain only one store each. */ | ||
397 | if (then_assign == NULL | ||
398 | || !gimple_assign_single_p (then_assign) | ||
399 | || else_assign == NULL | ||
400 | @@ -1385,6 +1370,190 @@ | ||
401 | return true; | ||
402 | } | ||
403 | |||
404 | +/* Conditional store replacement. We already know | ||
405 | + that the recognized pattern looks like so: | ||
406 | + | ||
407 | + split: | ||
408 | + if (cond) goto THEN_BB; else goto ELSE_BB (edge E1) | ||
409 | + THEN_BB: | ||
410 | + ... | ||
411 | + X = Y; | ||
412 | + ... | ||
413 | + goto JOIN_BB; | ||
414 | + ELSE_BB: | ||
415 | + ... | ||
416 | + X = Z; | ||
417 | + ... | ||
418 | + fallthrough (edge E0) | ||
419 | + JOIN_BB: | ||
420 | + some more | ||
421 | + | ||
422 | + We check that it is safe to sink the store to JOIN_BB by verifying that | ||
423 | + there are no read-after-write or write-after-write dependencies in | ||
424 | + THEN_BB and ELSE_BB. */ | ||
425 | + | ||
426 | +static bool | ||
427 | +cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, | ||
428 | + basic_block join_bb) | ||
429 | +{ | ||
430 | + gimple then_assign = last_and_only_stmt (then_bb); | ||
431 | + gimple else_assign = last_and_only_stmt (else_bb); | ||
432 | + VEC (data_reference_p, heap) *then_datarefs, *else_datarefs; | ||
433 | + VEC (ddr_p, heap) *then_ddrs, *else_ddrs; | ||
434 | + gimple then_store, else_store; | ||
435 | + bool found, ok = false, res; | ||
436 | + struct data_dependence_relation *ddr; | ||
437 | + data_reference_p then_dr, else_dr; | ||
438 | + int i, j; | ||
439 | + tree then_lhs, else_lhs; | ||
440 | + VEC (gimple, heap) *then_stores, *else_stores; | ||
441 | + basic_block blocks[3]; | ||
442 | + | ||
443 | + if (MAX_STORES_TO_SINK == 0) | ||
444 | + return false; | ||
445 | + | ||
446 | + /* Handle the case with single statement in THEN_BB and ELSE_BB. */ | ||
447 | + if (then_assign && else_assign) | ||
448 | + return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, | ||
449 | + then_assign, else_assign); | ||
450 | + | ||
451 | + /* Find data references. */ | ||
452 | + then_datarefs = VEC_alloc (data_reference_p, heap, 1); | ||
453 | + else_datarefs = VEC_alloc (data_reference_p, heap, 1); | ||
454 | + if ((find_data_references_in_bb (NULL, then_bb, &then_datarefs) | ||
455 | + == chrec_dont_know) | ||
456 | + || !VEC_length (data_reference_p, then_datarefs) | ||
457 | + || (find_data_references_in_bb (NULL, else_bb, &else_datarefs) | ||
458 | + == chrec_dont_know) | ||
459 | + || !VEC_length (data_reference_p, else_datarefs)) | ||
460 | + { | ||
461 | + free_data_refs (then_datarefs); | ||
462 | + free_data_refs (else_datarefs); | ||
463 | + return false; | ||
464 | + } | ||
465 | + | ||
466 | + /* Find pairs of stores with equal LHS. */ | ||
467 | + then_stores = VEC_alloc (gimple, heap, 1); | ||
468 | + else_stores = VEC_alloc (gimple, heap, 1); | ||
469 | + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) | ||
470 | + { | ||
471 | + if (DR_IS_READ (then_dr)) | ||
472 | + continue; | ||
473 | + | ||
474 | + then_store = DR_STMT (then_dr); | ||
475 | + then_lhs = gimple_assign_lhs (then_store); | ||
476 | + found = false; | ||
477 | + | ||
478 | + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) | ||
479 | + { | ||
480 | + if (DR_IS_READ (else_dr)) | ||
481 | + continue; | ||
482 | + | ||
483 | + else_store = DR_STMT (else_dr); | ||
484 | + else_lhs = gimple_assign_lhs (else_store); | ||
485 | + | ||
486 | + if (operand_equal_p (then_lhs, else_lhs, 0)) | ||
487 | + { | ||
488 | + found = true; | ||
489 | + break; | ||
490 | + } | ||
491 | + } | ||
492 | + | ||
493 | + if (!found) | ||
494 | + continue; | ||
495 | + | ||
496 | + VEC_safe_push (gimple, heap, then_stores, then_store); | ||
497 | + VEC_safe_push (gimple, heap, else_stores, else_store); | ||
498 | + } | ||
499 | + | ||
500 | + /* No pairs of stores found. */ | ||
501 | + if (!VEC_length (gimple, then_stores) | ||
502 | + || VEC_length (gimple, then_stores) > (unsigned) MAX_STORES_TO_SINK) | ||
503 | + { | ||
504 | + free_data_refs (then_datarefs); | ||
505 | + free_data_refs (else_datarefs); | ||
506 | + VEC_free (gimple, heap, then_stores); | ||
507 | + VEC_free (gimple, heap, else_stores); | ||
508 | + return false; | ||
509 | + } | ||
510 | + | ||
511 | + /* Compute and check data dependencies in both basic blocks. */ | ||
512 | + then_ddrs = VEC_alloc (ddr_p, heap, 1); | ||
513 | + else_ddrs = VEC_alloc (ddr_p, heap, 1); | ||
514 | + compute_all_dependences (then_datarefs, &then_ddrs, NULL, false); | ||
515 | + compute_all_dependences (else_datarefs, &else_ddrs, NULL, false); | ||
516 | + blocks[0] = then_bb; | ||
517 | + blocks[1] = else_bb; | ||
518 | + blocks[2] = join_bb; | ||
519 | + renumber_gimple_stmt_uids_in_blocks (blocks, 3); | ||
520 | + | ||
521 | + /* Check that there are no read-after-write or write-after-write dependencies | ||
522 | + in THEN_BB. */ | ||
523 | + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) | ||
524 | + { | ||
525 | + struct data_reference *dra = DDR_A (ddr); | ||
526 | + struct data_reference *drb = DDR_B (ddr); | ||
527 | + | ||
528 | + if (DDR_ARE_DEPENDENT (ddr) != chrec_known | ||
529 | + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) | ||
530 | + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) | ||
531 | + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) | ||
532 | + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra))) | ||
533 | + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)))) | ||
534 | + { | ||
535 | + free_dependence_relations (then_ddrs); | ||
536 | + free_dependence_relations (else_ddrs); | ||
537 | + free_data_refs (then_datarefs); | ||
538 | + free_data_refs (else_datarefs); | ||
539 | + VEC_free (gimple, heap, then_stores); | ||
540 | + VEC_free (gimple, heap, else_stores); | ||
541 | + return false; | ||
542 | + } | ||
543 | + } | ||
544 | + | ||
545 | + /* Check that there are no read-after-write or write-after-write dependencies | ||
546 | + in ELSE_BB. */ | ||
547 | + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) | ||
548 | + { | ||
549 | + struct data_reference *dra = DDR_A (ddr); | ||
550 | + struct data_reference *drb = DDR_B (ddr); | ||
551 | + | ||
552 | + if (DDR_ARE_DEPENDENT (ddr) != chrec_known | ||
553 | + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) | ||
554 | + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) | ||
555 | + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) | ||
556 | + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra))) | ||
557 | + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)))) | ||
558 | + { | ||
559 | + free_dependence_relations (then_ddrs); | ||
560 | + free_dependence_relations (else_ddrs); | ||
561 | + free_data_refs (then_datarefs); | ||
562 | + free_data_refs (else_datarefs); | ||
563 | + VEC_free (gimple, heap, then_stores); | ||
564 | + VEC_free (gimple, heap, else_stores); | ||
565 | + return false; | ||
566 | + } | ||
567 | + } | ||
568 | + | ||
569 | + /* Sink stores with same LHS. */ | ||
570 | + FOR_EACH_VEC_ELT (gimple, then_stores, i, then_store) | ||
571 | + { | ||
572 | + else_store = VEC_index (gimple, else_stores, i); | ||
573 | + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, | ||
574 | + then_store, else_store); | ||
575 | + ok = ok || res; | ||
576 | + } | ||
577 | + | ||
578 | + free_dependence_relations (then_ddrs); | ||
579 | + free_dependence_relations (else_ddrs); | ||
580 | + free_data_refs (then_datarefs); | ||
581 | + free_data_refs (else_datarefs); | ||
582 | + VEC_free (gimple, heap, then_stores); | ||
583 | + VEC_free (gimple, heap, else_stores); | ||
584 | + | ||
585 | + return ok; | ||
586 | +} | ||
587 | + | ||
588 | /* Always do these optimizations if we have SSA | ||
589 | trees to work on. */ | ||
590 | static bool | ||
591 | |||
592 | === modified file 'gcc/tree-vect-data-refs.c' | ||
593 | --- old/gcc/tree-vect-data-refs.c 2011-02-25 11:18:14 +0000 | ||
594 | +++ new/gcc/tree-vect-data-refs.c 2011-03-27 09:38:18 +0000 | ||
595 | @@ -289,39 +289,6 @@ | ||
596 | } | ||
597 | } | ||
598 | |||
599 | - | ||
600 | -/* Function vect_equal_offsets. | ||
601 | - | ||
602 | - Check if OFFSET1 and OFFSET2 are identical expressions. */ | ||
603 | - | ||
604 | -static bool | ||
605 | -vect_equal_offsets (tree offset1, tree offset2) | ||
606 | -{ | ||
607 | - bool res; | ||
608 | - | ||
609 | - STRIP_NOPS (offset1); | ||
610 | - STRIP_NOPS (offset2); | ||
611 | - | ||
612 | - if (offset1 == offset2) | ||
613 | - return true; | ||
614 | - | ||
615 | - if (TREE_CODE (offset1) != TREE_CODE (offset2) | ||
616 | - || (!BINARY_CLASS_P (offset1) && !UNARY_CLASS_P (offset1))) | ||
617 | - return false; | ||
618 | - | ||
619 | - res = vect_equal_offsets (TREE_OPERAND (offset1, 0), | ||
620 | - TREE_OPERAND (offset2, 0)); | ||
621 | - | ||
622 | - if (!res || !BINARY_CLASS_P (offset1)) | ||
623 | - return res; | ||
624 | - | ||
625 | - res = vect_equal_offsets (TREE_OPERAND (offset1, 1), | ||
626 | - TREE_OPERAND (offset2, 1)); | ||
627 | - | ||
628 | - return res; | ||
629 | -} | ||
630 | - | ||
631 | - | ||
632 | /* Check dependence between DRA and DRB for basic block vectorization. | ||
633 | If the accesses share same bases and offsets, we can compare their initial | ||
634 | constant offsets to decide whether they differ or not. In case of a read- | ||
635 | @@ -352,7 +319,7 @@ | ||
636 | || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR | ||
637 | || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0) | ||
638 | != TREE_OPERAND (DR_BASE_ADDRESS (drb),0))) | ||
639 | - || !vect_equal_offsets (DR_OFFSET (dra), DR_OFFSET (drb))) | ||
640 | + || !dr_equal_offsets_p (dra, drb)) | ||
641 | return true; | ||
642 | |||
643 | /* Check the types. */ | ||
644 | @@ -402,7 +369,7 @@ | ||
645 | || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR | ||
646 | || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0) | ||
647 | != TREE_OPERAND (DR_BASE_ADDRESS (drb),0))) | ||
648 | - || !vect_equal_offsets (DR_OFFSET (dra), DR_OFFSET (drb)) | ||
649 | + || !dr_equal_offsets_p (dra, drb) | ||
650 | || !tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb)) | ||
651 | || DR_IS_READ (dra) != DR_IS_READ (drb)) | ||
652 | return false; | ||
653 | |||