PR tree-optimization/37482
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Sep 2008 07:55:39 +0000 (07:55 +0000)
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Sep 2008 07:55:39 +0000 (07:55 +0000)
* tree-vectorizer.h (struct _slp_instance): Add new field.
(SLP_INSTANCE_FIRST_LOAD_STMT): New.
(get_earlier_stmt): New function.
* tree-vect-analyze.c (vect_find_first_load_in_slp_instance): New
function.
(vect_analyze_slp_instance): Set SLP_INSTANCE_FIRST_LOAD_STMT.
* tree-vect-transform.c (vect_finish_stmt_generation): Remove the
asserts that GSI points to the scalar statement being vectorized.
Set new statement location according to GSI.
(vect_schedule_slp_instance): Use GSI of
SLP_INSTANCE_FIRST_LOAD_STMT when vectorizing loads.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr37482.c [new file with mode: 0644]
gcc/tree-vect-analyze.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.h

index 9f67a4c..0987ef0 100644 (file)
@@ -1,3 +1,18 @@
+2008-09-22  Ira Rosen  <irar@il.ibm.com>
+
+       PR tree-optimization/37482
+       * tree-vectorizer.h (struct _slp_instance): Add new field.
+       (SLP_INSTANCE_FIRST_LOAD_STMT): New.
+       (get_earlier_stmt): New function.
+       * tree-vect-analyze.c (vect_find_first_load_in_slp_instance): New
+       function.
+       (vect_analyze_slp_instance): Set SLP_INSTANCE_FIRST_LOAD_STMT.
+       * tree-vect-transform.c (vect_finish_stmt_generation): Remove the
+       asserts that GSI points to the scalar statement being vectorized.
+       Set new statement location according to GSI.
+       (vect_schedule_slp_instance): Use GSI of
+       SLP_INSTANCE_FIRST_LOAD_STMT when vectorizing loads.
+
 2008-09-21  Jan Hubicka  <jh@suse.cz>
 
        * ipa-cp.c (ipcp_estimate_growth): Check recursive calls.
index ca0e708..2af0a0e 100644 (file)
@@ -1,3 +1,8 @@
+2008-09-22  Ira Rosen  <irar@il.ibm.com>
+
+       PR tree-optimization/37482
+       * gcc.dg/vect/pr37482.c: New test.
+
 2008-09-22  Hans-Peter Nilsson  <hp@axis.com>
 
        PR middle-end/37170
diff --git a/gcc/testsuite/gcc.dg/vect/pr37482.c b/gcc/testsuite/gcc.dg/vect/pr37482.c
new file mode 100644 (file)
index 0000000..0b3bed3
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+void SexiALI_Convert(void *vdest, void *vsrc, unsigned int frames)
+{
+ unsigned int x;
+ short *src = vsrc;
+ unsigned char *dest = vdest;
+ for(x=0;x<256;x++)
+ {
+  int tmp;
+  tmp = *src;
+  src++;
+  tmp += *src;
+  src++;
+  *dest++ = tmp;
+  *dest++ = tmp;
+ }
+}
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
index 405ac35..c97b3fa 100644 (file)
@@ -3228,6 +3228,32 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
   return false; 
 }
 
+
+/* Find the first load in the loop that belongs to INSTANCE. 
+   When loads are in several SLP nodes, there can be a case in which the first
+   load does not appear in the first SLP node to be transformed, causing 
+   incorrect order of statements. Since we generate all the loads together,
+   they must be inserted before the first load of the SLP instance and not
+   before the first load of the first node of the instance.  */
+static gimple 
+vect_find_first_load_in_slp_instance (slp_instance instance) 
+{
+  int i, j;
+  slp_tree load_node;
+  gimple first_load = NULL, load;
+
+  for (i = 0; 
+       VEC_iterate (slp_tree, SLP_INSTANCE_LOADS (instance), i, load_node); 
+       i++)
+    for (j = 0; 
+         VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (load_node), j, load);
+         j++)
+      first_load = get_earlier_stmt (load, first_load);
+  
+  return first_load;
+}
+
+
 /* Analyze an SLP instance starting from a group of strided stores. Call
    vect_build_slp_tree to build a tree of packed stmts if possible.  
    Return FALSE if it's impossible to SLP any stmt in the loop.  */
@@ -3312,6 +3338,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
       SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (new_instance) = outside_cost;
       SLP_INSTANCE_INSIDE_OF_LOOP_COST (new_instance) = inside_cost;
       SLP_INSTANCE_LOADS (new_instance) = loads;
+      SLP_INSTANCE_FIRST_LOAD_STMT (new_instance) = NULL;
       SLP_INSTANCE_LOAD_PERMUTATION (new_instance) = load_permutation;
       if (VEC_length (slp_tree, loads))
         {
@@ -3328,6 +3355,9 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
               vect_free_slp_instance (new_instance);
               return false;
             }
