OSDN Git Service

* tree-vect-stmts.c (vectorizable_type_demotion): Handle basic
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Sep 2011 12:26:34 +0000 (12:26 +0000)
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Sep 2011 12:26:34 +0000 (12:26 +0000)
        block vectorization.
        (vectorizable_type_promotion): Likewise.
        (vect_analyze_stmt): Call vectorizable_type_demotion and
        vectorizable_type_promotion for basic blocks.
        (supportable_widening_operation): Don't assume loop
        vectorization.
        * tree-vect-slp.c (vect_build_slp_tree): Allow multiple types
        for basic blocks.  Update vectorization factor for basic block
        vectorization.
        (vect_analyze_slp_instance): Allow multiple types for basic
        block vectorization.  Recheck unrolling factor after
        construction of SLP instance.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/bb-slp-11.c
gcc/testsuite/gcc.dg/vect/bb-slp-27.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/bb-slp-28.c [new file with mode: 0644]
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c

index f346ed7..1f01b9e 100644 (file)
@@ -1,3 +1,18 @@
+2011-09-27  Ira Rosen  <ira.rosen@linaro.org>
+
+       * tree-vect-stmts.c (vectorizable_type_demotion): Handle basic block
+       vectorization.
+       (vectorizable_type_promotion): Likewise.
+       (vect_analyze_stmt): Call vectorizable_type_demotion and
+       vectorizable_type_promotion for basic blocks.
+       (supportable_widening_operation): Don't assume loop vectorization.
+       * tree-vect-slp.c (vect_build_slp_tree): Allow multiple types for
+       basic blocks.  Update vectorization factor for basic block
+       vectorization.
+       (vect_analyze_slp_instance): Allow multiple types for basic block
+       vectorization.  Recheck unrolling factor after construction of SLP
+       instance.
+
 2011-09-27  Richard Guenther  <rguenther@suse.de>
 
        * tree-object-size.c (compute_object_sizes): Fix dumping of
index 57bfa8a..a45af3b 100644 (file)
@@ -1,3 +1,10 @@
+2011-09-27  Ira Rosen  <ira.rosen@linaro.org>
+
+       * gcc.dg/vect/bb-slp-11.c: Expect to get vectorized with 64-bit
+       vectors.
+       * gcc.dg/vect/bb-slp-27.c: New.
+       * gcc.dg/vect/bb-slp-28.c: New.
+
 2011-09-27  Bernd Schmidt  <bernds@codesourcery.com>
 
        * testsuite/lib/target-supports.exp (check_profiling_available):
index 677eb38..225d08e 100644 (file)
@@ -48,8 +48,6 @@ int main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
-/* { dg-final { scan-tree-dump-times "SLP with multiple types" 1 "slp" { xfail vect_multiple_sizes } } } */
-/* { dg-final { scan-tree-dump-times "SLP with multiple types" 2 "slp" { target vect_multiple_sizes } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect64 } } } */
 /* { dg-final { cleanup-tree-dump "slp" } } */
   
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
new file mode 100644 (file)
index 0000000..7157eba
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define A 3
+#define N 16
+
+short src[N], dst[N];
+
+void foo (int a)
+{
+  dst[0] += a*src[0];
+  dst[1] += a*src[1];
+  dst[2] += a*src[2];
+  dst[3] += a*src[3];
+  dst[4] += a*src[4];
+  dst[5] += a*src[5];
+  dst[6] += a*src[6];
+  dst[7] += a*src[7];
+}
+
+
+int main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N; i++)
+    {
+      dst[i] = 0;
+      src[i] = i;
+    }
+
+  foo (A);
+
+  for (i = 0; i < 8; i++)
+    {
+      if (dst[i] != A * i)
+        abort ();
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
new file mode 100644 (file)
index 0000000..996f8f3
--- /dev/null
@@ -0,0 +1,71 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define A 300
+#define N 16
+
+char src[N];
+short dst[N];
+short src1[N], dst1[N];
+
+void foo (int a)
+{
+  dst[0] = (short) (a * (int) src[0]);
+  dst[1] = (short) (a * (int) src[1]);
+  dst[2] = (short) (a * (int) src[2]);
+  dst[3] = (short) (a * (int) src[3]);
+  dst[4] = (short) (a * (int) src[4]);
+  dst[5] = (short) (a * (int) src[5]);
+  dst[6] = (short) (a * (int) src[6]);
+  dst[7] = (short) (a * (int) src[7]);
+  dst[8] = (short) (a * (int) src[8]);
+  dst[9] = (short) (a * (int) src[9]);
+  dst[10] = (short) (a * (int) src[10]);
+  dst[11] = (short) (a * (int) src[11]);
+  dst[12] = (short) (a * (int) src[12]);
+  dst[13] = (short) (a * (int) src[13]);
+  dst[14] = (short) (a * (int) src[14]);
+  dst[15] = (short) (a * (int) src[15]);
+
+  dst1[0] += src1[0];
+  dst1[1] += src1[1];
+  dst1[2] += src1[2];
+  dst1[3] += src1[3];
+  dst1[4] += src1[4];
+  dst1[5] += src1[5];
+  dst1[6] += src1[6];
+  dst1[7] += src1[7];
+}
+
+
+int main (void)
+{
+  int i;
+
+  check_vect ();
+
+  for (i = 0; i < N; i++)
+    {
+      dst[i] = 2;
+      dst1[i] = 0;
+      src[i] = i;
+      src1[i] = i+2;
+    }
+
+  foo (A);
+
+  for (i = 0; i < N; i++)
+    {
+      if (dst[i] != A * i
+          || (i < N/2 && dst1[i] != i + 2))
+        abort ();
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_int_mult &&  { vect_pack_trunc && vect_unpack } } } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
index 5dc5cf6..4b205bf 100644 (file)
@@ -393,20 +393,15 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
           return false;
         }
 
