re PR tree-optimization/56118 (Piecewise vector / complex initialization from constan...
authorRichard Biener <rguenther@suse.de>
Mon, 9 Nov 2015 12:59:17 +0000 (12:59 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 9 Nov 2015 12:59:17 +0000 (12:59 +0000)
2015-11-09  Richard Biener  <rguenther@suse.de>

PR tree-optimization/56118
* tree-vectorizer.h (vect_find_last_scalar_stmt_in_slp): Declare.
* tree-vect-slp.c (vect_find_last_scalar_stmt_in_slp): Export.
* tree-vect-data-refs.c (vect_slp_analyze_node_dependences): New
function.
(vect_slp_analyze_data_ref_dependences): Instead of computing
all dependences of the region DRs just analyze the code motions
SLP vectorization will perform.  Remove SLP instances that
cannot have their store/load motions applied.
(vect_analyze_data_refs): Allow DRs without a vectype
in BB vectorization.

* gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c: Adjust.

From-SVN: r230020

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-slp.c
gcc/tree-vectorizer.h

index eb6acd5..56c609f 100644 (file)
@@ -1,3 +1,17 @@
+2015-11-09  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/56118
+       * tree-vectorizer.h (vect_find_last_scalar_stmt_in_slp): Declare.
+       * tree-vect-slp.c (vect_find_last_scalar_stmt_in_slp): Export.
+       * tree-vect-data-refs.c (vect_slp_analyze_node_dependences): New
+       function.
+       (vect_slp_analyze_data_ref_dependences): Instead of computing
+       all dependences of the region DRs just analyze the code motions
+       SLP vectorization will perform.  Remove SLP instances that
+       cannot have their store/load motions applied.
+       (vect_analyze_data_refs): Allow DRs without a vectype
+       in BB vectorization.
+
 2015-11-09  Julian Brown  <julian@codesourcery.com>
 
        * final.c (output_asm_insn): Pass VOIDmode to output_address.
index 4cd50cd..3809a72 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-09  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/56118
+       * gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c: Adjust.
+
 2015-11-09  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * gcc.target/arm/thumb2-slow-flash-data.c: Add missing typespec for
index e7328fc..8fe67f4 100644 (file)
@@ -13,4 +13,4 @@ A sum(A a,A b)
   return a;
 }
 
-/* { dg-final { scan-tree-dump-times "not vectorized: more than one data ref in stmt" 0 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
index 11bce79..6e32391 100644 (file)
@@ -559,6 +559,49 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
 }
 
 
+/* Analyze dependences involved in the transform of SLP NODE.  */
+
+static bool
+vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node)
+{
+  /* This walks over all stmts involved in the SLP load/store done
+     in NODE verifying we can sink them up to the last stmt in the
+     group.  */
+  gimple *last_access = vect_find_last_scalar_stmt_in_slp (node);
+  for (unsigned k = 0; k < SLP_INSTANCE_GROUP_SIZE (instance); ++k)
+    {
+      gimple *access = SLP_TREE_SCALAR_STMTS (node)[k];
+      if (access == last_access)
+       continue;
+      stmt_vec_info access_stmt_info = vinfo_for_stmt (access);
+      gimple_stmt_iterator gsi = gsi_for_stmt (access);
+      gsi_next (&gsi);
+      for (; gsi_stmt (gsi) != last_access; gsi_next (&gsi))
+       {
+         gimple *stmt = gsi_stmt (gsi);
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         if (!STMT_VINFO_DATA_REF (stmt_info)
+             || (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info))
+                 && DR_IS_READ (STMT_VINFO_DATA_REF (access_stmt_info))))
+           continue;
+
+         ddr_p ddr = initialize_data_dependence_relation
+             (STMT_VINFO_DATA_REF (access_stmt_info),
+              STMT_VINFO_DATA_REF (stmt_info), vNULL);
+         if (vect_slp_analyze_data_ref_dependence (ddr))
+           {
+             /* ???  If the dependence analysis failed we can resort to the
+                alias oracle which can handle more kinds of stmts.  */
+             free_dependence_relation (ddr);
+             return false;
+           }
+         free_dependence_relation (ddr);
+       }
+    }
+  return true;
+}
+
+
 /* Function vect_analyze_data_ref_dependences.
 
    Examine all the data references in the basic-block, and make sure there
@@ -568,21 +611,45 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
 bool
 vect_slp_analyze_data_ref_dependences (bb_vec_info bb_vinfo)
 {
-  struct data_dependence_relation *ddr;
-  unsigned int i;
-
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
                      "=== vect_slp_analyze_data_ref_dependences ===\n");
 
-  if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo),
-                               &BB_VINFO_DDRS (bb_vinfo),
-                               vNULL, true))
-    return false;
+  slp_instance instance;
+  slp_tree load;
+  unsigned int i, j;
+  for (i = 0; BB_VINFO_SLP_INSTANCES (bb_vinfo).iterate (i, &instance); )
+    {
+      bool remove = false;
+      /* Verify we can sink loads to the vectorized stmt insert location.  */
+      FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), j, load)
+       if (! vect_slp_analyze_node_dependences (instance, load))
+         {
+           remove = true;
+           break;
+         }
+      /* Verify we can sink stores to the vectorized stmt insert location.  */
+      slp_tree store = SLP_INSTANCE_TREE (instance);
+      if (!remove
+         && STMT_VINFO_DATA_REF
+               (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (store)[0]))
+         && ! vect_slp_analyze_node_dependences (instance, store))
+       remove = true;
+      if (remove)
+       {
+         dump_printf_loc (MSG_NOTE, vect_location,
+                          "removing SLP instance operations starting from: ");
+         dump_gimple_stmt (MSG_NOTE, TDF_SLIM,
+                           SLP_TREE_SCALAR_STMTS
+                             (SLP_INSTANCE_TREE (instance))[0], 0);
+         vect_free_slp_instance (instance);
+         BB_VINFO_SLP_INSTANCES (bb_vinfo).ordered_remove (i);
+       }
+      i++;
+    }
 
-  FOR_EACH_VEC_ELT (BB_VINFO_DDRS (bb_vinfo), i, ddr)
-    if (vect_slp_analyze_data_ref_dependence (ddr))
-      return false;
+  if (!BB_VINFO_SLP_INSTANCES (bb_vinfo).length ())
+    return false;
 
   return true;
 }
@@ -3674,7 +3741,12 @@ again:
             }
 
           if (is_a <bb_vec_info> (vinfo))
-           break;
+           {
+             /* No vector type is fine, the ref can still participate
+                in dependence analysis, we just can't vectorize it.  */
+             STMT_VINFO_VECTORIZABLE (stmt_info) = false;
+             continue;
+           }
 
          if (gatherscatter != SG_NONE || simd_lane_access)
            {
index cfdfc29..954b85e 100644 (file)
@@ -1426,7 +1426,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn)
 
 /* Find the last store in SLP INSTANCE.  */
 
-static gimple *
+gimple *
 vect_find_last_scalar_stmt_in_slp (slp_tree node)
 {
   gimple *last = NULL, *stmt;
index 9cde091..fed80c8 100644 (file)
@@ -1075,6 +1075,7 @@ extern void vect_detect_hybrid_slp (loop_vec_info);
 extern void vect_get_slp_defs (vec<tree> , slp_tree,
                               vec<vec<tree> > *, int);
 extern bool vect_slp_bb (basic_block);
+extern gimple *vect_find_last_scalar_stmt_in_slp (slp_tree);
 
 /* In tree-vect-patterns.c.  */
 /* Pattern recognition functions.