summaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106840.patch
diff options
context:
space:
mode:
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.patch1400
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 @@
12011-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