Re: [4/7] Add a gather_scatter_info structure

2016-06-15 Thread Richard Biener
On Wed, Jun 15, 2016 at 10:51 AM, Richard Sandiford
 wrote:
> This patch just refactors the gather/scatter support so that all
> information is in a single structure, rather than separate variables.
> This reduces the number of arguments to a function added in patch 6.
>
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Please pack it by moving offset_dt after offset_vectype.

Ok with that change.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> gcc/
> * tree-vectorizer.h (gather_scatter_info): New structure.
> (vect_check_gather_scatter): Return a bool rather than a decl.
> Replace return-by-pointer arguments with a single
> gather_scatter_info *.
> * tree-vect-data-refs.c (vect_check_gather_scatter): Likewise.
> (vect_analyze_data_refs): Update call accordingly.
> * tree-vect-stmts.c (vect_mark_stmts_to_be_vectorized): Likewise.
> (vectorizable_mask_load_store): Likewise.  Also record the
> offset dt and vectype in the gather_scatter_info.
> (vectorizable_store): Likewise.
> (vectorizable_load): Likewise.
>
> Index: gcc/tree-vectorizer.h
> ===
> --- gcc/tree-vectorizer.h
> +++ gcc/tree-vectorizer.h
> @@ -612,6 +612,28 @@ typedef struct _stmt_vec_info {
>unsigned int num_slp_uses;
>  } *stmt_vec_info;
>
> +/* Information about a gather/scatter call.  */
> +struct gather_scatter_info {
> +  /* The FUNCTION_DECL for the built-in gather/scatter function.  */
> +  tree decl;
> +
> +  /* The loop-invariant base value.  */
> +  tree base;
> +
> +  /* The original scalar offset, which is a non-loop-invariant SSA_NAME.  */
> +  tree offset;
> +
> +  /* The definition type for the vectorized offset.  */
> +  enum vect_def_type offset_dt;
> +
> +  /* The type of the vectorized offset.  */
> +  tree offset_vectype;
> +
> +  /* Each offset element should be multiplied by this amount before
> + being added to the base.  */
> +  int scale;
> +};
> +
>  /* Access Functions.  */
>  #define STMT_VINFO_TYPE(S) (S)->type
>  #define STMT_VINFO_STMT(S) (S)->stmt
> @@ -1035,8 +1057,8 @@ extern bool vect_verify_datarefs_alignment 
> (loop_vec_info);
>  extern bool vect_slp_analyze_and_verify_instance_alignment (slp_instance);
>  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_check_gather_scatter (gimple *, loop_vec_info,
> +  gather_scatter_info *);
>  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 *,
> Index: gcc/tree-vect-data-refs.c
> ===
> --- gcc/tree-vect-data-refs.c
> +++ gcc/tree-vect-data-refs.c
> @@ -3174,12 +3174,12 @@ vect_prune_runtime_alias_test_list (loop_vec_info 
> loop_vinfo)
>return true;
>  }
>
> -/* Check whether a non-affine read or write in stmt is suitable for gather 
> load
> -   or scatter store and if so, return a builtin decl for that operation.  */
> +/* Return true if a non-affine read or write in STMT is suitable for a
> +   gather load or scatter store.  Describe the operation in *INFO if so.  */
>
> -tree
> -vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo, tree 
> *basep,
> -  tree *offp, int *scalep)
> +bool
> +vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo,
> +  gather_scatter_info *info)
>  {
>HOST_WIDE_INT scale = 1, pbitpos, pbitsize;
>struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> @@ -3253,7 +3253,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
> loop_vinfo, tree *basep,
>if (!expr_invariant_in_loop_p (loop, base))
>  {
>if (!integer_zerop (off))
> -   return NULL_TREE;
> +   return false;
>off = base;
>base = size_int (pbitpos / BITS_PER_UNIT);
>  }
> @@ -3279,7 +3279,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
> loop_vinfo, tree *basep,
>   gimple *def_stmt = SSA_NAME_DEF_STMT (off);
>
>   if (expr_invariant_in_loop_p (loop, off))
> -   return NULL_TREE;
> +   return false;
>
>   if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
> break;
> @@ -3291,7 +3291,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
> loop_vinfo, tree *basep,
>else
> {
>   if (get_gimple_rhs_class (TREE_CODE (off)) == GIMPLE_TERNARY_RHS)
> -   return NULL_TREE;
> +   return false;
>   code = TREE_CODE (off);
>   

[4/7] Add a gather_scatter_info structure

2016-06-15 Thread Richard Sandiford
This patch just refactors the gather/scatter support so that all
information is in a single structure, rather than separate variables.
This reduces the number of arguments to a function added in patch 6.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Thanks,
Richard


gcc/
* tree-vectorizer.h (gather_scatter_info): New structure.
(vect_check_gather_scatter): Return a bool rather than a decl.
Replace return-by-pointer arguments with a single
gather_scatter_info *.
* tree-vect-data-refs.c (vect_check_gather_scatter): Likewise.
(vect_analyze_data_refs): Update call accordingly.
* tree-vect-stmts.c (vect_mark_stmts_to_be_vectorized): Likewise.
(vectorizable_mask_load_store): Likewise.  Also record the
offset dt and vectype in the gather_scatter_info.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.

Index: gcc/tree-vectorizer.h
===
--- gcc/tree-vectorizer.h
+++ gcc/tree-vectorizer.h
@@ -612,6 +612,28 @@ typedef struct _stmt_vec_info {
   unsigned int num_slp_uses;
 } *stmt_vec_info;
 
+/* Information about a gather/scatter call.  */
+struct gather_scatter_info {
+  /* The FUNCTION_DECL for the built-in gather/scatter function.  */
+  tree decl;
+
+  /* The loop-invariant base value.  */
+  tree base;
+
+  /* The original scalar offset, which is a non-loop-invariant SSA_NAME.  */
+  tree offset;
+
+  /* The definition type for the vectorized offset.  */
+  enum vect_def_type offset_dt;
+
+  /* The type of the vectorized offset.  */
+  tree offset_vectype;
+
+  /* Each offset element should be multiplied by this amount before
+ being added to the base.  */
+  int scale;
+};
+
 /* Access Functions.  */
 #define STMT_VINFO_TYPE(S) (S)->type
 #define STMT_VINFO_STMT(S) (S)->stmt
@@ -1035,8 +1057,8 @@ extern bool vect_verify_datarefs_alignment 
(loop_vec_info);
 extern bool vect_slp_analyze_and_verify_instance_alignment (slp_instance);
 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_check_gather_scatter (gimple *, loop_vec_info,
+  gather_scatter_info *);
 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 *,
Index: gcc/tree-vect-data-refs.c
===
--- gcc/tree-vect-data-refs.c
+++ gcc/tree-vect-data-refs.c
@@ -3174,12 +3174,12 @@ vect_prune_runtime_alias_test_list (loop_vec_info 
loop_vinfo)
   return true;
 }
 
-/* Check whether a non-affine read or write in stmt is suitable for gather load
-   or scatter store and if so, return a builtin decl for that operation.  */
+/* Return true if a non-affine read or write in STMT is suitable for a
+   gather load or scatter store.  Describe the operation in *INFO if so.  */
 
-tree
-vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo, tree *basep,
-  tree *offp, int *scalep)
+bool
+vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo,
+  gather_scatter_info *info)
 {
   HOST_WIDE_INT scale = 1, pbitpos, pbitsize;
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -3253,7 +3253,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
loop_vinfo, tree *basep,
   if (!expr_invariant_in_loop_p (loop, base))
 {
   if (!integer_zerop (off))
-   return NULL_TREE;
+   return false;
   off = base;
   base = size_int (pbitpos / BITS_PER_UNIT);
 }
@@ -3279,7 +3279,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
loop_vinfo, tree *basep,
  gimple *def_stmt = SSA_NAME_DEF_STMT (off);
 
  if (expr_invariant_in_loop_p (loop, off))
-   return NULL_TREE;
+   return false;
 
  if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
break;
@@ -3291,7 +3291,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
loop_vinfo, tree *basep,
   else
{
  if (get_gimple_rhs_class (TREE_CODE (off)) == GIMPLE_TERNARY_RHS)
-   return NULL_TREE;
+   return false;
  code = TREE_CODE (off);
  extract_ops_from_tree (off, , , );
}
@@ -3366,7 +3366,7 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info 
loop_vinfo, tree *basep,
  defined in the loop, punt.  */
   if (TREE_CODE (off) != SSA_NAME
   || expr_invariant_in_loop_p (loop, off))
-return NULL_TREE;
+return false;
 
   if (offtype == NULL_TREE)
 offtype = TREE_TYPE (off);
@@ -3379,15 +3379,15 @@ vect_check_gather_scatter