2015-11-03 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Nov 2015 15:59:17 +0000 (15:59 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Nov 2015 15:59:17 +0000 (15:59 +0000)
* tree-vect-data-refs.c (vect_analyze_data_refs): Do not collect
data references here.
* tree-vect-loop.c: Include cgraph.h.
(vect_analyze_loop_2): Collect data references here.
* tree-vect-slp.c (find_bb_location): Inline ...
(vect_slp_bb): ... here.  Renamed from vect_slp_analyze_bb.
Factor in vect_slp_transform_bb.
(vect_slp_transform_bb): Removed.
(vect_slp_analyze_bb_1): Collect data references here.
* tree-vectorizer.c (pass_slp_vectorize::execute): Call
vect_slp_bb.
* tree-vectorizer.h (vect_slp_bb): Declare.
(vect_slp_analyze_bb): Remove.
(vect_slp_transform_bb): Remove.
(find_bb_location): Remove.
(vect_analyze_data_refs): Remove stmt count reference parameter.

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

gcc/ChangeLog
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h

index 97a1101..d00b074 100644 (file)
@@ -1,3 +1,22 @@
+2015-11-03  Richard Biener  <rguenther@suse.de>
+
+       * tree-vect-data-refs.c (vect_analyze_data_refs): Do not collect
+       data references here.
+       * tree-vect-loop.c: Include cgraph.h.
+       (vect_analyze_loop_2): Collect data references here.
+       * tree-vect-slp.c (find_bb_location): Inline ...
+       (vect_slp_bb): ... here.  Renamed from vect_slp_analyze_bb.
+       Factor in vect_slp_transform_bb.
+       (vect_slp_transform_bb): Removed.
+       (vect_slp_analyze_bb_1): Collect data references here.
+       * tree-vectorizer.c (pass_slp_vectorize::execute): Call
+       vect_slp_bb.
+       * tree-vectorizer.h (vect_slp_bb): Declare.
+       (vect_slp_analyze_bb): Remove.
+       (vect_slp_transform_bb): Remove.
+       (find_bb_location): Remove.
+       (vect_analyze_data_refs): Remove stmt count reference parameter.
+
 2015-11-03  Evgeny Stupachenko  <evstupac@gmail.com>
 
        * multiple_target.c (create_dispatcher_calls): Add target check
index 7d3abcf..3de71fb 100644 (file)
@@ -3245,120 +3245,24 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo, tree *basep,
 */
 
 bool
-vect_analyze_data_refs (vec_info *vinfo, int *min_vf, unsigned *n_stmts)
+vect_analyze_data_refs (vec_info *vinfo, int *min_vf)
 {
   struct loop *loop = NULL;
-  basic_block bb = NULL;
   unsigned int i;
-  vec<data_reference_p> datarefs;
   struct data_reference *dr;
   tree scalar_type;
 
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
-                     "=== vect_analyze_data_refs ===\n");
+                    "=== vect_analyze_data_refs ===\n");
 
   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
