diff options
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 @@ -2011-11-17 Ira Rosen <ira.rosen@linaro.org> - - Backport from mainline: - - 2011-11-03 Ira Rosen <ira.rosen@linaro.org> - - gcc/ - * tree-vectorizer.h (slp_void_p): New. - (struct _slp_tree): Replace left and right with children. Update - documentation. - (struct _slp_oprnd_info): New. - (vect_get_vec_defs): Declare. - (vect_get_slp_defs): Update arguments. - * tree-vect-loop.c (vect_create_epilog_for_reduction): Call - vect_get_vec_defs instead of vect_get_slp_defs. - (vectorizable_reduction): Likewise. - * tree-vect-stmts.c (vect_get_vec_defs): Remove static, add argument. - Update call to vect_get_slp_defs. - (vectorizable_conversion): Update call to vect_get_vec_defs. - (vectorizable_assignment, vectorizable_shift, - vectorizable_operation): Likewise. - (vectorizable_type_demotion): Call vect_get_vec_defs instead of - vect_get_slp_defs. - (vectorizable_type_promotion, vectorizable_store): Likewise. - (vect_analyze_stmt): Fix typo. - * tree-vect-slp.c (vect_free_slp_tree): Update SLP tree traversal. - (vect_print_slp_tree, vect_mark_slp_stmts, - vect_mark_slp_stmts_relevant, vect_slp_rearrange_stmts, - vect_detect_hybrid_slp_stmts, vect_slp_analyze_node_operations, - vect_schedule_slp_instance): Likewise. - (vect_create_new_slp_node): New. - (vect_create_oprnd_info, vect_free_oprnd_info): Likewise. - (vect_get_and_check_slp_defs): Pass information about defs using - oprnds_info, allow any number of operands. - (vect_build_slp_tree): Likewise. Update calls to - vect_get_and_check_slp_defs. Fix comments. - (vect_analyze_slp_instance): Move node creation to - vect_create_new_slp_node. - (vect_get_slp_defs): Allow any number of operands. - - 2011-11-11 Jakub Jelinek <jakub@redhat.com> - - gcc/ - * tree-vect-slp.c (vect_free_slp_tree): Also free SLP_TREE_CHILDREN - vector. - (vect_create_new_slp_node): Don't allocate node before checking stmt - type. - (vect_free_oprnd_info): Remove FREE_DEF_STMTS argument, always - free def_stmts vectors and additionally free oprnd_info. - (vect_build_slp_tree): Adjust callers. Call it even if - stop_recursion. If vect_create_new_slp_node or - vect_build_slp_tree fails, properly handle freeing memory. - If it succeeded, clear def_stmts in oprnd_info. - -=== modified file 'gcc/tree-vect-loop.c' ---- old/gcc/tree-vect-loop.c 2011-09-05 06:23:37 +0000 -+++ new/gcc/tree-vect-loop.c 2011-11-14 11:38:08 +0000 -@@ -3282,8 +3282,8 @@ - - /* Get the loop-entry arguments. */ - if (slp_node) -- vect_get_slp_defs (reduction_op, NULL_TREE, slp_node, &vec_initial_defs, -- NULL, reduc_index); -+ vect_get_vec_defs (reduction_op, NULL_TREE, stmt, &vec_initial_defs, -+ NULL, slp_node, reduc_index); - else - { - vec_initial_defs = VEC_alloc (tree, heap, 1); -@@ -4451,8 +4451,8 @@ - } - - if (slp_node) -- vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, &vec_oprnds1, -- -1); -+ vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, -+ slp_node, -1); - else - { - loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index], - -=== modified file 'gcc/tree-vect-slp.c' ---- old/gcc/tree-vect-slp.c 2011-10-27 11:27:59 +0000 -+++ new/gcc/tree-vect-slp.c 2011-11-14 11:38:08 +0000 -@@ -67,15 +67,16 @@ - static void - vect_free_slp_tree (slp_tree node) - { -+ int i; -+ slp_void_p child; -+ - if (!node) - return; - -- if (SLP_TREE_LEFT (node)) -- vect_free_slp_tree (SLP_TREE_LEFT (node)); -- -- if (SLP_TREE_RIGHT (node)) -- vect_free_slp_tree (SLP_TREE_RIGHT (node)); -- -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_free_slp_tree ((slp_tree) child); -+ -+ VEC_free (slp_void_p, heap, SLP_TREE_CHILDREN (node)); - VEC_free (gimple, heap, SLP_TREE_SCALAR_STMTS (node)); - - if (SLP_TREE_VEC_STMTS (node)) -@@ -96,48 +97,116 @@ - } - - --/* Get the defs for the rhs of STMT (collect them in DEF_STMTS0/1), check that -- they are of a legal type and that they match the defs of the first stmt of -- the SLP group (stored in FIRST_STMT_...). */ -+/* Create an SLP node for SCALAR_STMTS. */ -+ -+static slp_tree -+vect_create_new_slp_node (VEC (gimple, heap) *scalar_stmts) -+{ -+ slp_tree node; -+ gimple stmt = VEC_index (gimple, scalar_stmts, 0); -+ unsigned int nops; -+ -+ if (is_gimple_call (stmt)) -+ nops = gimple_call_num_args (stmt); -+ else if (is_gimple_assign (stmt)) -+ nops = gimple_num_ops (stmt) - 1; -+ else -+ return NULL; -+ -+ node = XNEW (struct _slp_tree); -+ SLP_TREE_SCALAR_STMTS (node) = scalar_stmts; -+ SLP_TREE_VEC_STMTS (node) = NULL; -+ SLP_TREE_CHILDREN (node) = VEC_alloc (slp_void_p, heap, nops); -+ SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0; -+ SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0; -+ -+ return node; -+} -+ -+ -+/* Allocate operands info for NOPS operands, and GROUP_SIZE def-stmts for each -+ operand. */ -+static VEC (slp_oprnd_info, heap) * -+vect_create_oprnd_info (int nops, int group_size) -+{ -+ int i; -+ slp_oprnd_info oprnd_info; -+ VEC (slp_oprnd_info, heap) *oprnds_info; -+ -+ oprnds_info = VEC_alloc (slp_oprnd_info, heap, nops); -+ for (i = 0; i < nops; i++) -+ { -+ oprnd_info = XNEW (struct _slp_oprnd_info); -+ oprnd_info->def_stmts = VEC_alloc (gimple, heap, group_size); -+ oprnd_info->first_dt = vect_uninitialized_def; -+ oprnd_info->first_def_type = NULL_TREE; -+ oprnd_info->first_const_oprnd = NULL_TREE; -+ oprnd_info->first_pattern = false; -+ VEC_quick_push (slp_oprnd_info, oprnds_info, oprnd_info); -+ } -+ -+ return oprnds_info; -+} -+ -+ -+/* Free operands info. */ -+ -+static void -+vect_free_oprnd_info (VEC (slp_oprnd_info, heap) **oprnds_info) -+{ -+ int i; -+ slp_oprnd_info oprnd_info; -+ -+ FOR_EACH_VEC_ELT (slp_oprnd_info, *oprnds_info, i, oprnd_info) -+ { -+ VEC_free (gimple, heap, oprnd_info->def_stmts); -+ XDELETE (oprnd_info); -+ } -+ -+ VEC_free (slp_oprnd_info, heap, *oprnds_info); -+} -+ -+ -+/* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that -+ they are of a valid type and that they match the defs of the first stmt of -+ the SLP group (stored in OPRNDS_INFO). */ - - static bool - vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, - slp_tree slp_node, gimple stmt, -- VEC (gimple, heap) **def_stmts0, -- VEC (gimple, heap) **def_stmts1, -- enum vect_def_type *first_stmt_dt0, -- enum vect_def_type *first_stmt_dt1, -- tree *first_stmt_def0_type, -- tree *first_stmt_def1_type, -- tree *first_stmt_const_oprnd, -- int ncopies_for_cost, -- bool *pattern0, bool *pattern1) -+ int ncopies_for_cost, bool first, -+ VEC (slp_oprnd_info, heap) **oprnds_info) - { - tree oprnd; - unsigned int i, number_of_oprnds; -- tree def[2]; -+ tree def, def_op0 = NULL_TREE; - gimple def_stmt; -- enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; -- stmt_vec_info stmt_info = -- vinfo_for_stmt (VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0)); -- enum gimple_rhs_class rhs_class; -+ enum vect_def_type dt = vect_uninitialized_def; -+ enum vect_def_type dt_op0 = vect_uninitialized_def; -+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt); -+ tree lhs = gimple_get_lhs (stmt); - struct loop *loop = NULL; - enum tree_code rhs_code; - bool different_types = false; -+ bool pattern = false; -+ slp_oprnd_info oprnd_info, oprnd0_info, oprnd1_info; - - if (loop_vinfo) - loop = LOOP_VINFO_LOOP (loop_vinfo); - -- rhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt)); -- number_of_oprnds = gimple_num_ops (stmt) - 1; /* RHS only */ -+ if (is_gimple_call (stmt)) -+ number_of_oprnds = gimple_call_num_args (stmt); -+ else -+ number_of_oprnds = gimple_num_ops (stmt) - 1; - - for (i = 0; i < number_of_oprnds; i++) - { - oprnd = gimple_op (stmt, i + 1); -+ oprnd_info = VEC_index (slp_oprnd_info, *oprnds_info, i); - -- if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def[i], -- &dt[i]) -- || (!def_stmt && dt[i] != vect_constant_def)) -+ if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def, -+ &dt) -+ || (!def_stmt && dt != vect_constant_def)) - { - if (vect_print_dump_info (REPORT_SLP)) - { -@@ -158,29 +227,24 @@ - && !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt)) - && !STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt))) - { -- if (!*first_stmt_dt0) -- *pattern0 = true; -- else -- { -- if (i == 1 && !*first_stmt_dt1) -- *pattern1 = true; -- else if ((i == 0 && !*pattern0) || (i == 1 && !*pattern1)) -- { -- if (vect_print_dump_info (REPORT_DETAILS)) -- { -- fprintf (vect_dump, "Build SLP failed: some of the stmts" -- " are in a pattern, and others are not "); -- print_generic_expr (vect_dump, oprnd, TDF_SLIM); -- } -+ pattern = true; -+ if (!first && !oprnd_info->first_pattern) -+ { -+ if (vect_print_dump_info (REPORT_DETAILS)) -+ { -+ fprintf (vect_dump, "Build SLP failed: some of the stmts" -+ " are in a pattern, and others are not "); -+ print_generic_expr (vect_dump, oprnd, TDF_SLIM); -+ } - -- return false; -- } -+ return false; - } - - def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); -- dt[i] = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); -+ dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); - -- if (*dt == vect_unknown_def_type) -+ if (dt == vect_unknown_def_type -+ || STMT_VINFO_PATTERN_DEF_STMT (vinfo_for_stmt (def_stmt))) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "Unsupported pattern."); -@@ -190,11 +254,11 @@ - switch (gimple_code (def_stmt)) - { - case GIMPLE_PHI: -- def[i] = gimple_phi_result (def_stmt); -+ def = gimple_phi_result (def_stmt); - break; - - case GIMPLE_ASSIGN: -- def[i] = gimple_assign_lhs (def_stmt); -+ def = gimple_assign_lhs (def_stmt); - break; - - default: -@@ -204,117 +268,125 @@ - } - } - -- if (!*first_stmt_dt0) -+ if (first) - { -- /* op0 of the first stmt of the group - store its info. */ -- *first_stmt_dt0 = dt[i]; -- if (def[i]) -- *first_stmt_def0_type = TREE_TYPE (def[i]); -- else -- *first_stmt_const_oprnd = oprnd; -+ oprnd_info->first_dt = dt; -+ oprnd_info->first_pattern = pattern; -+ if (def) -+ { -+ oprnd_info->first_def_type = TREE_TYPE (def); -+ oprnd_info->first_const_oprnd = NULL_TREE; -+ } -+ else -+ { -+ oprnd_info->first_def_type = NULL_TREE; -+ oprnd_info->first_const_oprnd = oprnd; -+ } - -- /* Analyze costs (for the first stmt of the group only). */ -- if (rhs_class != GIMPLE_SINGLE_RHS) -- /* Not memory operation (we don't call this functions for loads). */ -- vect_model_simple_cost (stmt_info, ncopies_for_cost, dt, slp_node); -- else -- /* Store. */ -- vect_model_store_cost (stmt_info, ncopies_for_cost, false, -- dt[0], slp_node); -+ if (i == 0) -+ { -+ def_op0 = def; -+ dt_op0 = dt; -+ /* Analyze costs (for the first stmt of the group only). */ -+ if (REFERENCE_CLASS_P (lhs)) -+ /* Store. */ -+ vect_model_store_cost (stmt_info, ncopies_for_cost, false, -+ dt, slp_node); -+ else -+ /* Not memory operation (we don't call this function for -+ loads). */ -+ vect_model_simple_cost (stmt_info, ncopies_for_cost, &dt, -+ slp_node); -+ } - } - - else - { -- if (!*first_stmt_dt1 && i == 1) -- { -- /* op1 of the first stmt of the group - store its info. */ -- *first_stmt_dt1 = dt[i]; -- if (def[i]) -- *first_stmt_def1_type = TREE_TYPE (def[i]); -- else -- { -- /* We assume that the stmt contains only one constant -- operand. We fail otherwise, to be on the safe side. */ -- if (*first_stmt_const_oprnd) -- { -- if (vect_print_dump_info (REPORT_SLP)) -- fprintf (vect_dump, "Build SLP failed: two constant " -- "oprnds in stmt"); -- return false; -- } -- *first_stmt_const_oprnd = oprnd; -- } -- } -- else -- { -- /* Not first stmt of the group, check that the def-stmt/s match -- the def-stmt/s of the first stmt. */ -- if ((i == 0 -- && (*first_stmt_dt0 != dt[i] -- || (*first_stmt_def0_type && def[0] -- && !types_compatible_p (*first_stmt_def0_type, -- TREE_TYPE (def[0]))))) -- || (i == 1 -- && (*first_stmt_dt1 != dt[i] -- || (*first_stmt_def1_type && def[1] -- && !types_compatible_p (*first_stmt_def1_type, -- TREE_TYPE (def[1]))))) -- || (!def[i] -- && !types_compatible_p (TREE_TYPE (*first_stmt_const_oprnd), -- TREE_TYPE (oprnd))) -- || different_types) -- { -- if (i != number_of_oprnds - 1) -- different_types = true; -+ /* Not first stmt of the group, check that the def-stmt/s match -+ the def-stmt/s of the first stmt. Allow different definition -+ types for reduction chains: the first stmt must be a -+ vect_reduction_def (a phi node), and the rest -+ vect_internal_def. */ -+ if (((oprnd_info->first_dt != dt -+ && !(oprnd_info->first_dt == vect_reduction_def -+ && dt == vect_internal_def)) -+ || (oprnd_info->first_def_type != NULL_TREE -+ && def -+ && !types_compatible_p (oprnd_info->first_def_type, -+ TREE_TYPE (def)))) -+ || (!def -+ && !types_compatible_p (TREE_TYPE (oprnd_info->first_const_oprnd), -+ TREE_TYPE (oprnd))) -+ || different_types) -+ { -+ if (number_of_oprnds != 2) -+ { -+ if (vect_print_dump_info (REPORT_SLP)) -+ fprintf (vect_dump, "Build SLP failed: different types "); -+ -+ return false; -+ } -+ -+ /* Try to swap operands in case of binary operation. */ -+ if (i == 0) -+ different_types = true; -+ else -+ { -+ oprnd0_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); -+ if (is_gimple_assign (stmt) -+ && (rhs_code = gimple_assign_rhs_code (stmt)) -+ && TREE_CODE_CLASS (rhs_code) == tcc_binary -+ && commutative_tree_code (rhs_code) -+ && oprnd0_info->first_dt == dt -+ && oprnd_info->first_dt == dt_op0 -+ && def_op0 && def -+ && !(oprnd0_info->first_def_type -+ && !types_compatible_p (oprnd0_info->first_def_type, -+ TREE_TYPE (def))) -+ && !(oprnd_info->first_def_type -+ && !types_compatible_p (oprnd_info->first_def_type, -+ TREE_TYPE (def_op0)))) -+ { -+ if (vect_print_dump_info (REPORT_SLP)) -+ { -+ fprintf (vect_dump, "Swapping operands of "); -+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); -+ } -+ -+ swap_tree_operands (stmt, gimple_assign_rhs1_ptr (stmt), -+ gimple_assign_rhs2_ptr (stmt)); -+ } - else -- { -- if (is_gimple_assign (stmt) -- && (rhs_code = gimple_assign_rhs_code (stmt)) -- && TREE_CODE_CLASS (rhs_code) == tcc_binary -- && commutative_tree_code (rhs_code) -- && *first_stmt_dt0 == dt[1] -- && *first_stmt_dt1 == dt[0] -- && def[0] && def[1] -- && !(*first_stmt_def0_type -- && !types_compatible_p (*first_stmt_def0_type, -- TREE_TYPE (def[1]))) -- && !(*first_stmt_def1_type -- && !types_compatible_p (*first_stmt_def1_type, -- TREE_TYPE (def[0])))) -- { -- if (vect_print_dump_info (REPORT_SLP)) -- { -- fprintf (vect_dump, "Swapping operands of "); -- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); -- } -- swap_tree_operands (stmt, gimple_assign_rhs1_ptr (stmt), -- gimple_assign_rhs2_ptr (stmt)); -- } -- else -- { -- if (vect_print_dump_info (REPORT_SLP)) -- fprintf (vect_dump, "Build SLP failed: different types "); -- -- return false; -- } -- } -+ { -+ if (vect_print_dump_info (REPORT_SLP)) -+ fprintf (vect_dump, "Build SLP failed: different types "); -+ -+ return false; -+ } - } - } - } - - /* Check the types of the definitions. */ -- switch (dt[i]) -+ switch (dt) - { - case vect_constant_def: - case vect_external_def: -+ case vect_reduction_def: - break; - - case vect_internal_def: -- case vect_reduction_def: -- if ((i == 0 && !different_types) || (i == 1 && different_types)) -- VEC_safe_push (gimple, heap, *def_stmts0, def_stmt); -+ if (different_types) -+ { -+ oprnd0_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); -+ oprnd1_info = VEC_index (slp_oprnd_info, *oprnds_info, 0); -+ if (i == 0) -+ VEC_quick_push (gimple, oprnd1_info->def_stmts, def_stmt); -+ else -+ VEC_quick_push (gimple, oprnd0_info->def_stmts, def_stmt); -+ } - else -- VEC_safe_push (gimple, heap, *def_stmts1, def_stmt); -+ VEC_quick_push (gimple, oprnd_info->def_stmts, def_stmt); - break; - - default: -@@ -322,7 +394,7 @@ - if (vect_print_dump_info (REPORT_SLP)) - { - fprintf (vect_dump, "Build SLP failed: illegal type of def "); -- print_generic_expr (vect_dump, def[i], TDF_SLIM); -+ print_generic_expr (vect_dump, def, TDF_SLIM); - } - - return false; -@@ -347,15 +419,10 @@ - VEC (slp_tree, heap) **loads, - unsigned int vectorization_factor, bool *loads_permuted) - { -- VEC (gimple, heap) *def_stmts0 = VEC_alloc (gimple, heap, group_size); -- VEC (gimple, heap) *def_stmts1 = VEC_alloc (gimple, heap, group_size); - unsigned int i; - VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node); - gimple stmt = VEC_index (gimple, stmts, 0); -- enum vect_def_type first_stmt_dt0 = vect_uninitialized_def; -- enum vect_def_type first_stmt_dt1 = vect_uninitialized_def; - enum tree_code first_stmt_code = ERROR_MARK, rhs_code = ERROR_MARK; -- tree first_stmt_def1_type = NULL_TREE, first_stmt_def0_type = NULL_TREE; - tree lhs; - bool stop_recursion = false, need_same_oprnds = false; - tree vectype, scalar_type, first_op1 = NULL_TREE; -@@ -364,13 +431,21 @@ - int icode; - enum machine_mode optab_op2_mode; - enum machine_mode vec_mode; -- tree first_stmt_const_oprnd = NULL_TREE; - struct data_reference *first_dr; -- bool pattern0 = false, pattern1 = false; - HOST_WIDE_INT dummy; - bool permutation = false; - unsigned int load_place; - gimple first_load, prev_first_load = NULL; -+ VEC (slp_oprnd_info, heap) *oprnds_info; -+ unsigned int nops; -+ slp_oprnd_info oprnd_info; -+ -+ if (is_gimple_call (stmt)) -+ nops = gimple_call_num_args (stmt); -+ else -+ nops = gimple_num_ops (stmt) - 1; -+ -+ oprnds_info = vect_create_oprnd_info (nops, group_size); - - /* For every stmt in NODE find its def stmt/s. */ - FOR_EACH_VEC_ELT (gimple, stmts, i, stmt) -@@ -391,6 +466,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -400,10 +476,11 @@ - if (vect_print_dump_info (REPORT_SLP)) - { - fprintf (vect_dump, -- "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL"); -+ "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL "); - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -416,6 +493,8 @@ - fprintf (vect_dump, "Build SLP failed: unsupported data-type "); - print_generic_expr (vect_dump, scalar_type, TDF_SLIM); - } -+ -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -462,6 +541,7 @@ - { - if (vect_print_dump_info (REPORT_SLP)) - fprintf (vect_dump, "Build SLP failed: no optab."); -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - icode = (int) optab_handler (optab, vec_mode); -@@ -470,6 +550,7 @@ - if (vect_print_dump_info (REPORT_SLP)) - fprintf (vect_dump, "Build SLP failed: " - "op not supported by target."); -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - optab_op2_mode = insn_data[icode].operand[2].mode; -@@ -506,6 +587,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -519,6 +601,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - } -@@ -530,15 +613,12 @@ - { - /* Store. */ - if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, -- stmt, &def_stmts0, &def_stmts1, -- &first_stmt_dt0, -- &first_stmt_dt1, -- &first_stmt_def0_type, -- &first_stmt_def1_type, -- &first_stmt_const_oprnd, -- ncopies_for_cost, -- &pattern0, &pattern1)) -- return false; -+ stmt, ncopies_for_cost, -+ (i == 0), &oprnds_info)) -+ { -+ vect_free_oprnd_info (&oprnds_info); -+ return false; -+ } - } - else - { -@@ -556,6 +636,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -573,6 +654,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -593,6 +675,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - } -@@ -612,6 +695,7 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -639,7 +723,7 @@ - { - if (TREE_CODE_CLASS (rhs_code) == tcc_reference) - { -- /* Not strided load. */ -+ /* Not strided load. */ - if (vect_print_dump_info (REPORT_SLP)) - { - fprintf (vect_dump, "Build SLP failed: not strided load "); -@@ -647,6 +731,7 @@ - } - - /* FORNOW: Not strided loads are not supported. */ -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - -@@ -661,19 +746,18 @@ - print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); - } - -+ vect_free_oprnd_info (&oprnds_info); - return false; - } - - /* Find the def-stmts. */ - if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, stmt, -- &def_stmts0, &def_stmts1, -- &first_stmt_dt0, &first_stmt_dt1, -- &first_stmt_def0_type, -- &first_stmt_def1_type, -- &first_stmt_const_oprnd, -- ncopies_for_cost, -- &pattern0, &pattern1)) -- return false; -+ ncopies_for_cost, (i == 0), -+ &oprnds_info)) -+ { -+ vect_free_oprnd_info (&oprnds_info); -+ return false; -+ } - } - } - -@@ -702,46 +786,37 @@ - *loads_permuted = true; - } - -+ vect_free_oprnd_info (&oprnds_info); - return true; - } - - /* Create SLP_TREE nodes for the definition node/s. */ -- if (first_stmt_dt0 == vect_internal_def) -- { -- slp_tree left_node = XNEW (struct _slp_tree); -- SLP_TREE_SCALAR_STMTS (left_node) = def_stmts0; -- SLP_TREE_VEC_STMTS (left_node) = NULL; -- SLP_TREE_LEFT (left_node) = NULL; -- SLP_TREE_RIGHT (left_node) = NULL; -- SLP_TREE_OUTSIDE_OF_LOOP_COST (left_node) = 0; -- SLP_TREE_INSIDE_OF_LOOP_COST (left_node) = 0; -- if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &left_node, group_size, -- inside_cost, outside_cost, ncopies_for_cost, -- max_nunits, load_permutation, loads, -- vectorization_factor, loads_permuted)) -- return false; -- -- SLP_TREE_LEFT (*node) = left_node; -- } -- -- if (first_stmt_dt1 == vect_internal_def) -- { -- slp_tree right_node = XNEW (struct _slp_tree); -- SLP_TREE_SCALAR_STMTS (right_node) = def_stmts1; -- SLP_TREE_VEC_STMTS (right_node) = NULL; -- SLP_TREE_LEFT (right_node) = NULL; -- SLP_TREE_RIGHT (right_node) = NULL; -- SLP_TREE_OUTSIDE_OF_LOOP_COST (right_node) = 0; -- SLP_TREE_INSIDE_OF_LOOP_COST (right_node) = 0; -- if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &right_node, group_size, -- inside_cost, outside_cost, ncopies_for_cost, -- max_nunits, load_permutation, loads, -- vectorization_factor, loads_permuted)) -- return false; -- -- SLP_TREE_RIGHT (*node) = right_node; -- } -- -+ FOR_EACH_VEC_ELT (slp_oprnd_info, oprnds_info, i, oprnd_info) -+ { -+ slp_tree child; -+ -+ if (oprnd_info->first_dt != vect_internal_def) -+ continue; -+ -+ child = vect_create_new_slp_node (oprnd_info->def_stmts); -+ if (!child -+ || !vect_build_slp_tree (loop_vinfo, bb_vinfo, &child, group_size, -+ inside_cost, outside_cost, ncopies_for_cost, -+ max_nunits, load_permutation, loads, -+ vectorization_factor, loads_permuted)) -+ { -+ if (child) -+ oprnd_info->def_stmts = NULL; -+ vect_free_slp_tree (child); -+ vect_free_oprnd_info (&oprnds_info); -+ return false; -+ } -+ -+ oprnd_info->def_stmts = NULL; -+ VEC_quick_push (slp_void_p, SLP_TREE_CHILDREN (*node), child); -+ } -+ -+ vect_free_oprnd_info (&oprnds_info); - return true; - } - -@@ -751,6 +826,7 @@ - { - int i; - gimple stmt; -+ slp_void_p child; - - if (!node) - return; -@@ -763,8 +839,8 @@ - } - fprintf (vect_dump, "\n"); - -- vect_print_slp_tree (SLP_TREE_LEFT (node)); -- vect_print_slp_tree (SLP_TREE_RIGHT (node)); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_print_slp_tree ((slp_tree) child); - } - - -@@ -778,6 +854,7 @@ - { - int i; - gimple stmt; -+ slp_void_p child; - - if (!node) - return; -@@ -786,8 +863,8 @@ - if (j < 0 || i == j) - STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark; - -- vect_mark_slp_stmts (SLP_TREE_LEFT (node), mark, j); -- vect_mark_slp_stmts (SLP_TREE_RIGHT (node), mark, j); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_mark_slp_stmts ((slp_tree) child, mark, j); - } - - -@@ -799,6 +876,7 @@ - int i; - gimple stmt; - stmt_vec_info stmt_info; -+ slp_void_p child; - - if (!node) - return; -@@ -811,8 +889,8 @@ - STMT_VINFO_RELEVANT (stmt_info) = vect_used_in_scope; - } - -- vect_mark_slp_stmts_relevant (SLP_TREE_LEFT (node)); -- vect_mark_slp_stmts_relevant (SLP_TREE_RIGHT (node)); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_mark_slp_stmts_relevant ((slp_tree) child); - } - - -@@ -885,12 +963,13 @@ - gimple stmt; - VEC (gimple, heap) *tmp_stmts; - unsigned int index, i; -+ slp_void_p child; - - if (!node) - return; - -- vect_slp_rearrange_stmts (SLP_TREE_LEFT (node), group_size, permutation); -- vect_slp_rearrange_stmts (SLP_TREE_RIGHT (node), group_size, permutation); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_slp_rearrange_stmts ((slp_tree) child, group_size, permutation); - - gcc_assert (group_size == VEC_length (gimple, SLP_TREE_SCALAR_STMTS (node))); - tmp_stmts = VEC_alloc (gimple, heap, group_size); -@@ -1253,7 +1332,7 @@ - gimple stmt) - { - slp_instance new_instance; -- slp_tree node = XNEW (struct _slp_tree); -+ slp_tree node; - unsigned int group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt)); - unsigned int unrolling_factor = 1, nunits; - tree vectype, scalar_type = NULL_TREE; -@@ -1265,6 +1344,7 @@ - VEC (slp_tree, heap) *loads; - struct data_reference *dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); - bool loads_permuted = false; -+ VEC (gimple, heap) *scalar_stmts; - - if (dr) - { -@@ -1308,39 +1388,26 @@ - } - - /* Create a node (a root of the SLP tree) for the packed strided stores. */ -- SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (gimple, heap, group_size); -+ scalar_stmts = VEC_alloc (gimple, heap, group_size); - next = stmt; - if (dr) - { - /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */ - while (next) - { -- VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); -+ VEC_safe_push (gimple, heap, scalar_stmts, next); - next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next)); - } - } - else - { - /* Collect reduction statements. */ -- for (i = 0; VEC_iterate (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, -- next); -- i++) -- { -- VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next); -- if (vect_print_dump_info (REPORT_DETAILS)) -- { -- fprintf (vect_dump, "pushing reduction into node: "); -- print_gimple_stmt (vect_dump, next, 0, TDF_SLIM); -- } -- } -+ VEC (gimple, heap) *reductions = LOOP_VINFO_REDUCTIONS (loop_vinfo); -+ for (i = 0; VEC_iterate (gimple, reductions, i, next); i++) -+ VEC_safe_push (gimple, heap, scalar_stmts, next); - } - -- SLP_TREE_VEC_STMTS (node) = NULL; -- SLP_TREE_NUMBER_OF_VEC_STMTS (node) = 0; -- SLP_TREE_LEFT (node) = NULL; -- SLP_TREE_RIGHT (node) = NULL; -- SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0; -- SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0; -+ node = vect_create_new_slp_node (scalar_stmts); - - /* Calculate the number of vector stmts to create based on the unrolling - factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is -@@ -1517,6 +1584,7 @@ - imm_use_iterator imm_iter; - gimple use_stmt; - stmt_vec_info stmt_vinfo; -+ slp_void_p child; - - if (!node) - return; -@@ -1534,8 +1602,8 @@ - == vect_reduction_def)) - vect_mark_slp_stmts (node, hybrid, i); - -- vect_detect_hybrid_slp_stmts (SLP_TREE_LEFT (node)); -- vect_detect_hybrid_slp_stmts (SLP_TREE_RIGHT (node)); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_detect_hybrid_slp_stmts ((slp_tree) child); - } - - -@@ -1625,13 +1693,14 @@ - bool dummy; - int i; - gimple stmt; -+ slp_void_p child; - - if (!node) - return true; - -- if (!vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_LEFT (node)) -- || !vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_RIGHT (node))) -- return false; -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ if (!vect_slp_analyze_node_operations (bb_vinfo, (slp_tree) child)) -+ return false; - - FOR_EACH_VEC_ELT (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt) - { -@@ -2207,88 +2276,102 @@ - If the scalar definitions are loop invariants or constants, collect them and - call vect_get_constant_vectors() to create vector stmts. - Otherwise, the def-stmts must be already vectorized and the vectorized stmts -- must be stored in the LEFT/RIGHT node of SLP_NODE, and we call -- vect_get_slp_vect_defs() to retrieve them. -- If VEC_OPRNDS1 is NULL, don't get vector defs for the second operand (from -- the right node. This is used when the second operand must remain scalar. */ -+ must be stored in the corresponding child of SLP_NODE, and we call -+ vect_get_slp_vect_defs () to retrieve them. */ - - void --vect_get_slp_defs (tree op0, tree op1, slp_tree slp_node, -- VEC (tree,heap) **vec_oprnds0, -- VEC (tree,heap) **vec_oprnds1, int reduc_index) -+vect_get_slp_defs (VEC (tree, heap) *ops, slp_tree slp_node, -+ VEC (slp_void_p, heap) **vec_oprnds, int reduc_index) - { -- gimple first_stmt; -- enum tree_code code; -- int number_of_vects; -+ gimple first_stmt, first_def; -+ int number_of_vects = 0, i; -+ unsigned int child_index = 0; - HOST_WIDE_INT lhs_size_unit, rhs_size_unit; -+ slp_tree child = NULL; -+ VEC (tree, heap) *vec_defs; -+ tree oprnd, def_lhs; -+ bool vectorized_defs; - - first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); -- /* The number of vector defs is determined by the number of vector statements -- in the node from which we get those statements. */ -- if (SLP_TREE_LEFT (slp_node)) -- number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (SLP_TREE_LEFT (slp_node)); -- else -- { -- number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); -- /* Number of vector stmts was calculated according to LHS in -- vect_schedule_slp_instance(), fix it by replacing LHS with RHS, if -- necessary. See vect_get_smallest_scalar_type () for details. */ -- vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, -- &rhs_size_unit); -- if (rhs_size_unit != lhs_size_unit) -- { -- number_of_vects *= rhs_size_unit; -- number_of_vects /= lhs_size_unit; -- } -+ FOR_EACH_VEC_ELT (tree, ops, i, oprnd) -+ { -+ /* For each operand we check if it has vectorized definitions in a child -+ node or we need to create them (for invariants and constants). We -+ check if the LHS of the first stmt of the next child matches OPRND. -+ If it does, we found the correct child. Otherwise, we call -+ vect_get_constant_vectors (), and not advance CHILD_INDEX in order -+ to check this child node for the next operand. */ -+ vectorized_defs = false; -+ if (VEC_length (slp_void_p, SLP_TREE_CHILDREN (slp_node)) > child_index) -+ { -+ child = (slp_tree) VEC_index (slp_void_p, -+ SLP_TREE_CHILDREN (slp_node), -+ child_index); -+ first_def = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (child), 0); -+ -+ /* In the end of a pattern sequence we have a use of the original stmt, -+ so we need to compare OPRND with the original def. */ -+ if (is_pattern_stmt_p (vinfo_for_stmt (first_def)) -+ && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt)) -+ && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt))) -+ first_def = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def)); -+ -+ if (is_gimple_call (first_def)) -+ def_lhs = gimple_call_lhs (first_def); -+ else -+ def_lhs = gimple_assign_lhs (first_def); -+ -+ if (operand_equal_p (oprnd, def_lhs, 0)) -+ { -+ /* The number of vector defs is determined by the number of -+ vector statements in the node from which we get those -+ statements. */ -+ number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); -+ vectorized_defs = true; -+ child_index++; -+ } -+ } -+ -+ if (!vectorized_defs) -+ { -+ if (i == 0) -+ { -+ number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); -+ /* Number of vector stmts was calculated according to LHS in -+ vect_schedule_slp_instance (), fix it by replacing LHS with -+ RHS, if necessary. See vect_get_smallest_scalar_type () for -+ details. */ -+ vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, -+ &rhs_size_unit); -+ if (rhs_size_unit != lhs_size_unit) -+ { -+ number_of_vects *= rhs_size_unit; -+ number_of_vects /= lhs_size_unit; -+ } -+ } -+ } -+ -+ /* Allocate memory for vectorized defs. */ -+ vec_defs = VEC_alloc (tree, heap, number_of_vects); -+ -+ /* For reduction defs we call vect_get_constant_vectors (), since we are -+ looking for initial loop invariant values. */ -+ if (vectorized_defs && reduc_index == -1) -+ /* The defs are already vectorized. */ -+ vect_get_slp_vect_defs (child, &vec_defs); -+ else -+ /* Build vectors from scalar defs. */ -+ vect_get_constant_vectors (oprnd, slp_node, &vec_defs, i, -+ number_of_vects, reduc_index); -+ -+ VEC_quick_push (slp_void_p, *vec_oprnds, (slp_void_p) vec_defs); -+ -+ /* For reductions, we only need initial values. */ -+ if (reduc_index != -1) -+ return; - } -- -- /* Allocate memory for vectorized defs. */ -- *vec_oprnds0 = VEC_alloc (tree, heap, number_of_vects); -- -- /* SLP_NODE corresponds either to a group of stores or to a group of -- unary/binary operations. We don't call this function for loads. -- For reduction defs we call vect_get_constant_vectors(), since we are -- looking for initial loop invariant values. */ -- if (SLP_TREE_LEFT (slp_node) && reduc_index == -1) -- /* The defs are already vectorized. */ -- vect_get_slp_vect_defs (SLP_TREE_LEFT (slp_node), vec_oprnds0); -- else -- /* Build vectors from scalar defs. */ -- vect_get_constant_vectors (op0, slp_node, vec_oprnds0, 0, number_of_vects, -- reduc_index); -- -- if (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt))) -- /* Since we don't call this function with loads, this is a group of -- stores. */ -- return; -- -- /* For reductions, we only need initial values. */ -- if (reduc_index != -1) -- return; -- -- code = gimple_assign_rhs_code (first_stmt); -- if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS || !vec_oprnds1) -- return; -- -- /* The number of vector defs is determined by the number of vector statements -- in the node from which we get those statements. */ -- if (SLP_TREE_RIGHT (slp_node)) -- number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (SLP_TREE_RIGHT (slp_node)); -- else -- number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); -- -- *vec_oprnds1 = VEC_alloc (tree, heap, number_of_vects); -- -- if (SLP_TREE_RIGHT (slp_node)) -- /* The defs are already vectorized. */ -- vect_get_slp_vect_defs (SLP_TREE_RIGHT (slp_node), vec_oprnds1); -- else -- /* Build vectors from scalar defs. */ -- vect_get_constant_vectors (op1, slp_node, vec_oprnds1, 1, number_of_vects, -- -1); - } - -- - /* Create NCOPIES permutation statements using the mask MASK_BYTES (by - building a vector of type MASK_TYPE from it) and two input vectors placed in - DR_CHAIN at FIRST_VEC_INDX and SECOND_VEC_INDX for the first copy and -@@ -2605,14 +2688,14 @@ - tree vectype; - int i; - slp_tree loads_node; -+ slp_void_p child; - - if (!node) - return false; - -- vect_schedule_slp_instance (SLP_TREE_LEFT (node), instance, -- vectorization_factor); -- vect_schedule_slp_instance (SLP_TREE_RIGHT (node), instance, -- vectorization_factor); -+ FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child) -+ vect_schedule_slp_instance ((slp_tree) child, instance, -+ vectorization_factor); - - stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (node), 0); - stmt_info = vinfo_for_stmt (stmt); - -=== modified file 'gcc/tree-vect-stmts.c' ---- old/gcc/tree-vect-stmts.c 2011-10-27 11:27:59 +0000 -+++ new/gcc/tree-vect-stmts.c 2011-11-14 11:38:08 +0000 -@@ -1419,16 +1419,35 @@ - } - - --/* Get vectorized definitions for OP0 and OP1, or SLP_NODE if it is not -- NULL. */ -+/* Get vectorized definitions for OP0 and OP1. -+ REDUC_INDEX is the index of reduction operand in case of reduction, -+ and -1 otherwise. */ - --static void -+void - vect_get_vec_defs (tree op0, tree op1, gimple stmt, -- VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1, -- slp_tree slp_node) -+ VEC (tree, heap) **vec_oprnds0, -+ VEC (tree, heap) **vec_oprnds1, -+ slp_tree slp_node, int reduc_index) - { - if (slp_node) -- vect_get_slp_defs (op0, op1, slp_node, vec_oprnds0, vec_oprnds1, -1); -+ { -+ int nops = (op1 == NULL_TREE) ? 1 : 2; -+ VEC (tree, heap) *ops = VEC_alloc (tree, heap, nops); -+ VEC (slp_void_p, heap) *vec_defs = VEC_alloc (slp_void_p, heap, nops); -+ -+ VEC_quick_push (tree, ops, op0); -+ if (op1) -+ VEC_quick_push (tree, ops, op1); -+ -+ vect_get_slp_defs (ops, slp_node, &vec_defs, reduc_index); -+ -+ *vec_oprnds0 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 0); -+ if (op1) -+ *vec_oprnds1 = (VEC (tree, heap) *) VEC_index (slp_void_p, vec_defs, 1); -+ -+ VEC_free (tree, heap, ops); -+ VEC_free (slp_void_p, heap, vec_defs); -+ } - else - { - tree vec_oprnd; -@@ -2016,7 +2035,8 @@ - for (j = 0; j < ncopies; j++) - { - if (j == 0) -- vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node); -+ vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node, -+ -1); - else - vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL); - -@@ -2221,7 +2241,7 @@ - { - /* Handle uses. */ - if (j == 0) -- vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node); -+ vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node, -1); - else - vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL); - -@@ -2576,10 +2596,10 @@ - operand 1 should be of a vector type (the usual case). */ - if (vec_oprnd1) - vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, -- slp_node); -+ slp_node, -1); - else - vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, -- slp_node); -+ slp_node, -1); - } - else - vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1); -@@ -2887,10 +2907,10 @@ - { - if (op_type == binary_op || op_type == ternary_op) - vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, -- slp_node); -+ slp_node, -1); - else - vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, -- slp_node); -+ slp_node, -1); - if (op_type == ternary_op) - { - vec_oprnds2 = VEC_alloc (tree, heap, 1); -@@ -3202,7 +3222,8 @@ - { - /* Handle uses. */ - if (slp_node) -- vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, -1); -+ vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, -+ slp_node, -1); - else - { - VEC_free (tree, heap, vec_oprnds0); -@@ -3548,12 +3569,12 @@ - for (k = 0; k < slp_node->vec_stmts_size - 1; k++) - VEC_quick_push (tree, vec_oprnds1, vec_oprnd1); - -- vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, -- -1); -+ vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, -+ slp_node, -1); - } - else -- vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, -- &vec_oprnds1, -1); -+ vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, -+ &vec_oprnds1, slp_node, -1); - } - else - { -@@ -3796,6 +3817,7 @@ - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); - first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); -+ op = gimple_assign_rhs1 (first_stmt); - } - else - /* VEC_NUM is the number of vect stmts to be created for this -@@ -3878,8 +3900,8 @@ - if (slp) - { - /* Get vectorized arguments for SLP_NODE. */ -- vect_get_slp_defs (NULL_TREE, NULL_TREE, slp_node, &vec_oprnds, -- NULL, -1); -+ vect_get_vec_defs (op, NULL_TREE, stmt, &vec_oprnds, -+ NULL, slp_node, -1); - - vec_oprnd = VEC_index (tree, vec_oprnds, 0); - } -@@ -5040,7 +5062,7 @@ - In basic blocks we only analyze statements that are a part of some SLP - instance, therefore, all the statements are relevant. - -- Pattern statement need to be analyzed instead of the original statement -+ Pattern statement needs to be analyzed instead of the original statement - if the original statement is not relevant. Otherwise, we analyze both - statements. */ - - -=== modified file 'gcc/tree-vectorizer.h' ---- old/gcc/tree-vectorizer.h 2011-10-23 13:33:07 +0000 -+++ new/gcc/tree-vectorizer.h 2011-11-14 11:38:08 +0000 -@@ -73,15 +73,15 @@ - /************************************************************************ - SLP - ************************************************************************/ -+typedef void *slp_void_p; -+DEF_VEC_P (slp_void_p); -+DEF_VEC_ALLOC_P (slp_void_p, heap); - --/* A computation tree of an SLP instance. Each node corresponds to a group of -+/* A computation tree of an SLP instance. Each node corresponds to a group of - stmts to be packed in a SIMD stmt. */ - typedef struct _slp_tree { -- /* Only binary and unary operations are supported. LEFT child corresponds to -- the first operand and RIGHT child to the second if the operation is -- binary. */ -- struct _slp_tree *left; -- struct _slp_tree *right; -+ /* Nodes that contain def-stmts of this node statements operands. */ -+ VEC (slp_void_p, heap) *children; - /* A group of scalar stmts to be vectorized together. */ - VEC (gimple, heap) *stmts; - /* Vectorized stmt/s. */ -@@ -146,14 +146,32 @@ - #define SLP_INSTANCE_LOADS(S) (S)->loads - #define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load - --#define SLP_TREE_LEFT(S) (S)->left --#define SLP_TREE_RIGHT(S) (S)->right -+#define SLP_TREE_CHILDREN(S) (S)->children - #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts - #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts - #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size - #define SLP_TREE_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop - #define SLP_TREE_INSIDE_OF_LOOP_COST(S) (S)->cost.inside_of_loop - -+/* This structure is used in creation of an SLP tree. Each instance -+ corresponds to the same operand in a group of scalar stmts in an SLP -+ node. */ -+typedef struct _slp_oprnd_info -+{ -+ /* Def-stmts for the operands. */ -+ VEC (gimple, heap) *def_stmts; -+ /* Information about the first statement, its vector def-type, type, the -+ operand itself in case it's constant, and an indication if it's a pattern -+ stmt. */ -+ enum vect_def_type first_dt; -+ tree first_def_type; -+ tree first_const_oprnd; -+ bool first_pattern; -+} *slp_oprnd_info; -+ -+DEF_VEC_P(slp_oprnd_info); -+DEF_VEC_ALLOC_P(slp_oprnd_info, heap); -+ - - typedef struct _vect_peel_info - { -@@ -819,6 +837,8 @@ - unsigned int *, unsigned int *); - extern void vect_get_store_cost (struct data_reference *, int, unsigned int *); - extern bool vect_supportable_shift (enum tree_code, tree); -+extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **, -+ VEC (tree, heap) **, slp_tree, int); - - /* In tree-vect-data-refs.c. */ - extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int); -@@ -885,8 +905,9 @@ - extern bool vect_analyze_slp (loop_vec_info, bb_vec_info); - extern void vect_make_slp_decision (loop_vec_info); - extern void vect_detect_hybrid_slp (loop_vec_info); --extern void vect_get_slp_defs (tree, tree, slp_tree, VEC (tree,heap) **, -- VEC (tree,heap) **, int); -+extern void vect_get_slp_defs (VEC (tree, heap) *, slp_tree, -+ VEC (slp_void_p, heap) **, int); -+ - extern LOC find_bb_location (basic_block); - extern bb_vec_info vect_slp_analyze_bb (basic_block); - extern void vect_slp_transform_bb (basic_block); - |