Hi,

This patch STMT_VINFO_FIRST_COPY_P field to statement vec info.
This is used to find the first vector store generated for a
scalar one.  For other statements I use original scalar statement
to find the first and following vector statement.  For stores
original scalar statement is removed and this new fiels is used
to mark a chain start.  Also original data reference and vector
type are preserved in the first vector statement for masking
purposes.

Thanks,
Ilya
--
gcc/

2016-05-19  Ilya Enkovich  <ilya.enkov...@intel.com>

        * tree-vect-stmts.c (vectorizable_mask_load_store): Mark
        the first copy of generated vector stores.
        (vectorizable_store): Mark the first copy of generated
        vector stores and provide it with vectype and the original
        data reference.
        * tree-vectorizer.h (struct _stmt_vec_info): Add first_copy_p
        field.
        (STMT_VINFO_FIRST_COPY_P): New.


diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 91ebe5a..84f4dc81 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2131,7 +2131,10 @@ vectorizable_mask_load_store (gimple *stmt, 
gimple_stmt_iterator *gsi,
                                          ptr, vec_mask, vec_rhs);
          vect_finish_stmt_generation (stmt, new_stmt, gsi);
          if (i == 0)
-           STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+           {
+             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+             STMT_VINFO_FIRST_COPY_P (vinfo_for_stmt (new_stmt)) = true;
+           }
          else
            STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
          prev_stmt_info = vinfo_for_stmt (new_stmt);
@@ -6203,7 +6206,16 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator 
*gsi, gimple **vec_stmt,
       if (!slp)
        {
          if (j == 0)
-           STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+           {
+             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+             STMT_VINFO_FIRST_COPY_P (vinfo_for_stmt (new_stmt)) = true;
+             /* Original statement is replaced with the first vector one.
+                Keep data reference and original vectype in the first
+                vector copy for masking purposes.  */
+             STMT_VINFO_DATA_REF (vinfo_for_stmt (new_stmt))
+               = STMT_VINFO_DATA_REF (stmt_info);
+             STMT_VINFO_VECTYPE (vinfo_for_stmt (new_stmt)) = vectype;
+           }
          else
            STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
          prev_stmt_info = vinfo_for_stmt (new_stmt);
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 86c5371..3702c5d 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -633,6 +633,10 @@ typedef struct _stmt_vec_info {
   /* For both loads and stores.  */
   bool simd_lane_access_p;
 
+  /* True for the first vector statement copy when scalar
+     statement is vectorized into several vector ones.  */
+  bool first_copy_p;
+
   /* For reduction loops, this is the type of reduction.  */
   enum vect_reduction_type v_reduc_type;
 
@@ -666,6 +670,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
 #define STMT_VINFO_GATHER_SCATTER_P(S)    (S)->gather_scatter_p
 #define STMT_VINFO_STRIDED_P(S)                   (S)->strided_p
 #define STMT_VINFO_SIMD_LANE_ACCESS_P(S)   (S)->simd_lane_access_p
+#define STMT_VINFO_FIRST_COPY_P(S)         (S)->first_copy_p
 #define STMT_VINFO_VEC_REDUCTION_TYPE(S)   (S)->v_reduc_type
 
 #define STMT_VINFO_DR_BASE_ADDRESS(S)      (S)->dr_base_address

Reply via email to