tree-vectorizer.h (stmt_vec_info_type): Add enum value induc_vec_info_type.
authorDorit Nuzman <dorit@il.ibm.com>
Tue, 17 Apr 2007 07:31:45 +0000 (07:31 +0000)
committerDorit Nuzman <dorit@gcc.gnu.org>
Tue, 17 Apr 2007 07:31:45 +0000 (07:31 +0000)
        * tree-vectorizer.h (stmt_vec_info_type): Add enum value
        induc_vec_info_type.
        (vectorizable_induction): New function declaration.
        * tree-vect-transform.c (get_initial_def_for_induction): No need to
        check if already vectorized.  Find first place in BB where new stmts
        can be inserted.  Takes only one argument.
        (vectorizable_induction): New function.
        (vect_transform_stmt): Add case for induc_vec_info_type to call
        vectorizable_induction.
        (vect_transform_loop): Consider phis for vectorization.
        * tree-vect-analyze.c (vect_determine_vectorization_factor): Simplify
        condition.
        (analyze_operations): Call vectorizable_induction when analyzing phis.
        Fix comment.
        (vect_mark_stmts_to_be_vectorized): Remove redundant checks.
        (vect_mark_relevant): Include phis in relevance analysis.
        (vect_mark_stmts_to_be_vectorize): Likewise.
        * tree-vect-patterns.c (widened_name_p): Remove obsolete asserts.

From-SVN: r123910

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c [new file with mode: 0644]
gcc/tree-vect-analyze.c
gcc/tree-vect-patterns.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.h

index 5cf9903435f9396015de77608056b4d0fd5f9ead..d065322a2b71ece891a5510a12d1a0254ec74c84 100644 (file)
@@ -1,3 +1,24 @@
+2007-04-17  Dorit Nuzman  <dorit@il.ibm.com>
+
+       * tree-vectorizer.h (stmt_vec_info_type): Add enum value
+       induc_vec_info_type.
+       (vectorizable_induction): New function declaration.
+       * tree-vect-transform.c (get_initial_def_for_induction): No need to
+       check if already vectorized.  Find first place in BB where new stmts
+       can be inserted.  Takes only one argument.
+       (vectorizable_induction): New function.
+       (vect_transform_stmt): Add case for induc_vec_info_type to call
+       vectorizable_induction.
+       (vect_transform_loop): Consider phis for vectorization.
+       * tree-vect-analyze.c (vect_determine_vectorization_factor): Simplify
+       condition.
+       (analyze_operations): Call vectorizable_induction when analyzing phis.  
+       Fix comment.
+       (vect_mark_stmts_to_be_vectorized): Remove redundant checks.
+       (vect_mark_relevant): Include phis in relevance analysis.
+       (vect_mark_stmts_to_be_vectorize): Likewise.
+       * tree-vect-patterns.c (widened_name_p): Remove obsolete asserts.
+
 2007-04-16  Lawrence Crowl  <crowl@google.com>
 
        * doc/invoke.texi (Debugging Options): Add documentation for the
index 652e4cc0c948f287c9a3f698caecf82a36a2f019..c3d96c31fdf3ccd18546cd9b73d6ceb02efceba4 100644 (file)
@@ -1,3 +1,7 @@
+2007-04-17  Dorit Nuzman  <dorit@il.ibm.com>
+
+       * gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c: New test.
+
 2007-04-16  Lawrence Crowl  <crowl@google.com>
 
        * g++.dg/other/fesd-any.C: Test -femit-struct-debug-detailed=any.
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c b/gcc/testsuite/gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c
new file mode 100644 (file)
index 0000000..cdfaa6f
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 26
+unsigned int main1 ()
+{  
+  unsigned short i;
+  unsigned int intsum = 0;
+
+  /* vectorization of reduction with induction, and widenning sum: 
+     sum shorts into int. 
+     Need -fno-tree-scev-cprop or else the loop is eliminated.  */
+  for (i = 0; i < N; i++)
+    {
+      intsum += i;
+    } 
+
+  return intsum;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_hi_to_si } } } */
+/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" { target vect_widen_sum_hi_to_si } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
index e7dff736325b98cebb309333aaca76c041162bf1..c707a025c011dcb36f3d0eb6b5694025f85c6e6e 100644 (file)
@@ -122,13 +122,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
 
          gcc_assert (stmt_info);
 