-    {
-      basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
-
-      loop = LOOP_VINFO_LOOP (loop_vinfo);
-      datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
-      if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo)))
-       {
-         if (dump_enabled_p ())
-           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                            "not vectorized: loop contains function calls"
-                            " or data references that cannot be analyzed\n");
-         return false;
-       }
-
-      for (i = 0; i < loop->num_nodes; i++)
-       {
-         gimple_stmt_iterator gsi;
-
-         for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
-           {
-             gimple *stmt = gsi_stmt (gsi);
-             if (is_gimple_debug (stmt))
-               continue;
-             ++*n_stmts;
-             if (!find_data_references_in_stmt (loop, stmt, &datarefs))
-               {
-                 if (is_gimple_call (stmt) && loop->safelen)
-                   {
-                     tree fndecl = gimple_call_fndecl (stmt), op;
-                     if (fndecl != NULL_TREE)
-                       {
-                         struct cgraph_node *node = cgraph_node::get (fndecl);
-                         if (node != NULL && node->simd_clones != NULL)
-                           {
-                             unsigned int j, n = gimple_call_num_args (stmt);
-                             for (j = 0; j < n; j++)
-                               {
-                                 op = gimple_call_arg (stmt, j);
-                                 if (DECL_P (op)
-                                     || (REFERENCE_CLASS_P (op)
-                                         && get_base_address (op)))
-                                   break;
-                               }
-                             op = gimple_call_lhs (stmt);
-                             /* Ignore #pragma omp declare simd functions
-                                if they don't have data references in the
-                                call stmt itself.  */
-                             if (j == n
-                                 && !(op
-                                      && (DECL_P (op)
-                                          || (REFERENCE_CLASS_P (op)
-                                              && get_base_address (op)))))
-                               continue;
-                           }
-                       }
-                   }
-                 LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
-                 if (dump_enabled_p ())
-                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                                    "not vectorized: loop contains function "
-                                    "calls or data references that cannot "
-                                    "be analyzed\n");
-                 return false;
-               }
-           }
-       }
-
-      LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
-    }
-  else
-    {
-      bb_vec_info bb_vinfo = as_a <bb_vec_info> (vinfo);
-      gimple_stmt_iterator gsi;
-
-      bb = BB_VINFO_BB (bb_vinfo);
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-       {
-         gimple *stmt = gsi_stmt (gsi);
-         if (is_gimple_debug (stmt))
-           continue;
-         ++*n_stmts;
-         if (!find_data_references_in_stmt (NULL, stmt,
-                                            &BB_VINFO_DATAREFS (bb_vinfo)))
-           {
-             /* Mark the rest of the basic-block as unvectorizable.  */
-             for (; !gsi_end_p (gsi); gsi_next (&gsi))
-               {
-                 stmt = gsi_stmt (gsi);
-                 STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false;
-               }
-             break;
-           }
-       }
-
-      datarefs = BB_VINFO_DATAREFS (bb_vinfo);
-    }
+    loop = LOOP_VINFO_LOOP (loop_vinfo);
 
   /* Go through the data-refs, check that the analysis succeeded.  Update
      pointer from stmt_vec_info struct to DR and vectype.  */
 
+  vec<data_reference_p> datarefs = vinfo->datarefs;
   FOR_EACH_VEC_ELT (datarefs, i, dr)
     {
       gimple *stmt;
index bdf93ba..43ada18 100644 (file)
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
 #include "gimple-fold.h"
+#include "cgraph.h"
 
 /* Loop Vectorization Pass.
 
@@ -1584,13 +1585,74 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
   unsigned int n_stmts = 0;
 
   /* Find all data references in the loop (which correspond to vdefs/vuses)
-     and analyze their evolution in the loop.  Also adjust the minimal
-     vectorization factor according to the loads and stores.
+     and analyze their evolution in the loop.  */
 
-     FORNOW: Handle only simple, array references, which
-     alignment can be forced, and aligned pointer-references.  */
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+
+  loop_p loop = LOOP_VINFO_LOOP (loop_vinfo);
+  if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo)))
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "not vectorized: loop contains function calls"
+                        " or data references that cannot be analyzed\n");
+      return false;
+    }
+
+  for (unsigned i = 0; i < loop->num_nodes; i++)
+    for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]);
+        !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+       gimple *stmt = gsi_stmt (gsi);
+       if (is_gimple_debug (stmt))
+         continue;
+       ++n_stmts;
+       if (!find_data_references_in_stmt (loop, stmt,
+                                          &LOOP_VINFO_DATAREFS (loop_vinfo)))
+         {
+           if (is_gimple_call (stmt) && loop->safelen)
+             {
+               tree fndecl = gimple_call_fndecl (stmt), op;
+               if (fndecl != NULL_TREE)
+                 {
+                   cgraph_node *node = cgraph_node::get (fndecl);
+                   if (node != NULL && node->simd_clones != NULL)
+                     {
+                       unsigned int j, n = gimple_call_num_args (stmt);
+                       for (j = 0; j < n; j++)
+                         {
+                           op = gimple_call_arg (stmt, j);
+                           if (DECL_P (op)
+                               || (REFERENCE_CLASS_P (op)
+                                   && get_base_address (op)))
+                             break;
+                         }
+                       op = gimple_call_lhs (stmt);
+                       /* Ignore #pragma omp declare simd functions
+                          if they don't have data references in the
+                          call stmt itself.  */
+                       if (j == n
+                           && !(op
+                                && (DECL_P (op)
+                                    || (REFERENCE_CLASS_P (op)
+                                        && get_base_address (op)))))
+                         continue;
+                     }
+                 }
+             }
+           if (dump_enabled_p ())
+             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                              "not vectorized: loop contains function "
+                              "calls or data references that cannot "
+                              "be analyzed\n");
+           return false;
+         }
+      }
+
+  /* Analyze the data references and also adjust the minimal
+     vectorization factor according to the loads and stores.  */
 
