* New target hook for validating builtin_vec_perm input
@ 2009-11-26 2:11 Richard Henderson
0 siblings, 0 replies; only message in thread
From: Richard Henderson @ 2009-11-26 2:11 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 397 bytes --]
On ix86 before SSSE3 we don't have the capability for general two vector
permutation. Rather than give up entirely, we can ask the backend if a
given permutation is one that it knows how to implement.
The default hook simply returns true, so powerpc should be unaffected.
Tested on x86_64 with additional patches to actually implement the both
builtin_vec_perm and builtin_vec_perm_ok.
r~
[-- Attachment #2: z --]
[-- Type: text/plain, Size: 5994 bytes --]
* 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.
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..38296da 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++);
}
}
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-11-26 1:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-26 2:11 New target hook for validating builtin_vec_perm input Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).