OSDN Git Service

* target.h (targetm.vectorize.builtin_vec_perm_ok): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Nov 2009 01:52:19 +0000 (01:52 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Nov 2009 01:52:19 +0000 (01:52 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154665 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/hooks.c
gcc/hooks.h
gcc/target-def.h
gcc/target.h
gcc/tree-vect-slp.c

index dfe7c91..625e168 100644 (file)
@@ -1,3 +1,13 @@
+2009-11-25  Richard Henderson  <rth@redhat.com>
+
+       * 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  <jakub@redhat.com>
 
        * config/rs6000/sysv4.opt (mregnames): Change Var to rs6000_regnames.
index ccbce01..fd3c837 100644 (file)
@@ -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;
index e0430de..38296da 100644 (file)
@@ -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);
index c57977b..0fe5d13 100644 (file)
 #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
 
     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
index 477a512..e5df4ef 100644 (file)
@@ -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.  */
index fe88e1d..76227aa 100644 (file)
@@ -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++);
                     }
                 }
             }