-      ncopies = vectorization_factor / TYPE_VECTOR_SUBPARTS (vectype);
-      if (ncopies != 1)
+      /* In case of multiple types we need to detect the smallest type.  */
+      if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
         {
-         if (vect_print_dump_info (REPORT_SLP))
-            fprintf (vect_dump, "SLP with multiple types ");
-
-          /* FORNOW: multiple types are unsupported in BB SLP.  */
-         if (bb_vinfo)
-           return false;
+          *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
+          if (bb_vinfo)
+            vectorization_factor = *max_nunits;
         }
 
-      /* In case of multiple types we need to detect the smallest type.  */
-      if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
-        *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
+      ncopies = vectorization_factor / TYPE_VECTOR_SUBPARTS (vectype);
 
       if (is_gimple_call (stmt))
        rhs_code = CALL_EXPR;
@@ -1201,7 +1196,6 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
   if (loop_vinfo)
     vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   else
-    /* No multitypes in BB SLP.  */
     vectorization_factor = nunits;
 
   /* Calculate the unrolling factor.  */
@@ -1257,16 +1251,23 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
                           &max_nunits, &load_permutation, &loads,
                           vectorization_factor))
     {
-      /* Create a new SLP instance.  */
-      new_instance = XNEW (struct _slp_instance);
-      SLP_INSTANCE_TREE (new_instance) = node;
-      SLP_INSTANCE_GROUP_SIZE (new_instance) = group_size;
-      /* Calculate the unrolling factor based on the smallest type in the
-         loop.  */
+      /* Calculate the unrolling factor based on the smallest type.  */
       if (max_nunits > nunits)
         unrolling_factor = least_common_multiple (max_nunits, group_size)
                            / group_size;
 
+      if (unrolling_factor != 1 && !loop_vinfo)
+        {
+          if (vect_print_dump_info (REPORT_SLP))
+            fprintf (vect_dump, "Build SLP failed: unrolling required in basic"
+                               " block SLP");
+          return false;
+        }
+
+      /* Create a new SLP instance.  */
+      new_instance = XNEW (struct _slp_instance);
+      SLP_INSTANCE_TREE (new_instance) = node;
+      SLP_INSTANCE_GROUP_SIZE (new_instance) = group_size;
       SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
       SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (new_instance) = outside_cost;
       SLP_INSTANCE_INSIDE_OF_LOOP_COST (new_instance) = inside_cost;
index 2c77091..8c2edad 100644 (file)
@@ -3039,11 +3039,9 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
   VEC (tree, heap) *vec_oprnds0 = NULL;
   VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
   tree last_oprnd, intermediate_type;
+  bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
 
-  /* FORNOW: not supported by basic block SLP vectorization.  */
-  gcc_assert (loop_vinfo);
-
-  if (!STMT_VINFO_RELEVANT_P (stmt_info))
+  if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
     return false;
 
   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -3071,7 +3069,7 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
             && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0))
             && CONVERT_EXPR_CODE_P (code))))
     return false;
-  if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL,
+  if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
                             &def_stmt, &def, &dt[0], &vectype_in))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -3318,11 +3316,9 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
   int multi_step_cvt = 0;
   VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
   VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
+  bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
 
-  /* FORNOW: not supported by basic block SLP vectorization.  */
-  gcc_assert (loop_vinfo);
-
-  if (!STMT_VINFO_RELEVANT_P (stmt_info))
+  if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
     return false;
 
   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -3351,7 +3347,7 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
             && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0))
             && CONVERT_EXPR_CODE_P (code))))
     return false;
-  if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL,
+  if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
                             &def_stmt, &def, &dt[0], &vectype_in))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -5083,7 +5079,9 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
     else
       {
         if (bb_vinfo)
-          ok = (vectorizable_shift (stmt, NULL, NULL, node)
+          ok = (vectorizable_type_promotion (stmt, NULL, NULL, node)
+                || vectorizable_type_demotion (stmt, NULL, NULL, node)
+               || vectorizable_shift (stmt, NULL, NULL, node)
                 || vectorizable_operation (stmt, NULL, NULL, node)
                 || vectorizable_assignment (stmt, NULL, NULL, node)
                 || vectorizable_load (stmt, NULL, NULL, node, NULL)
@@ -5719,7 +5717,7 @@ supportable_widening_operation (enum tree_code code, gimple stmt,
 {
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info);
-  struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
+  struct loop *vect_loop = NULL;
   bool ordered_p;
   enum machine_mode vec_mode;
   enum insn_code icode1, icode2;
@@ -5728,6 +5726,9 @@ supportable_widening_operation (enum tree_code code, gimple stmt,
   tree wide_vectype = vectype_out;
   enum tree_code c1, c2;
 
+  if (loop_info)
+    vect_loop = LOOP_VINFO_LOOP (loop_info);
+
   /* The result of a vectorized widening operation usually requires two vectors
      (because the widened results do not fit int one vector). The generated
      vector results would normally be expected to be generated in the same
@@ -5748,7 +5749,8 @@ supportable_widening_operation (enum tree_code code, gimple stmt,
      iterations in parallel).  We therefore don't allow to change the order
      of the computation in the inner-loop during outer-loop vectorization.  */
 
-   if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
+   if (vect_loop
+       && STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
        && !nested_in_vect_loop_p (vect_loop, stmt))
      ordered_p = false;
    else