-  ok = vect_analyze_data_refs (loop_vinfo, &min_vf, &n_stmts);
+  ok = vect_analyze_data_refs (loop_vinfo, &min_vf);
   if (!ok)
     {
       if (dump_enabled_p ())
index 53f7f46..35808eb 100644 (file)
@@ -40,28 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vectorizer.h"
 #include "langhooks.h"
 #include "gimple-walk.h"
-
-/* Extract the location of the basic block in the source code.
-   Return the basic block location if succeed and NULL if not.  */
-
-source_location
-find_bb_location (basic_block bb)
-{
-  gimple *stmt = NULL;
-  gimple_stmt_iterator si;
-
-  if (!bb)
-    return UNKNOWN_LOCATION;
-
-  for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-    {
-      stmt = gsi_stmt (si);
-      if (gimple_location (stmt) != UNKNOWN_LOCATION)
-        return gimple_location (stmt);
-    }
-
-  return UNKNOWN_LOCATION;
-}
+#include "dbgcnt.h"
 
 
 /* Recursively free the memory allocated for the SLP tree rooted at NODE.  */
@@ -2361,7 +2340,31 @@ vect_slp_analyze_bb_1 (basic_block bb)
   if (!bb_vinfo)
     return NULL;
 
-  if (!vect_analyze_data_refs (bb_vinfo, &min_vf, &n_stmts))
+  /* Gather all data references in the basic-block.  */
+
+  for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+       !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      gimple *stmt = gsi_stmt (gsi);
+      if (is_gimple_debug (stmt))
+       continue;
+      ++n_stmts;
+      if (!find_data_references_in_stmt (NULL, stmt,
+                                        &BB_VINFO_DATAREFS (bb_vinfo)))
+       {
+         /* Mark the rest of the basic-block as unvectorizable.  */
+         for (; !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             stmt = gsi_stmt (gsi);
+             STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false;
+           }
+         break;
+       }
+    }
+
+  /* Analyze the data references.  */
+
+  if (!vect_analyze_data_refs (bb_vinfo, &min_vf))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2499,8 +2502,11 @@ vect_slp_analyze_bb_1 (basic_block bb)
 }
 
 
-bb_vec_info
-vect_slp_analyze_bb (basic_block bb)
+/* Main entry for the BB vectorizer.  Analyze and transform BB, returns
+   true if anything in the basic-block was vectorized.  */
+
+bool
+vect_slp_bb (basic_block bb)
 {
   bb_vec_info bb_vinfo;
   int insns = 0;
@@ -2517,6 +2523,8 @@ vect_slp_analyze_bb (basic_block bb)
           && !gimple_nop_p (stmt)
           && gimple_code (stmt) != GIMPLE_LABEL)
         insns++;
+      if (gimple_location (stmt) != UNKNOWN_LOCATION)
+       vect_location = gimple_location (stmt);
     }
 
   if (insns > PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB))
@@ -2526,7 +2534,7 @@ vect_slp_analyze_bb (basic_block bb)
                         "not vectorized: too many instructions in "
                         "basic block.\n");
 
-      return NULL;
+      return false;
     }
 
   /* Autodetect first vector size we try.  */