+
+          SLP_INSTANCE_FIRST_LOAD_STMT (new_instance)
+             = vect_find_first_load_in_slp_instance (new_instance);
         }
       else
         VEC_free (int, heap, SLP_INSTANCE_LOAD_PERMUTATION (new_instance));
index 4965da4..d004aad 100644 (file)
@@ -2155,7 +2155,6 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
 
-  gcc_assert (stmt == gsi_stmt (*gsi));
   gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
 
   gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
@@ -2168,10 +2167,7 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
       print_gimple_stmt (vect_dump, vec_stmt, 0, TDF_SLIM);
     }
 
-  /* Make sure gsi points to the stmt that is being vectorized.  */
-  gcc_assert (stmt == gsi_stmt (*gsi));
-
-  gimple_set_location (vec_stmt, gimple_location (stmt));
+  gimple_set_location (vec_stmt, gimple_location (gsi_stmt (*gsi)));
 }
 
 
@@ -8156,7 +8152,7 @@ vect_remove_stores (gimple first_stmt)
 
 static bool
 vect_schedule_slp_instance (slp_tree node, slp_instance instance,
-                            unsigned int vectorization_factor)
+                            unsigned int vectorization_factor) 
 {
   gimple stmt;
   bool strided_store, is_store;
@@ -8177,6 +8173,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
   
   stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (node), 0);
   stmt_info = vinfo_for_stmt (stmt);
+
   /* VECTYPE is the type of the destination.  */
   vectype = get_vectype_for_scalar_type (TREE_TYPE (gimple_assign_lhs (stmt)));
   nunits = (unsigned int) TYPE_VECTOR_SUBPARTS (vectype);
@@ -8218,7 +8215,14 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
       print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
     }  
 
-  si = gsi_for_stmt (stmt);
+  /* Loads should be inserted before the first load.  */
+  if (SLP_INSTANCE_FIRST_LOAD_STMT (instance)
+      && STMT_VINFO_STRIDED_ACCESS (stmt_info)
+      && !REFERENCE_CLASS_P (gimple_get_lhs (stmt)))
+    si = gsi_for_stmt (SLP_INSTANCE_FIRST_LOAD_STMT (instance));
+  else
+    si = gsi_for_stmt (stmt);
+
   is_store = vect_transform_stmt (stmt, &si, &strided_store, node, instance);
   if (is_store)
     {
@@ -8252,8 +8256,7 @@ vect_schedule_slp (loop_vec_info loop_vinfo)
     {
       /* Schedule the tree of INSTANCE.  */
       is_store = vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance),
-                                          instance,
-                                          LOOP_VINFO_VECT_FACTOR (loop_vinfo));
+                            instance, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
                          
       if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS)
          || vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
index 678dc59..84bd8cc 100644 (file)
@@ -133,6 +133,10 @@ typedef struct _slp_instance {
 
   /* The group of nodes that contain loads of this SLP instance.  */
   VEC (slp_tree, heap) *loads;
+
+  /* The first scalar load of the instance. The created vector loads will be
+     inserted before this statement.  */
+  gimple first_load;
 } *slp_instance;
 
 DEF_VEC_P(slp_instance);
@@ -146,6 +150,7 @@ DEF_VEC_ALLOC_P(slp_instance, heap);
 #define SLP_INSTANCE_INSIDE_OF_LOOP_COST(S)      (S)->cost.inside_of_loop
 #define SLP_INSTANCE_LOAD_PERMUTATION(S)         (S)->load_permutation
 #define SLP_INSTANCE_LOADS(S)                    (S)->loads
+#define SLP_INSTANCE_FIRST_LOAD_STMT(S)          (S)->first_load
 
 #define SLP_TREE_LEFT(S)                         (S)->left
 #define SLP_TREE_RIGHT(S)                        (S)->right
@@ -578,6 +583,32 @@ set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
     VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info);
 }
 
+static inline gimple
+get_earlier_stmt (gimple stmt1, gimple stmt2)
+{
+  unsigned int uid1, uid2;
+
+  if (stmt1 == NULL)
+    return stmt2;
+
+  if (stmt2 == NULL)
+    return stmt1;
+
+  uid1 = gimple_uid (stmt1);
+  uid2 = gimple_uid (stmt2);
+
+  if (uid1 == 0 || uid2 == 0)
+    return NULL;
+
+  gcc_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec));
+  gcc_assert (uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
+
+  if (uid1 < uid2)
+    return stmt1;
+  else
+    return stmt2;
+}
+
 static inline bool
 is_pattern_stmt_p (stmt_vec_info stmt_info)
 {