From faf63e396340307be88e36e86b1d30d0f8d88b14 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 25 Nov 2009 17:52:19 -0800 Subject: target.h (targetm.vectorize.builtin_vec_perm_ok): New. * target.h (targetm.vectorize.builtin_vec_perm_ok): New. * target-def.h (TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK): New. * hooks.h, hooks.c (hook_bool_tree_tree_true): New. * tree-vect-slp.c (vect_create_mask_and_perm): Don't create the vector constant here... (vect_transform_slp_perm_load): ... do it here instead. Validate that the permutation vector is implementable by the target. From-SVN: r154665 --- gcc/ChangeLog | 10 ++++++++++ gcc/hooks.c | 6 ++++++ gcc/hooks.h | 1 + gcc/target-def.h | 5 ++++- gcc/target.h | 4 ++++ gcc/tree-vect-slp.c | 43 +++++++++++++++++++++++++++---------------- 6 files changed, 52 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dfe7c91..625e168 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2009-11-25 Richard Henderson + + * target.h (targetm.vectorize.builtin_vec_perm_ok): New. + * target-def.h (TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK): New. + * hooks.h, hooks.c (hook_bool_tree_tree_true): New. + * tree-vect-slp.c (vect_create_mask_and_perm): Don't create + the vector constant here... + (vect_transform_slp_perm_load): ... do it here instead. Validate + that the permutation vector is implementable by the target. + 2009-11-25 Jakub Jelinek * config/rs6000/sysv4.opt (mregnames): Change Var to rs6000_regnames. diff --git a/gcc/hooks.c b/gcc/hooks.c index ccbce01..fd3c837 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -221,6 +221,12 @@ hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED) } bool +hook_bool_tree_tree_true (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED) +{ + return true; +} + +bool hook_bool_tree_bool_false (tree a ATTRIBUTE_UNUSED, bool b ATTRIBUTE_UNUSED) { return false; diff --git a/gcc/hooks.h b/gcc/hooks.h index e0430de..38296da2 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -50,6 +50,7 @@ extern bool hook_bool_rtx_int_int_intp_bool_false (rtx, int, int, int *, bool); extern bool hook_bool_constcharptr_size_t_false (const char *, size_t); extern bool hook_bool_size_t_constcharptr_int_true (size_t, const char *, int); extern bool hook_bool_tree_tree_false (tree, tree); +extern bool hook_bool_tree_tree_true (tree, tree); extern bool hook_bool_tree_bool_false (tree, bool); extern void hook_void_void (void); diff --git a/gcc/target-def.h b/gcc/target-def.h index c57977b..0fe5d13 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -391,6 +391,8 @@ #define TARGET_VECTOR_ALIGNMENT_REACHABLE \ default_builtin_vector_alignment_reachable #define TARGET_VECTORIZE_BUILTIN_VEC_PERM 0 +#define TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK \ + hook_bool_tree_tree_true #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ default_builtin_support_vector_misalignment @@ -405,7 +407,8 @@ TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST, \ TARGET_VECTOR_ALIGNMENT_REACHABLE, \ TARGET_VECTORIZE_BUILTIN_VEC_PERM, \ - TARGET_SUPPORT_VECTOR_MISALIGNMENT \ + TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK, \ + TARGET_SUPPORT_VECTOR_MISALIGNMENT \ } #define TARGET_DEFAULT_TARGET_FLAGS 0 diff --git a/gcc/target.h b/gcc/target.h index 477a512..e5df4ef 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -490,6 +490,10 @@ struct gcc_target /* Target builtin that implements vector permute. */ tree (* builtin_vec_perm) (tree, tree*); + + /* Return true if a vector created for builtin_vec_perm is valid. */ + bool (* builtin_vec_perm_ok) (tree, tree); + /* Return true if the target supports misaligned store/load of a specific factor denoted in the third parameter. The last parameter is true if the access is defined in a packed struct. */ diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index fe88e1d..76227aa 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1630,28 +1630,19 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0, static inline void vect_create_mask_and_perm (gimple stmt, gimple next_scalar_stmt, - int *mask_array, int mask_nunits, - tree mask_element_type, tree mask_type, - int first_vec_indx, int second_vec_indx, + tree mask, int first_vec_indx, int second_vec_indx, gimple_stmt_iterator *gsi, slp_tree node, tree builtin_decl, tree vectype, VEC(tree,heap) *dr_chain, int ncopies, int vect_stmts_counter) { - tree t = NULL_TREE, mask_vec, mask, perm_dest; + tree perm_dest; gimple perm_stmt = NULL; stmt_vec_info next_stmt_info; int i, group_size, stride, dr_chain_size; tree first_vec, second_vec, data_ref; VEC (tree, heap) *params = NULL; - /* Create a vector mask. */ - for (i = mask_nunits - 1; i >= 0; --i) - t = tree_cons (NULL_TREE, build_int_cst (mask_element_type, mask_array[i]), - t); - mask_vec = build_vector (mask_type, t); - mask = vect_init_vector (stmt, mask_vec, mask_type, NULL); - group_size = VEC_length (gimple, SLP_TREE_SCALAR_STMTS (node)); stride = SLP_TREE_NUMBER_OF_VEC_STMTS (node) / ncopies; dr_chain_size = VEC_length (tree, dr_chain); @@ -1890,7 +1881,28 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain, if (index == mask_nunits) { - index = 0; + tree mask_vec = NULL; + + while (--index >= 0) + { + tree t = build_int_cst (mask_element_type, mask[index]); + mask_vec = tree_cons (NULL, t, mask_vec); + } + mask_vec = build_vector (mask_type, mask_vec); + index = 0; + + if (!targetm.vectorize.builtin_vec_perm_ok (vectype, + mask_vec)) + { + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "unsupported vect permute "); + print_generic_expr (vect_dump, mask_vec, 0); + } + free (mask); + return false; + } + if (!analyze_only) { if (need_next_vector) @@ -1903,10 +1915,9 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain, SLP_TREE_SCALAR_STMTS (node), scalar_index++); vect_create_mask_and_perm (stmt, next_scalar_stmt, - mask, mask_nunits, mask_element_type, mask_type, - first_vec_index, second_vec_index, gsi, node, - builtin_decl, vectype, dr_chain, ncopies, - vect_stmts_counter++); + mask_vec, first_vec_index, second_vec_index, + gsi, node, builtin_decl, vectype, dr_chain, + ncopies, vect_stmts_counter++); } } } -- cgit v1.1