@@ -2537,14 +2545,33 @@ vect_slp_analyze_bb (basic_block bb)
     {
       bb_vinfo = vect_slp_analyze_bb_1 (bb);
       if (bb_vinfo)
-        return bb_vinfo;
+       {
+         if (!dbg_cnt (vect_slp))
+           {
+             destroy_bb_vec_info (bb_vinfo);
+             return false;
+           }
+
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB\n");
+
+         vect_schedule_slp (bb_vinfo);
+
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_NOTE, vect_location,
+                            "BASIC BLOCK VECTORIZED\n");
+
+         destroy_bb_vec_info (bb_vinfo);
+
+         return true;
+       }
 
       destroy_bb_vec_info (bb_vinfo);
 
       vector_sizes &= ~current_vector_size;
       if (vector_sizes == 0
           || current_vector_size == 0)
-        return NULL;
+        return false;
 
       /* Try the next biggest vector size.  */
       current_vector_size = 1 << floor_log2 (vector_sizes);
@@ -3533,48 +3560,3 @@ vect_schedule_slp (vec_info *vinfo)
 
   return is_store;
 }
-
-
-/* Vectorize the basic block.  */
-
-void
-vect_slp_transform_bb (basic_block bb)
-{
-  bb_vec_info bb_vinfo = vec_info_for_bb (bb);
-  gimple_stmt_iterator si;
-
-  gcc_assert (bb_vinfo);
-
-  if (dump_enabled_p ())
-    dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB\n");
-
-  for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-    {
-      gimple *stmt = gsi_stmt (si);
-      stmt_vec_info stmt_info;
-
-      if (dump_enabled_p ())
-        {
-          dump_printf_loc (MSG_NOTE, vect_location,
-                           "------>SLPing statement: ");
-          dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
-          dump_printf (MSG_NOTE, "\n");
-        }
-
-      stmt_info = vinfo_for_stmt (stmt);
-      gcc_assert (stmt_info);
-
-      /* Schedule all the SLP instances when the first SLP stmt is reached.  */
-      if (STMT_SLP_TYPE (stmt_info))
-        {
-          vect_schedule_slp (bb_vinfo);
-          break;
-        }
-    }
-
-  if (dump_enabled_p ())
-    dump_printf_loc (MSG_NOTE, vect_location,
-                    "BASIC BLOCK VECTORIZED\n");
-
-  destroy_bb_vec_info (bb_vinfo);
-}
index b80a8dd..7b3d9a3 100644 (file)
@@ -696,18 +696,9 @@ pass_slp_vectorize::execute (function *fun)
 
   FOR_EACH_BB_FN (bb, fun)
     {
-      vect_location = find_bb_location (bb);
-
-      if (vect_slp_analyze_bb (bb))
-        {
-          if (!dbg_cnt (vect_slp))
-            break;
-
-          vect_slp_transform_bb (bb);
-          if (dump_enabled_p ())
-            dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
-                            "basic block vectorized\n");
-        }
+      if (vect_slp_bb (bb))
+       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+                        "basic block vectorized\n");
     }
 
   free_stmt_vec_info_vec ();
index bf01ded..f77a4eb 100644 (file)
@@ -1010,7 +1010,7 @@ extern bool vect_analyze_data_ref_accesses (vec_info *);
 extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
 extern tree vect_check_gather_scatter (gimple *, loop_vec_info, tree *, tree *,
                                       int *);
-extern bool vect_analyze_data_refs (vec_info *, int *, unsigned *);
+extern bool vect_analyze_data_refs (vec_info *, int *);
 extern tree vect_create_data_ref_ptr (gimple *, tree, struct loop *, tree,
                                      tree *, gimple_stmt_iterator *,
                                      gimple **, bool, bool *,
@@ -1072,10 +1072,7 @@ extern bool vect_make_slp_decision (loop_vec_info);
 extern void vect_detect_hybrid_slp (loop_vec_info);
 extern void vect_get_slp_defs (vec<tree> , slp_tree,
                               vec<vec<tree> > *, int);
-
-extern source_location find_bb_location (basic_block);
-extern bb_vec_info vect_slp_analyze_bb (basic_block);
-extern void vect_slp_transform_bb (basic_block);
+extern bool vect_slp_bb (basic_block);
 
 /* In tree-vect-patterns.c.  */
 /* Pattern recognition functions.