diff options
author | Khem Raj <raj.khem@gmail.com> | 2012-06-28 12:19:53 -0700 |
---|---|---|
committer | Koen Kooi <koen@dominion.thruhere.net> | 2012-07-09 18:40:21 +0200 |
commit | 6b278fbb02d818b54b5a9fa2716fc49e896b72a8 (patch) | |
tree | 833783fb738ff7abf3d0e3029c9a468e73b06e28 /toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch | |
parent | 680af24d1ff95533db610176e6b01fcc9dcf6699 (diff) | |
download | meta-openembedded-6b278fbb02d818b54b5a9fa2716fc49e896b72a8.tar.gz |
gcc-4.6: Migrate recipes from OE-Core
Remove linaro patches. If one needs to use linaro
modified gcc they should use meta-linaro
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch | 1400 |
1 files changed, 0 insertions, 1400 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch deleted file mode 100644 index 70a7bdfa2b..0000000000 --- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch +++ /dev/null | |||
@@ -1,1400 +0,0 @@ | |||
1 | 2011-11-17 Ira Rosen <ira.rosen@linaro.org> | ||
2 | |||
3 | Backport from mainline: | ||
4 | |||
5 | 2011-11-03 Ira Rosen <ira.rosen@linaro.org> | ||
6 | |||
7 | gcc/ | ||
8 | * tree-vectorizer.h (slp_void_p): New. | ||
9 | (struct _slp_tree): Replace left and right with children. Update | ||
10 | documentation. | ||
11 | (struct _slp_oprnd_info): New. | ||
12 | (vect_get_vec_defs): Declare. | ||
13 | (vect_get_slp_defs): Update arguments. | ||
14 | * tree-vect-loop.c (vect_create_epilog_for_reduction): Call | ||
15 | vect_get_vec_defs instead of vect_get_slp_defs. | ||
16 | (vectorizable_reduction): Likewise. | ||
17 | * tree-vect-stmts.c (vect_get_vec_defs): Remove static, add argument. | ||
18 | Update call to vect_get_slp_defs. | ||
19 | (vectorizable_conversion): Update call to vect_get_vec_defs. | ||
20 | (vectorizable_assignment, vectorizable_shift, | ||
21 | vectorizable_operation): Likewise. | ||
22 | (vectorizable_type_demotion): Call vect_get_vec_defs instead of | ||
23 | vect_get_slp_defs. | ||
24 | (vectorizable_type_promotion, vectorizable_store): Likewise. | ||
25 | (vect_analyze_stmt): Fix typo. | ||
26 | * tree-vect-slp.c (vect_free_slp_tree): Update SLP tree traversal. | ||
27 | (vect_print_slp_tree, vect_mark_slp_stmts, | ||
28 | vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts, | ||
29 | vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations, | ||
30 | vect_schedule_slp_instance): Likewise. | ||
31 | (vect_create_new_slp_node): New. | ||
32 | (vect_create_oprnd_info, vect_free_oprnd_info): Likewise. | ||
33 | (vect_get_and_check_slp_defs): Pass information about defs using | ||
34 | oprnds_info, allow any number of operands. | ||
35 | (vect_build_slp_tree): Likewise. Update calls to | ||
36 | vect_get_and_check_slp_defs. Fix comments. | ||
37 | (vect_analyze_slp_instance): Move node creation to | ||
38 | vect_create_new_slp_node. | ||
39 | (vect_get_slp_defs): Allow any number of operands. | ||
40 | |||
41 | 2011-11-11 Jakub Jelinek <jakub@redhat.com> | ||
42 | |||
43 | gcc/ | ||
44 | * tree-vect-slp.c (vect_free_slp_tree): Also free SLP_TREE_CHILDREN | ||
45 | vector. | ||
46 | (vect_create_new_slp_node): Don't allocate node before checking stmt | ||
47 | type. | ||
48 | (vect_free_oprnd_info): Remove FREE_DEF_STMTS argument, always | ||
49 | free def_stmts vectors and additionally free oprnd_info. | ||
50 | (vect_build_slp_tree): Adjust callers. Call it even if | ||
51 | stop_recursion. If vect_create_new_slp_node or | ||
52 | vect_build_slp_tree fails, properly handle freeing memory. | ||
53 | If it succeeded, clear def_stmts in oprnd_info. | ||
54 | |||
55 | === modified file 'gcc/tree-vect-loop.c' | ||
56 | --- old/gcc/tree-vect-loop.c 2011-09-05 06:23:37 +0000 | ||
57 | +++ new/gcc/tree-vect-loop.c 2011-11-14 11:38:08 +0000 | ||
58 | @@ -3282,8 +3282,8 @@ | ||
59 | |||
60 | /* Get the loop-entry arguments. */ | ||
61 | if (slp_node) | ||
62 | - vect_get_slp_defs (reduction_op, NULL_TREE, slp_node, &vec_initial_defs, | ||
63 | - NULL, reduc_index); | ||
64 | + vect_get_vec_defs (reduction_op, NULL_TREE, stmt, &vec_initial_defs, | ||
65 | + NULL, slp_node, reduc_index); | ||
66 | else | ||
67 | { | ||
68 | vec_initial_defs = VEC_alloc (tree, heap, 1); | ||
69 | @@ -4451,8 +4451,8 @@ | ||
70 | } | ||
71 | |||
72 | if (slp_node) | ||
73 | - vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, &vec_oprnds1, | ||
74 | - -1); | ||
75 | + vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, | ||
76 | + slp_node, -1); | ||
77 | else | ||
78 | { | ||
79 | loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index], | ||
80 | |||
81 | === modified file 'gcc/tree-vect-slp.c' | ||
82 | --- old/gcc/tree-vect-slp.c 2011-10-27 11:27:59 +0000 | ||
83 | +++ new/gcc/tree-vect-slp.c 2011-11-14 11:38:08 +0000 | ||
84 | @@ -67,15 +67,16 @@ | ||
85 | static void | ||
86 | vect_free_slp_tree (slp_tree node) | ||
87 | { | ||
88 | + int i; | ||
89 | + slp_void_p child; | ||
90 | + | ||
91 | if (!node) | ||
92 | return; | ||
93 | |||
94 | - if (SLP_TREE_LEFT (node)) | ||
95 | - vect_free_slp_tree (SLP_TREE_LEFT (node)); | ||
96 | - | ||
97 | - if (SLP_TREE_RIGHT (node)) | ||
98 | - vect_free_slp_tree (SLP_TREE_RIGHT (node)); | ||
99 | - | ||
100 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
101 | + vect_free_slp_tree ((slp_tree) child); | ||
102 | + | ||
103 | + VEC_free (slp_void_p, heap, SLP_TREE_CHILDREN (node)); | ||
104 | VEC_free (gimple, heap, SLP_TREE_SCALAR_STMTS (node)); | ||
105 | |||
106 | if (SLP_TREE_VEC_STMTS (node)) | ||
107 | @@ -96,48 +97,116 @@ | ||
108 | } | ||
109 | |||
110 | |||
111 | -/* Get the defs for the rhs of STMT (collect them in DEF_STMTS0/1), check that | ||
112 | - they are of a legal type and that they match the defs of the first stmt of | ||
113 | - the SLP group (stored in FIRST_STMT_...). */ | ||
114 | +/* Create an SLP node for SCALAR_STMTS. */ | ||
115 | + | ||
116 | +static slp_tree | ||
117 | +vect_create_new_slp_node (VEC (gimple, heap) *scalar_stmts) | ||
118 | +{ | ||
119 | + slp_tree node; | ||
120 | + gimple stmt = VEC_index (gimple, scalar_stmts, 0); | ||
121 | + unsigned int nops; | ||
122 | + | ||
123 | + if (is_gimple_call (stmt)) | ||
124 | + nops = gimple_call_num_args (stmt); | ||
125 | + else if (is_gimple_assign (stmt)) | ||
126 | + nops = gimple_num_ops (stmt) - 1; | ||
127 | + else | ||
128 | + return NULL; | ||
129 | + | ||
130 | + node = XNEW (struct _slp_tree); | ||
131 | + SLP_TREE_SCALAR_STMTS (node) = scalar_stmts; | ||
132 | + SLP_TREE_VEC_STMTS (node) = NULL; | ||
133 | + SLP_TREE_CHILDREN (node) = VEC_alloc (slp_void_p, heap, nops); | ||
134 | + SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0; | ||
135 | + SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0; | ||
136 | + | ||
137 | + return node; | ||
138 | +} | ||
139 | + | ||
140 | + | ||
141 | +/* Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each | ||
142 | + operand. */ | ||
143 | +static VEC (slp_oprnd_info, heap) * | ||
144 | +vect_create_oprnd_info (int nops, int group_size) | ||
145 | +{ | ||
146 | + int i; | ||
147 | + slp_oprnd_info oprnd_info; | ||
148 | + VEC (slp_oprnd_info, heap) *oprnds_info; | ||
149 | + | ||
150 | + oprnds_info = VEC_alloc (slp_oprnd_info, heap, nops); | ||
151 | + for (i = 0; i < nops; i++) | ||
152 | + { | ||
153 | + oprnd_info = XNEW (struct _slp_oprnd_info); | ||
154 | + oprnd_info->def_stmts = VEC_alloc (gimple, heap, group_size); | ||
155 | + oprnd_info->first_dt = vect_uninitialized_def; | ||
156 | + oprnd_info->first_def_type = NULL_TREE; | ||
157 | + oprnd_info->first_const_oprnd = NULL_TREE; | ||
158 | + oprnd_info->first_pattern = false; | ||
159 | + VEC_quick_push (slp_oprnd_info, oprnds_info, oprnd_info); | ||
160 | + } | ||
161 | + | ||
162 | + return oprnds_info; | ||
163 | +} | ||
164 | + | ||
165 | + | ||
166 | +/* Free operands info. */ | ||
167 | + | ||
168 | +static void | ||
169 | +vect_free_oprnd_info (VEC (slp_oprnd_info, heap) **oprnds_info) | ||
170 | +{ | ||
171 | + int i; | ||
172 | + slp_oprnd_info oprnd_info; | ||
173 | + | ||
174 | + FOR_EACH_VEC_ELT (slp_oprnd_info, *oprnds_info, i, oprnd_info) | ||
175 | + { | ||
176 | + VEC_free (gimple, heap, oprnd_info->def_stmts); | ||
177 | + XDELETE (oprnd_info); | ||
178 | + } | ||
179 | + | ||
180 | + VEC_free (slp_oprnd_info, heap, *oprnds_info); | ||
181 | +} | ||
182 | + | ||
183 | + | ||
184 | +/* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that | ||
185 | + they are of a valid type and that they match the defs of the first stmt of | ||
186 | + the SLP group (stored in OPRNDS_INFO). */ | ||
187 | |||
188 | static bool | ||
189 | vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, | ||
190 | slp_tree slp_node, gimple stmt, | ||
191 | - VEC (gimple, heap) **def_stmts0, | ||
192 | - VEC (gimple, heap) **def_stmts1, | ||
193 | - enum vect_def_type *first_stmt_dt0, | ||
194 | - enum vect_def_type *first_stmt_dt1, | ||
195 | - tree *first_stmt_def0_type, | ||
196 | - tree *first_stmt_def1_type, | ||
197 | - tree *first_stmt_const_oprnd, | ||
198 | - int ncopies_for_cost, | ||
199 | - bool *pattern0, bool *pattern1) | ||
200 | + int ncopies_for_cost, bool first, | ||
201 | + VEC (slp_oprnd_info, heap) **oprnds_info) | ||
202 | { | ||
203 | tree oprnd; | ||
204 | unsigned int i, number_of_oprnds; | ||
205 | - tree def[2]; | ||
206 | + tree def, def_op0 = NULL_TREE; | ||
207 | gimple def_stmt; | ||
208 | - enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; | ||
209 | - stmt_vec_info stmt_info = | ||
210 | - vinfo_for_stmt (VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0)); | ||
211 | - enum gimple_rhs_class rhs_class; | ||
212 | + enum vect_def_type dt = vect_uninitialized_def; | ||
213 | + enum vect_def_type dt_op0 = vect_uninitialized_def; | ||
214 | + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); | ||
215 | + tree lhs = gimple_get_lhs (stmt); | ||
216 | struct loop *loop = NULL; | ||
217 | enum tree_code rhs_code; | ||
218 | bool different_types = false; | ||
219 | + bool pattern = false; | ||
220 | + slp_oprnd_info oprnd_info, oprnd0_info, oprnd1_info; | ||
221 | |||
222 | if (loop_vinfo) | ||
223 | loop = LOOP_VINFO_LOOP (loop_vinfo); | ||
224 | |||
225 | - rhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt)); | ||
226 | - number_of_oprnds = gimple_num_ops (stmt) - 1; /* RHS only */ | ||
227 | + if (is_gimple_call (stmt)) | ||
228 | + number_of_oprnds = gimple_call_num_args (stmt); | ||
229 | + else | ||
230 | + number_of_oprnds = gimple_num_ops (stmt) - 1; | ||
231 | |||
232 | for (i = 0; i < number_of_oprnds; i++) | ||
233 | { | ||
234 | oprnd = gimple_op (stmt, i + 1); | ||
235 | + oprnd_info = VEC_index (slp_oprnd_info, *oprnds_info, i); | ||
236 | |||
237 | - if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def[i], | ||
238 | - &dt[i]) | ||
239 | - || (!def_stmt && dt[i] != vect_constant_def)) | ||
240 | + if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def, | ||
241 | + &dt) | ||
242 | + || (!def_stmt && dt != vect_constant_def)) | ||
243 | { | ||
244 | if (vect_print_dump_info (REPORT_SLP)) | ||
245 | { | ||
246 | @@ -158,29 +227,24 @@ | ||
247 | && !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt)) | ||
248 | && !STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt))) | ||
249 | { | ||
250 | - if (!*first_stmt_dt0) | ||
251 | - *pattern0 = true; | ||
252 | - else | ||
253 | - { | ||
254 | - if (i == 1 && !*first_stmt_dt1) | ||
255 | - *pattern1 = true; | ||
256 | - else if ((i == 0 && !*pattern0) || (i == 1 && !*pattern1)) | ||
257 | - { | ||
258 | - if (vect_print_dump_info (REPORT_DETAILS)) | ||
259 | - { | ||
260 | - fprintf (vect_dump, "Build SLP failed: some of the stmts" | ||
261 | - " are in a pattern, and others are not "); | ||
262 | - print_generic_expr (vect_dump, oprnd, TDF_SLIM); | ||
263 | - } | ||
264 | + pattern = true; | ||
265 | + if (!first && !oprnd_info->first_pattern) | ||
266 | + { | ||
267 | + if (vect_print_dump_info (REPORT_DETAILS)) | ||
268 | + { | ||
269 | + fprintf (vect_dump, "Build SLP failed: some of the stmts" | ||
270 | + " are in a pattern, and others are not "); | ||
271 | + print_generic_expr (vect_dump, oprnd, TDF_SLIM); | ||
272 | + } | ||
273 | |||
274 | - return false; | ||
275 | - } | ||
276 | + return false; | ||
277 | } | ||
278 | |||
279 | def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); | ||
280 | - dt[i] = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); | ||
281 | + dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); | ||
282 | |||
283 | - if (*dt == vect_unknown_def_type) | ||
284 | + if (dt == vect_unknown_def_type | ||
285 | + || STMT_VINFO_PATTERN_DEF_STMT (vinfo_for_stmt (def_stmt))) | ||
286 | { | ||
287 | if (vect_print_dump_info (REPORT_DETAILS)) | ||
288 | fprintf (vect_dump, "Unsupported pattern."); | ||
289 | @@ -190,11 +254,11 @@ | ||
290 | switch (gimple_code (def_stmt)) | ||
291 | { | ||
292 | case GIMPLE_PHI: | ||
293 | - def[i] = gimple_phi_result (def_stmt); | ||
294 | + def = gimple_phi_result (def_stmt); | ||
295 | break; | ||
296 | |||
297 | case GIMPLE_ASSIGN: | ||
298 | - def[i] = gimple_assign_lhs (def_stmt); | ||
299 | + def = gimple_assign_lhs (def_stmt); | ||
300 | break; | ||
301 | |||
302 | default: | ||
303 | @@ -204,117 +268,125 @@ | ||
304 | } | ||
305 | } | ||
306 | |||
307 | - if (!*first_stmt_dt0) | ||
308 | + if (first) | ||
309 | { | ||
310 | - /* op0 of the first stmt of the group - store its info. */ | ||
311 | - *first_stmt_dt0 = dt[i]; | ||
312 | - if (def[i]) | ||
313 | - *first_stmt_def0_type = TREE_TYPE (def[i]); | ||
314 | - else | ||
315 | - *first_stmt_const_oprnd = oprnd; | ||
316 | + oprnd_info->first_dt = dt; | ||
317 | + oprnd_info->first_pattern = pattern; | ||
318 | + if (def) | ||
319 | + { | ||
320 | + oprnd_info->first_def_type = TREE_TYPE (def); | ||
321 | + oprnd_info->first_const_oprnd = NULL_TREE; | ||
322 | + } | ||
323 | + else | ||
324 | + { | ||
325 | + oprnd_info->first_def_type = NULL_TREE; | ||
326 | + oprnd_info->first_const_oprnd = oprnd; | ||
327 | + } | ||
328 | |||
329 | - /* Analyze costs (for the first stmt of the group only). */ | ||
330 | - if (rhs_class != GIMPLE_SINGLE_RHS) | ||
331 | - /* Not memory operation (we don't call this functions for loads). */ | ||
332 | - vect_model_simple_cost (stmt_info, ncopies_for_cost, dt, slp_node); | ||
333 | - else | ||
334 | - /* Store. */ | ||
335 | - vect_model_store_cost (stmt_info, ncopies_for_cost, false, | ||
336 | - dt[0], slp_node); | ||
337 | + if (i == 0) | ||
338 | + { | ||
339 | + def_op0 = def; | ||
340 | + dt_op0 = dt; | ||
341 | + /* Analyze costs (for the first stmt of the group only). */ | ||
342 | + if (REFERENCE_CLASS_P (lhs)) | ||
343 | + /* Store. */ | ||
344 | + vect_model_store_cost (stmt_info, ncopies_for_cost, false, | ||
345 | + dt, slp_node); | ||
346 | + else | ||
347 | + /* Not memory operation (we don't call this function for | ||
348 | + loads). */ | ||
349 | + vect_model_simple_cost (stmt_info, ncopies_for_cost, &dt, | ||
350 | + slp_node); | ||
351 | + } | ||
352 | } | ||
353 | |||
354 | else | ||
355 | { | ||
356 | - if (!*first_stmt_dt1 && i == 1) | ||
357 | - { | ||
358 | - /* op1 of the first stmt of the group - store its info. */ | ||
359 | - *first_stmt_dt1 = dt[i]; | ||
360 | - if (def[i]) | ||
361 | - *first_stmt_def1_type = TREE_TYPE (def[i]); | ||
362 | - else | ||
363 | - { | ||
364 | - /* We assume that the stmt contains only one constant | ||
365 | - operand. We fail otherwise, to be on the safe side. */ | ||
366 | - if (*first_stmt_const_oprnd) | ||
367 | - { | ||
368 | - if (vect_print_dump_info (REPORT_SLP)) | ||
369 | - fprintf (vect_dump, "Build SLP failed: two constant " | ||
370 | - "oprnds in stmt"); | ||
371 | - return false; | ||
372 | - } | ||
373 | - *first_stmt_const_oprnd = oprnd; | ||
374 | - } | ||
375 | - } | ||
376 | - else | ||
377 | - { | ||
378 | - /* Not first stmt of the group, check that the def-stmt/s match | ||
379 | - the def-stmt/s of the first stmt. */ | ||
380 | - if ((i == 0 | ||
381 | - && (*first_stmt_dt0 != dt[i] | ||
382 | - || (*first_stmt_def0_type && def[0] | ||
383 | - && !types_compatible_p (*first_stmt_def0_type, | ||
384 | - TREE_TYPE (def[0]))))) | ||
385 | - || (i == 1 | ||
386 | - && (*first_stmt_dt1 != dt[i] | ||
387 | - || (*first_stmt_def1_type && def[1] | ||
388 | - && !types_compatible_p (*first_stmt_def1_type, | ||
389 | - TREE_TYPE (def[1]))))) | ||
390 | - || (!def[i] | ||
391 | - && !types_compatible_p (TREE_TYPE (*first_stmt_const_oprnd), | ||
392 | - TREE_TYPE (oprnd))) | ||
393 | - || different_types) | ||
394 | - { | ||
395 | - if (i != number_of_oprnds - 1) | ||
396 | - different_types = true; | ||
397 | + /* Not first stmt of the group, check that the def-stmt/s match | ||
398 | + the def-stmt/s of the first stmt. Allow different definition | ||
399 | + types for reduction chains: the first stmt must be a | ||
400 | + vect_reduction_def (a phi node), and the rest | ||
401 | + vect_internal_def. */ | ||
402 | + if (((oprnd_info->first_dt != dt | ||
403 | + && !(oprnd_info->first_dt == vect_reduction_def | ||
404 | + && dt == vect_internal_def)) | ||
405 | + || (oprnd_info->first_def_type != NULL_TREE | ||
406 | + && def | ||
407 | + && !types_compatible_p (oprnd_info->first_def_type, | ||
408 | + TREE_TYPE (def)))) | ||
409 | + || (!def | ||
410 | + && !types_compatible_p (TREE_TYPE (oprnd_info->first_const_oprnd), | ||
411 | + TREE_TYPE (oprnd))) | ||
412 | + || different_types) | ||
413 | + { | ||
414 | + if (number_of_oprnds != 2) | ||
415 | + { | ||
416 | + if (vect_print_dump_info (REPORT_SLP)) | ||
417 | + fprintf (vect_dump, "Build SLP failed: different types "); | ||
418 | + | ||
419 | + return false; | ||
420 | + } | ||
421 | + | ||
422 | + /* Try to swap operands in case of binary operation. */ | ||
423 | + if (i == 0) | ||
424 | + different_types = true; | ||
425 | + else | ||
426 | + { | ||
427 | + oprnd0_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); | ||
428 | + if (is_gimple_assign (stmt) | ||
429 | + && (rhs_code = gimple_assign_rhs_code (stmt)) | ||
430 | + && TREE_CODE_CLASS (rhs_code) == tcc_binary | ||
431 | + && commutative_tree_code (rhs_code) | ||
432 | + && oprnd0_info->first_dt == dt | ||
433 | + && oprnd_info->first_dt == dt_op0 | ||
434 | + && def_op0 && def | ||
435 | + && !(oprnd0_info->first_def_type | ||
436 | + && !types_compatible_p (oprnd0_info->first_def_type, | ||
437 | + TREE_TYPE (def))) | ||
438 | + && !(oprnd_info->first_def_type | ||
439 | + && !types_compatible_p (oprnd_info->first_def_type, | ||
440 | + TREE_TYPE (def_op0)))) | ||
441 | + { | ||
442 | + if (vect_print_dump_info (REPORT_SLP)) | ||
443 | + { | ||
444 | + fprintf (vect_dump, "Swapping operands of "); | ||
445 | + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
446 | + } | ||
447 | + | ||
448 | + swap_tree_operands (stmt, gimple_assign_rhs1_ptr (stmt), | ||
449 | + gimple_assign_rhs2_ptr (stmt)); | ||
450 | + } | ||
451 | else | ||
452 | - { | ||
453 | - if (is_gimple_assign (stmt) | ||
454 | - && (rhs_code = gimple_assign_rhs_code (stmt)) | ||
455 | - && TREE_CODE_CLASS (rhs_code) == tcc_binary | ||
456 | - && commutative_tree_code (rhs_code) | ||
457 | - && *first_stmt_dt0 == dt[1] | ||
458 | - && *first_stmt_dt1 == dt[0] | ||
459 | - && def[0] && def[1] | ||
460 | - && !(*first_stmt_def0_type | ||
461 | - && !types_compatible_p (*first_stmt_def0_type, | ||
462 | - TREE_TYPE (def[1]))) | ||
463 | - && !(*first_stmt_def1_type | ||
464 | - && !types_compatible_p (*first_stmt_def1_type, | ||
465 | - TREE_TYPE (def[0])))) | ||
466 | - { | ||
467 | - if (vect_print_dump_info (REPORT_SLP)) | ||
468 | - { | ||
469 | - fprintf (vect_dump, "Swapping operands of "); | ||
470 | - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
471 | - } | ||
472 | - swap_tree_operands (stmt, gimple_assign_rhs1_ptr (stmt), | ||
473 | - gimple_assign_rhs2_ptr (stmt)); | ||
474 | - } | ||
475 | - else | ||
476 | - { | ||
477 | - if (vect_print_dump_info (REPORT_SLP)) | ||
478 | - fprintf (vect_dump, "Build SLP failed: different types "); | ||
479 | - | ||
480 | - return false; | ||
481 | - } | ||
482 | - } | ||
483 | + { | ||
484 | + if (vect_print_dump_info (REPORT_SLP)) | ||
485 | + fprintf (vect_dump, "Build SLP failed: different types "); | ||
486 | + | ||
487 | + return false; | ||
488 | + } | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /* Check the types of the definitions. */ | ||
494 | - switch (dt[i]) | ||
495 | + switch (dt) | ||
496 | { | ||
497 | case vect_constant_def: | ||
498 | case vect_external_def: | ||
499 | + case vect_reduction_def: | ||
500 | break; | ||
501 | |||
502 | case vect_internal_def: | ||
503 | - case vect_reduction_def: | ||
504 | - if ((i == 0 && !different_types) || (i == 1 && different_types)) | ||
505 | - VEC_safe_push (gimple, heap, *def_stmts0, def_stmt); | ||
506 | + if (different_types) | ||
507 | + { | ||
508 | + oprnd0_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); | ||
509 | + oprnd1_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); | ||
510 | + if (i == 0) | ||
511 | + VEC_quick_push (gimple, oprnd1_info->def_stmts, def_stmt); | ||
512 | + else | ||
513 | + VEC_quick_push (gimple, oprnd0_info->def_stmts, def_stmt); | ||
514 | + } | ||
515 | else | ||
516 | - VEC_safe_push (gimple, heap, *def_stmts1, def_stmt); | ||
517 | + VEC_quick_push (gimple, oprnd_info->def_stmts, def_stmt); | ||
518 | break; | ||
519 | |||
520 | default: | ||
521 | @@ -322,7 +394,7 @@ | ||
522 | if (vect_print_dump_info (REPORT_SLP)) | ||
523 | { | ||
524 | fprintf (vect_dump, "Build SLP failed: illegal type of def "); | ||
525 | - print_generic_expr (vect_dump, def[i], TDF_SLIM); | ||
526 | + print_generic_expr (vect_dump, def, TDF_SLIM); | ||
527 | } | ||
528 | |||
529 | return false; | ||
530 | @@ -347,15 +419,10 @@ | ||
531 | VEC (slp_tree, heap) **loads, | ||
532 | unsigned int vectorization_factor, bool *loads_permuted) | ||
533 | { | ||
534 | - VEC (gimple, heap) *def_stmts0 = VEC_alloc (gimple, heap, group_size); | ||
535 | - VEC (gimple, heap) *def_stmts1 = VEC_alloc (gimple, heap, group_size); | ||
536 | unsigned int i; | ||
537 | VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node); | ||
538 | gimple stmt = VEC_index (gimple, stmts, 0); | ||
539 | - enum vect_def_type first_stmt_dt0 = vect_uninitialized_def; | ||
540 | - enum vect_def_type first_stmt_dt1 = vect_uninitialized_def; | ||
541 | enum tree_code first_stmt_code = ERROR_MARK, rhs_code = ERROR_MARK; | ||
542 | - tree first_stmt_def1_type = NULL_TREE, first_stmt_def0_type = NULL_TREE; | ||
543 | tree lhs; | ||
544 | bool stop_recursion = false, need_same_oprnds = false; | ||
545 | tree vectype, scalar_type, first_op1 = NULL_TREE; | ||
546 | @@ -364,13 +431,21 @@ | ||
547 | int icode; | ||
548 | enum machine_mode optab_op2_mode; | ||
549 | enum machine_mode vec_mode; | ||
550 | - tree first_stmt_const_oprnd = NULL_TREE; | ||
551 | struct data_reference *first_dr; | ||
552 | - bool pattern0 = false, pattern1 = false; | ||
553 | HOST_WIDE_INT dummy; | ||
554 | bool permutation = false; | ||
555 | unsigned int load_place; | ||
556 | gimple first_load, prev_first_load = NULL; | ||
557 | + VEC (slp_oprnd_info, heap) *oprnds_info; | ||
558 | + unsigned int nops; | ||
559 | + slp_oprnd_info oprnd_info; | ||
560 | + | ||
561 | + if (is_gimple_call (stmt)) | ||
562 | + nops = gimple_call_num_args (stmt); | ||
563 | + else | ||
564 | + nops = gimple_num_ops (stmt) - 1; | ||
565 | + | ||
566 | + oprnds_info = vect_create_oprnd_info (nops, group_size); | ||
567 | |||
568 | /* For every stmt in NODE find its def stmt/s. */ | ||
569 | FOR_EACH_VEC_ELT (gimple, stmts, i, stmt) | ||
570 | @@ -391,6 +466,7 @@ | ||
571 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
572 | } | ||
573 | |||
574 | + vect_free_oprnd_info (&oprnds_info); | ||
575 | return false; | ||
576 | } | ||
577 | |||
578 | @@ -400,10 +476,11 @@ | ||
579 | if (vect_print_dump_info (REPORT_SLP)) | ||
580 | { | ||
581 | fprintf (vect_dump, | ||
582 | - "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL"); | ||
583 | + "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL "); | ||
584 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
585 | } | ||
586 | |||
587 | + vect_free_oprnd_info (&oprnds_info); | ||
588 | return false; | ||
589 | } | ||
590 | |||
591 | @@ -416,6 +493,8 @@ | ||
592 | fprintf (vect_dump, "Build SLP failed: unsupported data-type "); | ||
593 | print_generic_expr (vect_dump, scalar_type, TDF_SLIM); | ||
594 | } | ||
595 | + | ||
596 | + vect_free_oprnd_info (&oprnds_info); | ||
597 | return false; | ||
598 | } | ||
599 | |||
600 | @@ -462,6 +541,7 @@ | ||
601 | { | ||
602 | if (vect_print_dump_info (REPORT_SLP)) | ||
603 | fprintf (vect_dump, "Build SLP failed: no optab."); | ||
604 | + vect_free_oprnd_info (&oprnds_info); | ||
605 | return false; | ||
606 | } | ||
607 | icode = (int) optab_handler (optab, vec_mode); | ||
608 | @@ -470,6 +550,7 @@ | ||
609 | if (vect_print_dump_info (REPORT_SLP)) | ||
610 | fprintf (vect_dump, "Build SLP failed: " | ||
611 | "op not supported by target."); | ||
612 | + vect_free_oprnd_info (&oprnds_info); | ||
613 | return false; | ||
614 | } | ||
615 | optab_op2_mode = insn_data[icode].operand[2].mode; | ||
616 | @@ -506,6 +587,7 @@ | ||
617 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
618 | } | ||
619 | |||
620 | + vect_free_oprnd_info (&oprnds_info); | ||
621 | return false; | ||
622 | } | ||
623 | |||
624 | @@ -519,6 +601,7 @@ | ||
625 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
626 | } | ||
627 | |||
628 | + vect_free_oprnd_info (&oprnds_info); | ||
629 | return false; | ||
630 | } | ||
631 | } | ||
632 | @@ -530,15 +613,12 @@ | ||
633 | { | ||
634 | /* Store. */ | ||
635 | if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, | ||
636 | - stmt, &def_stmts0, &def_stmts1, | ||
637 | - &first_stmt_dt0, | ||
638 | - &first_stmt_dt1, | ||
639 | - &first_stmt_def0_type, | ||
640 | - &first_stmt_def1_type, | ||
641 | - &first_stmt_const_oprnd, | ||
642 | - ncopies_for_cost, | ||
643 | - &pattern0, &pattern1)) | ||
644 | - return false; | ||
645 | + stmt, ncopies_for_cost, | ||
646 | + (i == 0), &oprnds_info)) | ||
647 | + { | ||
648 | + vect_free_oprnd_info (&oprnds_info); | ||
649 | + return false; | ||
650 | + } | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | @@ -556,6 +636,7 @@ | ||
655 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
656 | } | ||
657 | |||
658 | + vect_free_oprnd_info (&oprnds_info); | ||
659 | return false; | ||
660 | } | ||
661 | |||
662 | @@ -573,6 +654,7 @@ | ||
663 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
664 | } | ||
665 | |||
666 | + vect_free_oprnd_info (&oprnds_info); | ||
667 | return false; | ||
668 | } | ||
669 | |||
670 | @@ -593,6 +675,7 @@ | ||
671 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
672 | } | ||
673 | |||
674 | + vect_free_oprnd_info (&oprnds_info); | ||
675 | return false; | ||
676 | } | ||
677 | } | ||
678 | @@ -612,6 +695,7 @@ | ||
679 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
680 | } | ||
681 | |||
682 | + vect_free_oprnd_info (&oprnds_info); | ||
683 | return false; | ||
684 | } | ||
685 | |||
686 | @@ -639,7 +723,7 @@ | ||
687 | { | ||
688 | if (TREE_CODE_CLASS (rhs_code) == tcc_reference) | ||
689 | { | ||
690 | - /* Not strided load. */ | ||
691 | + /* Not strided load. */ | ||
692 | if (vect_print_dump_info (REPORT_SLP)) | ||
693 | { | ||
694 | fprintf (vect_dump, "Build SLP failed: not strided load "); | ||
695 | @@ -647,6 +731,7 @@ | ||
696 | } | ||
697 | |||
698 | /* FORNOW: Not strided loads are not supported. */ | ||
699 | + vect_free_oprnd_info (&oprnds_info); | ||
700 | return false; | ||
701 | } | ||
702 | |||
703 | @@ -661,19 +746,18 @@ | ||
704 | print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); | ||
705 | } | ||
706 | |||
707 | + vect_free_oprnd_info (&oprnds_info); | ||
708 | return false; | ||
709 | } | ||
710 | |||
711 | /* Find the def-stmts. */ | ||
712 | if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, stmt, | ||
713 | - &def_stmts0, &def_stmts1, | ||
714 | - &first_stmt_dt0, &first_stmt_dt1, | ||
715 | - &first_stmt_def0_type, | ||
716 | - &first_stmt_def1_type, | ||
717 | - &first_stmt_const_oprnd, | ||
718 | - ncopies_for_cost, | ||
719 | - &pattern0, &pattern1)) | ||
720 | - return false; | ||
721 | + ncopies_for_cost, (i == 0), | ||
722 | + &oprnds_info)) | ||
723 | + { | ||
724 | + vect_free_oprnd_info (&oprnds_info); | ||
725 | + return false; | ||
726 | + } | ||
727 | } | ||
728 | } | ||
729 | |||
730 | @@ -702,46 +786,37 @@ | ||
731 | *loads_permuted = true; | ||
732 | } | ||
733 | |||
734 | + vect_free_oprnd_info (&oprnds_info); | ||
735 | return true; | ||
736 | } | ||
737 | |||
738 | /* Create SLP_TREE nodes for the definition node/s. */ | ||
739 | - if (first_stmt_dt0 == vect_internal_def) | ||
740 | - { | ||
741 | - slp_tree left_node = XNEW (struct _slp_tree); | ||
742 | - SLP_TREE_SCALAR_STMTS (left_node) = def_stmts0; | ||
743 | - SLP_TREE_VEC_STMTS (left_node) = NULL; | ||
744 | - SLP_TREE_LEFT (left_node) = NULL; | ||
745 | - SLP_TREE_RIGHT (left_node) = NULL; | ||
746 | - SLP_TREE_OUTSIDE_OF_LOOP_COST (left_node) = 0; | ||
747 | - SLP_TREE_INSIDE_OF_LOOP_COST (left_node) = 0; | ||
748 | - if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &left_node, group_size, | ||
749 | - inside_cost, outside_cost, ncopies_for_cost, | ||
750 | - max_nunits, load_permutation, loads, | ||
751 | - vectorization_factor, loads_permuted)) | ||
752 | - return false; | ||
753 | - | ||
754 | - SLP_TREE_LEFT (*node) = left_node; | ||
755 | - } | ||
756 | - | ||
757 | - if (first_stmt_dt1 == vect_internal_def) | ||
758 | - { | ||
759 | - slp_tree right_node = XNEW (struct _slp_tree); | ||
760 | - SLP_TREE_SCALAR_STMTS (right_node) = def_stmts1; | ||
761 | - SLP_TREE_VEC_STMTS (right_node) = NULL; | ||
762 | - SLP_TREE_LEFT (right_node) = NULL; | ||
763 | - SLP_TREE_RIGHT (right_node) = NULL; | ||
764 | - SLP_TREE_OUTSIDE_OF_LOOP_COST (right_node) = 0; | ||
765 | - SLP_TREE_INSIDE_OF_LOOP_COST (right_node) = 0; | ||
766 | - if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &right_node, group_size, | ||
767 | - inside_cost, outside_cost, ncopies_for_cost, | ||
768 | - max_nunits, load_permutation, loads, | ||
769 | - vectorization_factor, loads_permuted)) | ||
770 | - return false; | ||
771 | - | ||
772 | - SLP_TREE_RIGHT (*node) = right_node; | ||
773 | - } | ||
774 | - | ||
775 | + FOR_EACH_VEC_ELT (slp_oprnd_info, oprnds_info, i, oprnd_info) | ||
776 | + { | ||
777 | + slp_tree child; | ||
778 | + | ||
779 | + if (oprnd_info->first_dt != vect_internal_def) | ||
780 | + continue; | ||
781 | + | ||
782 | + child = vect_create_new_slp_node (oprnd_info->def_stmts); | ||
783 | + if (!child | ||
784 | + || !vect_build_slp_tree (loop_vinfo, bb_vinfo, &child, group_size, | ||
785 | + inside_cost, outside_cost, ncopies_for_cost, | ||
786 | + max_nunits, load_permutation, loads, | ||
787 | + vectorization_factor, loads_permuted)) | ||
788 | + { | ||
789 | + if (child) | ||
790 | + oprnd_info->def_stmts = NULL; | ||
791 | + vect_free_slp_tree (child); | ||
792 | + vect_free_oprnd_info (&oprnds_info); | ||
793 | + return false; | ||
794 | + } | ||
795 | + | ||
796 | + oprnd_info->def_stmts = NULL; | ||
797 | + VEC_quick_push (slp_void_p, SLP_TREE_CHILDREN (*node), child); | ||
798 | + } | ||
799 | + | ||
800 | + vect_free_oprnd_info (&oprnds_info); | ||
801 | return true; | ||
802 | } | ||
803 | |||
804 | @@ -751,6 +826,7 @@ | ||
805 | { | ||
806 | int i; | ||
807 | gimple stmt; | ||
808 | + slp_void_p child; | ||
809 | |||
810 | if (!node) | ||
811 | return; | ||
812 | @@ -763,8 +839,8 @@ | ||
813 | } | ||
814 | fprintf (vect_dump, "\n"); | ||
815 | |||
816 | - vect_print_slp_tree (SLP_TREE_LEFT (node)); | ||
817 | - vect_print_slp_tree (SLP_TREE_RIGHT (node)); | ||
818 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
819 | + vect_print_slp_tree ((slp_tree) child); | ||
820 | } | ||
821 | |||
822 | |||
823 | @@ -778,6 +854,7 @@ | ||
824 | { | ||
825 | int i; | ||
826 | gimple stmt; | ||
827 | + slp_void_p child; | ||
828 | |||
829 | if (!node) | ||
830 | return; | ||
831 | @@ -786,8 +863,8 @@ | ||
832 | if (j < 0 || i == j) | ||
833 | STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark; | ||
834 | |||
835 | - vect_mark_slp_stmts (SLP_TREE_LEFT (node), mark, j); | ||
836 | - vect_mark_slp_stmts (SLP_TREE_RIGHT (node), mark, j); | ||
837 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
838 | + vect_mark_slp_stmts ((slp_tree) child, mark, j); | ||
839 | } | ||
840 | |||
841 | |||
842 | @@ -799,6 +876,7 @@ | ||
843 | int i; | ||
844 | gimple stmt; | ||
845 | stmt_vec_info stmt_info; | ||
846 | + slp_void_p child; | ||
847 | |||
848 | if (!node) | ||
849 | return; | ||
850 | @@ -811,8 +889,8 @@ | ||
851 | STMT_VINFO_RELEVANT (stmt_info) = vect_used_in_scope; | ||
852 | } | ||
853 | |||
854 | - vect_mark_slp_stmts_relevant (SLP_TREE_LEFT (node)); | ||
855 | - vect_mark_slp_stmts_relevant (SLP_TREE_RIGHT (node)); | ||
856 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
857 | + vect_mark_slp_stmts_relevant ((slp_tree) child); | ||
858 | } | ||
859 | |||
860 | |||
861 | @@ -885,12 +963,13 @@ | ||
862 | gimple stmt; | ||
863 | VEC (gimple, heap) *tmp_stmts; | ||
864 | unsigned int index, i; | ||
865 | + slp_void_p child; | ||
866 | |||
867 | if (!node) | ||
868 | return; | ||
869 | |||
870 | - vect_slp_rearrange_stmts (SLP_TREE_LEFT (node), group_size, permutation); | ||
871 | - vect_slp_rearrange_stmts (SLP_TREE_RIGHT (node), group_size, permutation); | ||
872 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
873 | + vect_slp_rearrange_stmts ((slp_tree) child, group_size, permutation); | ||
874 | |||
875 | gcc_assert (group_size == VEC_length (gimple, SLP_TREE_SCALAR_STMTS (node))); | ||
876 | tmp_stmts = VEC_alloc (gimple, heap, group_size); | ||
877 | @@ -1253,7 +1332,7 @@ | ||
878 | gimple stmt) | ||
879 | { | ||
880 | slp_instance new_instance; | ||
881 | - slp_tree node = XNEW (struct _slp_tree); | ||
882 | + slp_tree node; | ||
883 | unsigned int group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt)); | ||
884 | unsigned int unrolling_factor = 1, nunits; | ||
885 | tree vectype, scalar_type = NULL_TREE; | ||
886 | @@ -1265,6 +1344,7 @@ | ||
887 | VEC (slp_tree, heap) *loads; | ||
888 | struct data_reference *dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); | ||
889 | bool loads_permuted = false; | ||
890 | + VEC (gimple, heap) *scalar_stmts; | ||
891 | |||
892 | if (dr) | ||
893 | { | ||
894 | @@ -1308,39 +1388,26 @@ | ||
895 | } | ||
896 | |||
897 | /* Create a node (a root of the SLP tree) for the packed strided stores. */ | ||
898 | - SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (gimple, heap, group_size); | ||
899 | + scalar_stmts = VEC_alloc (gimple, heap, group_size); | ||
900 | next = stmt; | ||
901 | if (dr) | ||
902 | { | ||
903 | /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */ | ||
904 | while (next) | ||
905 | { | ||
906 | - VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); | ||
907 | + VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
908 | next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next)); | ||
909 | } | ||
910 | } | ||
911 | else | ||
912 | { | ||
913 | /* Collect reduction statements. */ | ||
914 | - for (i = 0; VEC_iterate (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, | ||
915 | - next); | ||
916 | - i++) | ||
917 | - { | ||
918 | - VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); | ||
919 | - if (vect_print_dump_info (REPORT_DETAILS)) | ||
920 | - { | ||
921 | - fprintf (vect_dump, "pushing reduction into node: "); | ||
922 | - print_gimple_stmt (vect_dump, next, 0, TDF_SLIM); | ||
923 | - } | ||
924 | - } | ||
925 | + VEC (gimple, heap) *reductions = LOOP_VINFO_REDUCTIONS (loop_vinfo); | ||
926 | + for (i = 0; VEC_iterate (gimple, reductions, i, next); i++) | ||
927 | + VEC_safe_push (gimple, heap, scalar_stmts, next); | ||
928 | } | ||
929 | |||
930 | - SLP_TREE_VEC_STMTS (node) = NULL; | ||
931 | - SLP_TREE_NUMBER_OF_VEC_STMTS (node) = 0; | ||
932 | - SLP_TREE_LEFT (node) = NULL; | ||
933 | - SLP_TREE_RIGHT (node) = NULL; | ||
934 | - SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0; | ||
935 | - SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0; | ||
936 | + node = vect_create_new_slp_node (scalar_stmts); | ||
937 | |||
938 | /* Calculate the number of vector stmts to create based on the unrolling | ||
939 | factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is | ||
940 | @@ -1517,6 +1584,7 @@ | ||
941 | imm_use_iterator imm_iter; | ||
942 | gimple use_stmt; | ||
943 | stmt_vec_info stmt_vinfo; | ||
944 | + slp_void_p child; | ||
945 | |||
946 | if (!node) | ||
947 | return; | ||
948 | @@ -1534,8 +1602,8 @@ | ||
949 | == vect_reduction_def)) | ||
950 | vect_mark_slp_stmts (node, hybrid, i); | ||
951 | |||
952 | - vect_detect_hybrid_slp_stmts (SLP_TREE_LEFT (node)); | ||
953 | - vect_detect_hybrid_slp_stmts (SLP_TREE_RIGHT (node)); | ||
954 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
955 | + vect_detect_hybrid_slp_stmts ((slp_tree) child); | ||
956 | } | ||
957 | |||
958 | |||
959 | @@ -1625,13 +1693,14 @@ | ||
960 | bool dummy; | ||
961 | int i; | ||
962 | gimple stmt; | ||
963 | + slp_void_p child; | ||
964 | |||
965 | if (!node) | ||
966 | return true; | ||
967 | |||
968 | - if (!vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_LEFT (node)) | ||
969 | - || !vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_RIGHT (node))) | ||
970 | - return false; | ||
971 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
972 | + if (!vect_slp_analyze_node_operations (bb_vinfo, (slp_tree) child)) | ||
973 | + return false; | ||
974 | |||
975 | FOR_EACH_VEC_ELT (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt) | ||
976 | { | ||
977 | @@ -2207,88 +2276,102 @@ | ||
978 | If the scalar definitions are loop invariants or constants, collect them and | ||
979 | call vect_get_constant_vectors() to create vector stmts. | ||
980 | Otherwise, the def-stmts must be already vectorized and the vectorized stmts | ||
981 | - must be stored in the LEFT/RIGHT node of SLP_NODE, and we call | ||
982 | - vect_get_slp_vect_defs() to retrieve them. | ||
983 | - If VEC_OPRNDS1 is NULL, don't get vector defs for the second operand (from | ||
984 | - the right node. This is used when the second operand must remain scalar. */ | ||
985 | + must be stored in the corresponding child of SLP_NODE, and we call | ||
986 | + vect_get_slp_vect_defs () to retrieve them. */ | ||
987 | |||
988 | void | ||
989 | -vect_get_slp_defs (tree op0, tree op1, slp_tree slp_node, | ||
990 | - VEC (tree,heap) **vec_oprnds0, | ||
991 | - VEC (tree,heap) **vec_oprnds1, int reduc_index) | ||
992 | +vect_get_slp_defs (VEC (tree, heap) *ops, slp_tree slp_node, | ||
993 | + VEC (slp_void_p, heap) **vec_oprnds, int reduc_index) | ||
994 | { | ||
995 | - gimple first_stmt; | ||
996 | - enum tree_code code; | ||
997 | - int number_of_vects; | ||
998 | + gimple first_stmt, first_def; | ||
999 | + int number_of_vects = 0, i; | ||
1000 | + unsigned int child_index = 0; | ||
1001 | HOST_WIDE_INT lhs_size_unit, rhs_size_unit; | ||
1002 | + slp_tree child = NULL; | ||
1003 | + VEC (tree, heap) *vec_defs; | ||
1004 | + tree oprnd, def_lhs; | ||
1005 | + bool vectorized_defs; | ||
1006 | |||
1007 | first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); | ||
1008 | - /* The number of vector defs is determined by the number of vector statements | ||
1009 | - in the node from which we get those statements. */ | ||
1010 | - if (SLP_TREE_LEFT (slp_node)) | ||
1011 | - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (SLP_TREE_LEFT (slp_node)); | ||
1012 | - else | ||
1013 | - { | ||
1014 | - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); | ||
1015 | - /* Number of vector stmts was calculated according to LHS in | ||
1016 | - vect_schedule_slp_instance(), fix it by replacing LHS with RHS, if | ||
1017 | - necessary. See vect_get_smallest_scalar_type () for details. */ | ||
1018 | - vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, | ||
1019 | - &rhs_size_unit); | ||
1020 | - if (rhs_size_unit != lhs_size_unit) | ||
1021 | - { | ||
1022 | - number_of_vects *= rhs_size_unit; | ||
1023 | - number_of_vects /= lhs_size_unit; | ||
1024 | - } | ||
1025 | + FOR_EACH_VEC_ELT (tree, ops, i, oprnd) | ||
1026 | + { | ||
1027 | + /* For each operand we check if it has vectorized definitions in a child | ||
1028 | + node or we need to create them (for invariants and constants). We | ||
1029 | + check if the LHS of the first stmt of the next child matches OPRND. | ||
1030 | + If it does, we found the correct child. Otherwise, we call | ||
1031 | + vect_get_constant_vectors (), and not advance CHILD_INDEX in order | ||
1032 | + to check this child node for the next operand. */ | ||
1033 | + vectorized_defs = false; | ||
1034 | + if (VEC_length (slp_void_p, SLP_TREE_CHILDREN (slp_node)) > child_index) | ||
1035 | + { | ||
1036 | + child = (slp_tree) VEC_index (slp_void_p, | ||
1037 | + SLP_TREE_CHILDREN (slp_node), | ||
1038 | + child_index); | ||
1039 | + first_def = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (child), 0); | ||
1040 | + | ||
1041 | + /* In the end of a pattern sequence we have a use of the original stmt, | ||
1042 | + so we need to compare OPRND with the original def. */ | ||
1043 | + if (is_pattern_stmt_p (vinfo_for_stmt (first_def)) | ||
1044 | + && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt)) | ||
1045 | + && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt))) | ||
1046 | + first_def = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def)); | ||
1047 | + | ||
1048 | + if (is_gimple_call (first_def)) | ||
1049 | + def_lhs = gimple_call_lhs (first_def); | ||
1050 | + else | ||
1051 | + def_lhs = gimple_assign_lhs (first_def); | ||
1052 | + | ||
1053 | + if (operand_equal_p (oprnd, def_lhs, 0)) | ||
1054 | + { | ||
1055 | + /* The number of vector defs is determined by the number of | ||
1056 | + vector statements in the node from which we get those | ||
1057 | + statements. */ | ||
1058 | + number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); | ||
1059 | + vectorized_defs = true; | ||
1060 | + child_index++; | ||
1061 | + } | ||
1062 | + } | ||
1063 | + | ||
1064 | + if (!vectorized_defs) | ||
1065 | + { | ||
1066 | + if (i == 0) | ||
1067 | + { | ||
1068 | + number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); | ||
1069 | + /* Number of vector stmts was calculated according to LHS in | ||
1070 | + vect_schedule_slp_instance (), fix it by replacing LHS with | ||
1071 | + RHS, if necessary. See vect_get_smallest_scalar_type () for | ||
1072 | + details. */ | ||
1073 | + vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, | ||
1074 | + &rhs_size_unit); | ||
1075 | + if (rhs_size_unit != lhs_size_unit) | ||
1076 | + { | ||
1077 | + number_of_vects *= rhs_size_unit; | ||
1078 | + number_of_vects /= lhs_size_unit; | ||
1079 | + } | ||
1080 | + } | ||
1081 | + } | ||
1082 | + | ||
1083 | + /* Allocate memory for vectorized defs. */ | ||
1084 | + vec_defs = VEC_alloc (tree, heap, number_of_vects); | ||
1085 | + | ||
1086 | + /* For reduction defs we call vect_get_constant_vectors (), since we are | ||
1087 | + looking for initial loop invariant values. */ | ||
1088 | + if (vectorized_defs && reduc_index == -1) | ||
1089 | + /* The defs are already vectorized. */ | ||
1090 | + vect_get_slp_vect_defs (child, &vec_defs); | ||
1091 | + else | ||
1092 | + /* Build vectors from scalar defs. */ | ||
1093 | + vect_get_constant_vectors (oprnd, slp_node, &vec_defs, i, | ||
1094 | + number_of_vects, reduc_index); | ||
1095 | + | ||
1096 | + VEC_quick_push (slp_void_p, *vec_oprnds, (slp_void_p) vec_defs); | ||
1097 | + | ||
1098 | + /* For reductions, we only need initial values. */ | ||
1099 | + if (reduc_index != -1) | ||
1100 | + return; | ||
1101 | } | ||
1102 | - | ||
1103 | - /* Allocate memory for vectorized defs. */ | ||
1104 | - *vec_oprnds0 = VEC_alloc (tree, heap, number_of_vects); | ||
1105 | - | ||
1106 | - /* SLP_NODE corresponds either to a group of stores or to a group of | ||
1107 | - unary/binary operations. We don't call this function for loads. | ||
1108 | - For reduction defs we call vect_get_constant_vectors(), since we are | ||
1109 | - looking for initial loop invariant values. */ | ||
1110 | - if (SLP_TREE_LEFT (slp_node) && reduc_index == -1) | ||
1111 | - /* The defs are already vectorized. */ | ||
1112 | - vect_get_slp_vect_defs (SLP_TREE_LEFT (slp_node), vec_oprnds0); | ||
1113 | - else | ||
1114 | - /* Build vectors from scalar defs. */ | ||
1115 | - vect_get_constant_vectors (op0, slp_node, vec_oprnds0, 0, number_of_vects, | ||
1116 | - reduc_index); | ||
1117 | - | ||
1118 | - if (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt))) | ||
1119 | - /* Since we don't call this function with loads, this is a group of | ||
1120 | - stores. */ | ||
1121 | - return; | ||
1122 | - | ||
1123 | - /* For reductions, we only need initial values. */ | ||
1124 | - if (reduc_index != -1) | ||
1125 | - return; | ||
1126 | - | ||
1127 | - code = gimple_assign_rhs_code (first_stmt); | ||
1128 | - if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS || !vec_oprnds1) | ||
1129 | - return; | ||
1130 | - | ||
1131 | - /* The number of vector defs is determined by the number of vector statements | ||
1132 | - in the node from which we get those statements. */ | ||
1133 | - if (SLP_TREE_RIGHT (slp_node)) | ||
1134 | - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (SLP_TREE_RIGHT (slp_node)); | ||
1135 | - else | ||
1136 | - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); | ||
1137 | - | ||
1138 | - *vec_oprnds1 = VEC_alloc (tree, heap, number_of_vects); | ||
1139 | - | ||
1140 | - if (SLP_TREE_RIGHT (slp_node)) | ||
1141 | - /* The defs are already vectorized. */ | ||
1142 | - vect_get_slp_vect_defs (SLP_TREE_RIGHT (slp_node), vec_oprnds1); | ||
1143 | - else | ||
1144 | - /* Build vectors from scalar defs. */ | ||
1145 | - vect_get_constant_vectors (op1, slp_node, vec_oprnds1, 1, number_of_vects, | ||
1146 | - -1); | ||
1147 | } | ||
1148 | |||
1149 | - | ||
1150 | /* Create NCOPIES permutation statements using the mask MASK_BYTES (by | ||
1151 | building a vector of type MASK_TYPE from it) and two input vectors placed in | ||
1152 | DR_CHAIN at FIRST_VEC_INDX and SECOND_VEC_INDX for the first copy and | ||
1153 | @@ -2605,14 +2688,14 @@ | ||
1154 | tree vectype; | ||
1155 | int i; | ||
1156 | slp_tree loads_node; | ||
1157 | + slp_void_p child; | ||
1158 | |||
1159 | if (!node) | ||
1160 | return false; | ||
1161 | |||
1162 | - vect_schedule_slp_instance (SLP_TREE_LEFT (node), instance, | ||
1163 | - vectorization_factor); | ||
1164 | - vect_schedule_slp_instance (SLP_TREE_RIGHT (node), instance, | ||
1165 | - vectorization_factor); | ||
1166 | + FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) | ||
1167 | + vect_schedule_slp_instance ((slp_tree) child, instance, | ||
1168 | + vectorization_factor); | ||
1169 | |||
1170 | stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (node), 0); | ||
1171 | stmt_info = vinfo_for_stmt (stmt); | ||
1172 | |||
1173 | === modified file 'gcc/tree-vect-stmts.c' | ||
1174 | --- old/gcc/tree-vect-stmts.c 2011-10-27 11:27:59 +0000 | ||
1175 | +++ new/gcc/tree-vect-stmts.c 2011-11-14 11:38:08 +0000 | ||
1176 | @@ -1419,16 +1419,35 @@ | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | -/* Get vectorized definitions for OP0 and OP1, or SLP_NODE if it is not | ||
1181 | - NULL. */ | ||
1182 | +/* Get vectorized definitions for OP0 and OP1. | ||
1183 | + REDUC_INDEX is the index of reduction operand in case of reduction, | ||
1184 | + and -1 otherwise. */ | ||
1185 | |||
1186 | -static void | ||
1187 | +void | ||
1188 | vect_get_vec_defs (tree op0, tree op1, gimple stmt, | ||
1189 | - VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1, | ||
1190 | - slp_tree slp_node) | ||
1191 | + VEC (tree, heap) **vec_oprnds0, | ||
1192 | + VEC (tree, heap) **vec_oprnds1, | ||
1193 | + slp_tree slp_node, int reduc_index) | ||
1194 | { | ||
1195 | if (slp_node) | ||
1196 | - vect_get_slp_defs (op0, op1, slp_node, vec_oprnds0, vec_oprnds1, -1); | ||
1197 | + { | ||
1198 | + int nops = (op1 == NULL_TREE) ? 1 : 2; | ||
1199 | + VEC (tree, heap) *ops = VEC_alloc (tree, heap, nops); | ||
1200 | + VEC (slp_void_p, heap) *vec_defs = VEC_alloc (slp_void_p, heap, nops); | ||
1201 | + | ||
1202 | + VEC_quick_push (tree, ops, op0); | ||
1203 | + if (op1) | ||
1204 | + VEC_quick_push (tree, ops, op1); | ||
1205 | + | ||
1206 | + vect_get_slp_defs (ops, slp_node, &vec_defs, reduc_index); | ||
1207 | + | ||
1208 | + *vec_oprnds0 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 0); | ||
1209 | + if (op1) | ||
1210 | + *vec_oprnds1 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 1); | ||
1211 | + | ||
1212 | + VEC_free (tree, heap, ops); | ||
1213 | + VEC_free (slp_void_p, heap, vec_defs); | ||
1214 | + } | ||
1215 | else | ||
1216 | { | ||
1217 | tree vec_oprnd; | ||
1218 | @@ -2016,7 +2035,8 @@ | ||
1219 | for (j = 0; j < ncopies; j++) | ||
1220 | { | ||
1221 | if (j == 0) | ||
1222 | - vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node); | ||
1223 | + vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node, | ||
1224 | + -1); | ||
1225 | else | ||
1226 | vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL); | ||
1227 | |||
1228 | @@ -2221,7 +2241,7 @@ | ||
1229 | { | ||
1230 | /* Handle uses. */ | ||
1231 | if (j == 0) | ||
1232 | - vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node); | ||
1233 | + vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node, -1); | ||
1234 | else | ||
1235 | vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL); | ||
1236 | |||
1237 | @@ -2576,10 +2596,10 @@ | ||
1238 | operand 1 should be of a vector type (the usual case). */ | ||
1239 | if (vec_oprnd1) | ||
1240 | vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, | ||
1241 | - slp_node); | ||
1242 | + slp_node, -1); | ||
1243 | else | ||
1244 | vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, | ||
1245 | - slp_node); | ||
1246 | + slp_node, -1); | ||
1247 | } | ||
1248 | else | ||
1249 | vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1); | ||
1250 | @@ -2887,10 +2907,10 @@ | ||
1251 | { | ||
1252 | if (op_type == binary_op || op_type == ternary_op) | ||
1253 | vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, | ||
1254 | - slp_node); | ||
1255 | + slp_node, -1); | ||
1256 | else | ||
1257 | vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, | ||
1258 | - slp_node); | ||
1259 | + slp_node, -1); | ||
1260 | if (op_type == ternary_op) | ||
1261 | { | ||
1262 | vec_oprnds2 = VEC_alloc (tree, heap, 1); | ||
1263 | @@ -3202,7 +3222,8 @@ | ||
1264 | { | ||
1265 | /* Handle uses. */ | ||
1266 | if (slp_node) | ||
1267 | - vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, -1); | ||
1268 | + vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, | ||
1269 | + slp_node, -1); | ||
1270 | else | ||
1271 | { | ||
1272 | VEC_free (tree, heap, vec_oprnds0); | ||
1273 | @@ -3548,12 +3569,12 @@ | ||
1274 | for (k = 0; k < slp_node->vec_stmts_size - 1; k++) | ||
1275 | VEC_quick_push (tree, vec_oprnds1, vec_oprnd1); | ||
1276 | |||
1277 | - vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, | ||
1278 | - -1); | ||
1279 | + vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, | ||
1280 | + slp_node, -1); | ||
1281 | } | ||
1282 | else | ||
1283 | - vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, | ||
1284 | - &vec_oprnds1, -1); | ||
1285 | + vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, | ||
1286 | + &vec_oprnds1, slp_node, -1); | ||
1287 | } | ||
1288 | else | ||
1289 | { | ||
1290 | @@ -3796,6 +3817,7 @@ | ||
1291 | vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); | ||
1292 | first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); | ||
1293 | first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); | ||
1294 | + op = gimple_assign_rhs1 (first_stmt); | ||
1295 | } | ||
1296 | else | ||
1297 | /* VEC_NUM is the number of vect stmts to be created for this | ||
1298 | @@ -3878,8 +3900,8 @@ | ||
1299 | if (slp) | ||
1300 | { | ||
1301 | /* Get vectorized arguments for SLP_NODE. */ | ||
1302 | - vect_get_slp_defs (NULL_TREE, NULL_TREE, slp_node, &vec_oprnds, | ||
1303 | - NULL, -1); | ||
1304 | + vect_get_vec_defs (op, NULL_TREE, stmt, &vec_oprnds, | ||
1305 | + NULL, slp_node, -1); | ||
1306 | |||
1307 | vec_oprnd = VEC_index (tree, vec_oprnds, 0); | ||
1308 | } | ||
1309 | @@ -5040,7 +5062,7 @@ | ||
1310 | In basic blocks we only analyze statements that are a part of some SLP | ||
1311 | instance, therefore, all the statements are relevant. | ||
1312 | |||
1313 | - Pattern statement need to be analyzed instead of the original statement | ||
1314 | + Pattern statement needs to be analyzed instead of the original statement | ||
1315 | if the original statement is not relevant. Otherwise, we analyze both | ||
1316 | statements. */ | ||
1317 | |||
1318 | |||
1319 | === modified file 'gcc/tree-vectorizer.h' | ||
1320 | --- old/gcc/tree-vectorizer.h 2011-10-23 13:33:07 +0000 | ||
1321 | +++ new/gcc/tree-vectorizer.h 2011-11-14 11:38:08 +0000 | ||
1322 | @@ -73,15 +73,15 @@ | ||
1323 | /************************************************************************ | ||
1324 | SLP | ||
1325 | ************************************************************************/ | ||
1326 | +typedef void *slp_void_p; | ||
1327 | +DEF_VEC_P (slp_void_p); | ||
1328 | +DEF_VEC_ALLOC_P (slp_void_p, heap); | ||
1329 | |||
1330 | -/* A computation tree of an SLP instance. Each node corresponds to a group of | ||
1331 | +/* A computation tree of an SLP instance. Each node corresponds to a group of | ||
1332 | stmts to be packed in a SIMD stmt. */ | ||
1333 | typedef struct _slp_tree { | ||
1334 | - /* Only binary and unary operations are supported. LEFT child corresponds to | ||
1335 | - the first operand and RIGHT child to the second if the operation is | ||
1336 | - binary. */ | ||
1337 | - struct _slp_tree *left; | ||
1338 | - struct _slp_tree *right; | ||
1339 | + /* Nodes that contain def-stmts of this node statements operands. */ | ||
1340 | + VEC (slp_void_p, heap) *children; | ||
1341 | /* A group of scalar stmts to be vectorized together. */ | ||
1342 | VEC (gimple, heap) *stmts; | ||
1343 | /* Vectorized stmt/s. */ | ||
1344 | @@ -146,14 +146,32 @@ | ||
1345 | #define SLP_INSTANCE_LOADS(S) (S)->loads | ||
1346 | #define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load | ||
1347 | |||
1348 | -#define SLP_TREE_LEFT(S) (S)->left | ||
1349 | -#define SLP_TREE_RIGHT(S) (S)->right | ||
1350 | +#define SLP_TREE_CHILDREN(S) (S)->children | ||
1351 | #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts | ||
1352 | #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts | ||
1353 | #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size | ||
1354 | #define SLP_TREE_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop | ||
1355 | #define SLP_TREE_INSIDE_OF_LOOP_COST(S) (S)->cost.inside_of_loop | ||
1356 | |||
1357 | +/* This structure is used in creation of an SLP tree. Each instance | ||
1358 | + corresponds to the same operand in a group of scalar stmts in an SLP | ||
1359 | + node. */ | ||
1360 | +typedef struct _slp_oprnd_info | ||
1361 | +{ | ||
1362 | + /* Def-stmts for the operands. */ | ||
1363 | + VEC (gimple, heap) *def_stmts; | ||
1364 | + /* Information about the first statement, its vector def-type, type, the | ||
1365 | + operand itself in case it's constant, and an indication if it's a pattern | ||
1366 | + stmt. */ | ||
1367 | + enum vect_def_type first_dt; | ||
1368 | + tree first_def_type; | ||
1369 | + tree first_const_oprnd; | ||
1370 | + bool first_pattern; | ||
1371 | +} *slp_oprnd_info; | ||
1372 | + | ||
1373 | +DEF_VEC_P(slp_oprnd_info); | ||
1374 | +DEF_VEC_ALLOC_P(slp_oprnd_info, heap); | ||
1375 | + | ||
1376 | |||
1377 | typedef struct _vect_peel_info | ||
1378 | { | ||
1379 | @@ -819,6 +837,8 @@ | ||
1380 | unsigned int *, unsigned int *); | ||
1381 | extern void vect_get_store_cost (struct data_reference *, int, unsigned int *); | ||
1382 | extern bool vect_supportable_shift (enum tree_code, tree); | ||
1383 | +extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **, | ||
1384 | + VEC (tree, heap) **, slp_tree, int); | ||
1385 | |||
1386 | /* In tree-vect-data-refs.c. */ | ||
1387 | extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int); | ||
1388 | @@ -885,8 +905,9 @@ | ||
1389 | extern bool vect_analyze_slp (loop_vec_info, bb_vec_info); | ||
1390 | extern void vect_make_slp_decision (loop_vec_info); | ||
1391 | extern void vect_detect_hybrid_slp (loop_vec_info); | ||
1392 | -extern void vect_get_slp_defs (tree, tree, slp_tree, VEC (tree,heap) **, | ||
1393 | - VEC (tree,heap) **, int); | ||
1394 | +extern void vect_get_slp_defs (VEC (tree, heap) *, slp_tree, | ||
1395 | + VEC (slp_void_p, heap) **, int); | ||
1396 | + | ||
1397 | extern LOC find_bb_location (basic_block); | ||
1398 | extern bb_vec_info vect_slp_analyze_bb (basic_block); | ||
1399 | extern void vect_slp_transform_bb (basic_block); | ||
1400 | |||