OSDN Git Service

Add smaxv2di3, umaxv2di3, sminv2di3 and uminv2di3
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-slp.c
index fe88e1d..a3be678 100644 (file)
@@ -796,6 +796,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
 {
   int i = 0, j, prev = -1, next, k;
   bool supported;
+  sbitmap load_index;
 
   /* FORNOW: permutations are only supported in SLP.  */
   if (!slp_instn)
@@ -816,6 +817,8 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
     return false;
 
   supported = true;
+  load_index = sbitmap_alloc (group_size);
+  sbitmap_zero (load_index);
   for (j = 0; j < group_size; j++)
     {
       for (i = j * group_size, k = 0;
@@ -830,7 +833,17 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
 
          prev = next;
        }
+
+      if (TEST_BIT (load_index, prev))
+        {
+          supported = false;
+          break;
+        }
+
+      SET_BIT (load_index, prev);
     }
+  
+  sbitmap_free (load_index);
 
   if (supported && i == group_size * group_size
       && vect_supported_slp_permutation_p (slp_instn))
@@ -879,7 +892,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
   unsigned int unrolling_factor = 1, nunits;
   tree vectype, scalar_type;
   gimple next;
-  unsigned int vectorization_factor = 0, ncopies;
+  unsigned int vectorization_factor = 0;
   int inside_cost = 0, outside_cost = 0, ncopies_for_cost;
   unsigned int max_nunits = 0;
   VEC (int, heap) *load_permutation;
@@ -905,8 +918,6 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
     /* No multitypes in BB SLP.  */
     vectorization_factor = nunits;
 
-  ncopies = vectorization_factor / nunits;
-
   /* Calculate the unrolling factor.  */
   unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
   if (unrolling_factor != 1 && !loop_vinfo)
@@ -1630,31 +1641,20 @@ 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;
+  int i, stride;
   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);
 
   /* Initialize the vect stmts of NODE to properly insert the generated
      stmts later.  */
@@ -1890,7 +1890,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 +1924,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++);
                     }
                 }
             }