-         /* Two cases of "relevant" phis: those that define an 
-            induction that is used in the loop, and those that
-            define a reduction.  */
-         if ((STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
-              && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
-             || (STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
-                 && STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
+         if (STMT_VINFO_RELEVANT_P (stmt_info))
             {
              gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
               scalar_type = TREE_TYPE (PHI_RESULT (phi));
@@ -311,6 +305,8 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
 
       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
         {
+         ok = true;
+
          stmt_info = vinfo_for_stmt (phi);
          if (vect_print_dump_info (REPORT_DETAILS))
            {
@@ -331,15 +327,29 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
          if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
              && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
            {
-             /* Most likely a reduction-like computation that is used
-                in the loop.  */
+             /* A scalar-dependence cycle that we don't support.  */
              if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-               fprintf (vect_dump, "not vectorized: unsupported pattern.");
-            return false;
+               fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
+             return false;
            }
 
          if (STMT_VINFO_RELEVANT_P (stmt_info))
-           need_to_vectorize = true;
+           {
+             need_to_vectorize = true;
+             if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+               ok = vectorizable_induction (phi, NULL, NULL);
+           }
+
+         if (!ok)
+           {
+             if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+               {
+                 fprintf (vect_dump,
+                          "not vectorized: relevant phi not supported: ");
+                 print_generic_expr (vect_dump, phi, TDF_SLIM);
+               }
+             return false;
+           }
        }
 
       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
@@ -2106,11 +2116,6 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
   if (relevant > STMT_VINFO_RELEVANT (stmt_info))
     STMT_VINFO_RELEVANT (stmt_info) = relevant;
 
-  if (TREE_CODE (stmt) == PHI_NODE)
-    /* Don't put phi-nodes in the worklist. Phis that are marked relevant
-       or live will fail vectorization later on.  */
-    return;
-
   if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
     {
@@ -2228,27 +2233,23 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
   worklist = VEC_alloc (tree, heap, 64);
 
   /* 1. Init worklist.  */
-
-  bb = loop->header;
-  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
-    {
-      if (vect_print_dump_info (REPORT_DETAILS))
-        {
-          fprintf (vect_dump, "init: phi relevant? ");
-          print_generic_expr (vect_dump, phi, TDF_SLIM);
-        }
-
-      if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
-       vect_mark_relevant (&worklist, phi, relevant, live_p);
-    }
-
   for (i = 0; i < nbbs; i++)
     {
       bb = bbs[i];
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+       { 
+         if (vect_print_dump_info (REPORT_DETAILS))
+           {
+             fprintf (vect_dump, "init: phi relevant? ");
+             print_generic_expr (vect_dump, phi, TDF_SLIM);
+           }
+
+         if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
+           vect_mark_relevant (&worklist, phi, relevant, live_p);
+       }
       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
        {
          stmt = bsi_stmt (si);
-
          if (vect_print_dump_info (REPORT_DETAILS))
            {
              fprintf (vect_dump, "init: stmt relevant? ");
@@ -2279,8 +2280,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
          relevance properties of STMT.
        */
 
-      gcc_assert (TREE_CODE (stmt) != PHI_NODE);
-
       ann = stmt_ann (stmt);
       stmt_vinfo = vinfo_for_stmt (stmt);
 
@@ -2318,7 +2317,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
       /* case 2.2:  */
       if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
        {
-         gcc_assert (relevant == vect_unused_in_loop && live_p);
          relevant = vect_used_by_reduction;
          live_p = false;
        }
index 63255bd3fb14d88338c283707988338631a6fcb6..5773344abc5eab5aed674fc7167b64e7b567fb61 100644 (file)
@@ -109,10 +109,6 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
   if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy, &dummy, &dt))
     return false;
 
-  if (dt != vect_invariant_def && dt != vect_constant_def
-      && dt != vect_loop_def)
-    return false;
-
   return true;
 }
 
index 32fe626180ce40345d6254d86cfc7f111c7251e4..a00ecdc3d6bd76c080967c1cc64e089205da746d 100644 (file)
@@ -514,7 +514,6 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type)
 /* Function get_initial_def_for_induction
 
    Input:
-   STMT - a stmt that performs an induction operation in the loop.
    IV_PHI - the initial value of the induction variable
 
    Output:
@@ -524,9 +523,9 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type)
    [X, X + S, X + 2*S, X + 3*S].  */
 
 static tree
-get_initial_def_for_induction (tree stmt, tree iv_phi)
+get_initial_def_for_induction (tree iv_phi)
 {
-  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   tree scalar_type = TREE_TYPE (iv_phi);
@@ -549,27 +548,17 @@ get_initial_def_for_induction (tree stmt, tree iv_phi)
   tree expr;
   stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
   tree stmts;
+  tree stmt = NULL_TREE;
+  block_stmt_iterator si;
+  basic_block bb = bb_for_stmt (iv_phi);
 
   gcc_assert (phi_info);
+  gcc_assert (ncopies >= 1);
 
-  if (STMT_VINFO_VEC_STMT (phi_info))
-    {
-      induction_phi = STMT_VINFO_VEC_STMT (phi_info);
-      gcc_assert (TREE_CODE (induction_phi) == PHI_NODE);
-
-      if (vect_print_dump_info (REPORT_DETAILS))
-       {
-         fprintf (vect_dump, "induction already vectorized:");
-         print_generic_expr (vect_dump, iv_phi, TDF_SLIM);
-         fprintf (vect_dump, "\n");
-         print_generic_expr (vect_dump, induction_phi, TDF_SLIM);
-       }
-
-      return PHI_RESULT (induction_phi);
-    }
+  /* Find the first insertion point in the BB.  */
+  si = bsi_after_labels (bb);
+  stmt = bsi_stmt (si);
 
-  gcc_assert (ncopies >= 1);
   access_fn = analyze_scalar_evolution (loop, PHI_RESULT (iv_phi));
   gcc_assert (access_fn);
   ok = vect_is_simple_iv_evolution (loop->num, access_fn, &init_expr, &step_expr);
@@ -833,7 +822,7 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
        gcc_assert (TREE_CODE (def_stmt) == PHI_NODE);
 
        /* Get the def before the loop  */
-       return get_initial_def_for_induction (stmt, def_stmt);
+       return get_initial_def_for_induction (def_stmt);
       }
 
     default:
@@ -2233,6 +2222,59 @@ vect_min_worthwhile_factor (enum tree_code code)
 }
 
 
+/* Function vectorizable_induction
+
+   Check if PHI performs an induction computation that can be vectorized.
+   If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized
+   phi to replace it, put it in VEC_STMT, and add it to the same basic block.
+   Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+bool
+vectorizable_induction (tree phi, block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
+                        tree *vec_stmt)
+{
+  stmt_vec_info stmt_info = vinfo_for_stmt (phi);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+  int nunits = TYPE_VECTOR_SUBPARTS (vectype);
+  int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+  tree vec_def;
+
+  gcc_assert (ncopies >= 1);
+
+  if (!STMT_VINFO_RELEVANT_P (stmt_info))
+    return false;
+
+  gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def);
+
+  if (STMT_VINFO_LIVE_P (stmt_info))
+    {
+      /* FORNOW: not yet supported.  */
+      if (vect_print_dump_info (REPORT_DETAILS))
+        fprintf (vect_dump, "value used after loop.");
+      return false;
+    }
+
+  if (TREE_CODE (phi) != PHI_NODE)
+    return false;
+
+  if (!vec_stmt) /* transformation not required.  */
+    {
+      STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type;
+      return true;
+    }
+
+  /** Transform.  **/
+
+  if (vect_print_dump_info (REPORT_DETAILS))
+    fprintf (vect_dump, "transform induction phi.");
+
+  vec_def = get_initial_def_for_induction (phi);
+  *vec_stmt = SSA_NAME_DEF_STMT (vec_def);
+  return true;
+}
+
+
 /* Function vectorizable_operation.
 
    Check if STMT performs a binary or unary operation that can be vectorized. 
@@ -4285,6 +4327,11 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store)
       gcc_assert (done);
       break;
 
+    case induc_vec_info_type:
+      done = vectorizable_induction (stmt, bsi, &vec_stmt);
+      gcc_assert (done);
+      break;
+
     case op_vec_info_type:
       done = vectorizable_operation (stmt, bsi, &vec_stmt);
       gcc_assert (done);
@@ -5192,11 +5239,39 @@ vect_transform_loop (loop_vec_info loop_vinfo)
   for (i = 0; i < nbbs; i++)
     {
       basic_block bb = bbs[i];
+      stmt_vec_info stmt_info;
+      tree phi;
+
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+        {
+         if (vect_print_dump_info (REPORT_DETAILS))
+           {
+             fprintf (vect_dump, "------>vectorizing phi: ");
+             print_generic_expr (vect_dump, phi, TDF_SLIM);
+           }
+         stmt_info = vinfo_for_stmt (phi);
+         if (!stmt_info)
+           continue;
+         if (!STMT_VINFO_RELEVANT_P (stmt_info)
+             && !STMT_VINFO_LIVE_P (stmt_info))
+           continue;
+
+         if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
+               != (unsigned HOST_WIDE_INT) vectorization_factor)
+             && vect_print_dump_info (REPORT_DETAILS))
+           fprintf (vect_dump, "multiple-types.");
+
+         if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+           {
+             if (vect_print_dump_info (REPORT_DETAILS))
+               fprintf (vect_dump, "transform phi.");
+             vect_transform_stmt (phi, NULL, NULL);
+           }
+       }
 
       for (si = bsi_start (bb); !bsi_end_p (si);)
        {
          tree stmt = bsi_stmt (si);
-         stmt_vec_info stmt_info;
          bool is_store;
 
          if (vect_print_dump_info (REPORT_DETAILS))
index 4f0e7b95e8223af90a09e9289e7034eee66c92bb..3d418a92304b806501523ece968399ad30462ee1 100644 (file)
@@ -167,6 +167,7 @@ enum stmt_vec_info_type {
   assignment_vec_info_type,
   condition_vec_info_type,
   reduc_vec_info_type,
+  induc_vec_info_type,
   type_promotion_vec_info_type,
   type_demotion_vec_info_type,
   type_conversion_vec_info_type
@@ -428,6 +429,7 @@ extern bool vectorizable_call (tree, block_stmt_iterator *, tree *);
 extern bool vectorizable_condition (tree, block_stmt_iterator *, tree *);
 extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
 extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
+extern bool vectorizable_induction (tree, block_stmt_iterator *, tree *);
 /* Driver for transformation stage.  */
 extern void vect_transform_loop (loop_vec_info);