Re: Add gimple_build_vector* helpers

2017-09-14 Thread Richard Biener
On Thu, Sep 14, 2017 at 1:20 PM, Richard Sandiford
 wrote:
> This patch adds gimple-fold.h equivalents of build_vector and
> build_vector_from_val.  Like the other gimple-fold.h routines
> they always return a valid gimple value and add any new
> statements to a given gimple_seq.  In combination with later
> patches this reduces the number of force_gimple_operands.
>
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
> OK to install?

Ok.

Thanks,
Richard.

> Richard
>
>
> 2017-09-14  Richard Sandiford  
> Alan Hayward  
> David Sherwood  
>
> gcc/
> * gimple-fold.h (gimple_build_vector_from_val): Declare, and provide
> an inline wrapper that provides a location.
> (gimple_build_vector): Likewise.
> * gimple-fold.c (gimple_build_vector_from_val): New function.
> (gimple_build_vector): Likewise.
> * tree-vect-loop.c (get_initial_def_for_reduction): Use the new
> functions to build the initial value.  Always return a gimple value.
> (get_initial_defs_for_reduction): Likewise.  Only compute
> neutral_vec once.
> (vect_create_epilog_for_reduction): Don't call force_gimple_operand or
> vect_init_vector on the results from get_initial_def(s)_for_reduction.
> (vectorizable_induction): Use gimple_build_vector rather than
> vect_init_vector.
>
> Index: gcc/gimple-fold.h
> ===
> --- gcc/gimple-fold.h   2017-07-08 11:37:46.573465901 +0100
> +++ gcc/gimple-fold.h   2017-09-14 11:26:37.598804415 +0100
> @@ -127,6 +127,21 @@ gimple_convert_to_ptrofftype (gimple_seq
>return gimple_convert_to_ptrofftype (seq, UNKNOWN_LOCATION, op);
>  }
>
> +extern tree gimple_build_vector_from_val (gimple_seq *, location_t, tree,
> + tree);
> +inline tree
> +gimple_build_vector_from_val (gimple_seq *seq, tree type, tree op)
> +{
> +  return gimple_build_vector_from_val (seq, UNKNOWN_LOCATION, type, op);
> +}
> +
> +extern tree gimple_build_vector (gimple_seq *, location_t, tree, vec);
> +inline tree
> +gimple_build_vector (gimple_seq *seq, tree type, vec elts)
> +{
> +  return gimple_build_vector (seq, UNKNOWN_LOCATION, type, elts);
> +}
> +
>  extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);
>  extern bool gimple_stmt_integer_valued_real_p (gimple *, int = 0);
>
> Index: gcc/gimple-fold.c
> ===
> --- gcc/gimple-fold.c   2017-09-14 11:24:42.666088258 +0100
> +++ gcc/gimple-fold.c   2017-09-14 11:26:37.598804415 +0100
> @@ -7058,6 +7058,58 @@ gimple_convert_to_ptrofftype (gimple_seq
>return gimple_convert (seq, loc, sizetype, op);
>  }
>
> +/* Build a vector of type TYPE in which each element has the value OP.
> +   Return a gimple value for the result, appending any new statements
> +   to SEQ.  */
> +
> +tree
> +gimple_build_vector_from_val (gimple_seq *seq, location_t loc, tree type,
> + tree op)
> +{
> +  tree res, vec = build_vector_from_val (type, op);
> +  if (is_gimple_val (vec))
> +return vec;
> +  if (gimple_in_ssa_p (cfun))
> +res = make_ssa_name (type);
> +  else
> +res = create_tmp_reg (type);
> +  gimple *stmt = gimple_build_assign (res, vec);
> +  gimple_set_location (stmt, loc);
> +  gimple_seq_add_stmt_without_update (seq, stmt);
> +  return res;
> +}
> +
> +/* Build a vector of type TYPE in which the elements have the values
> +   given by ELTS.  Return a gimple value for the result, appending any
> +   new instructions to SEQ.  */
> +
> +tree
> +gimple_build_vector (gimple_seq *seq, location_t loc, tree type,
> +vec elts)
> +{
> +  unsigned int nelts = elts.length ();
> +  gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
> +  for (unsigned int i = 0; i < nelts; ++i)
> +if (!TREE_CONSTANT (elts[i]))
> +  {
> +   vec *v;
> +   vec_alloc (v, nelts);
> +   for (i = 0; i < nelts; ++i)
> + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]);
> +
> +   tree res;
> +   if (gimple_in_ssa_p (cfun))
> + res = make_ssa_name (type);
> +   else
> + res = create_tmp_reg (type);
> +   gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
> +   gimple_set_location (stmt, loc);
> +   gimple_seq_add_stmt_without_update (seq, stmt);
> +   return res;
> +  }
> +  return build_vector (type, elts);
> +}
> +
>  /* Return true if the result of assignment STMT is known to be non-negative.
> If the return value is based on the assumption that signed overflow is
> undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
> Index: gcc/tree-vect-loop.c
> ===
> --- gcc/tree-vect-loop.c2017-09-14 11:25:32.164167193 +0100
> +++ gcc/tree-vect-loop.c2017-09-14 11:26:

Add gimple_build_vector* helpers

2017-09-14 Thread Richard Sandiford
This patch adds gimple-fold.h equivalents of build_vector and
build_vector_from_val.  Like the other gimple-fold.h routines
they always return a valid gimple value and add any new
statements to a given gimple_seq.  In combination with later
patches this reduces the number of force_gimple_operands.

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

Richard


2017-09-14  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* gimple-fold.h (gimple_build_vector_from_val): Declare, and provide
an inline wrapper that provides a location.
(gimple_build_vector): Likewise.
* gimple-fold.c (gimple_build_vector_from_val): New function.
(gimple_build_vector): Likewise.
* tree-vect-loop.c (get_initial_def_for_reduction): Use the new
functions to build the initial value.  Always return a gimple value.
(get_initial_defs_for_reduction): Likewise.  Only compute
neutral_vec once.
(vect_create_epilog_for_reduction): Don't call force_gimple_operand or
vect_init_vector on the results from get_initial_def(s)_for_reduction.
(vectorizable_induction): Use gimple_build_vector rather than
vect_init_vector.

Index: gcc/gimple-fold.h
===
--- gcc/gimple-fold.h   2017-07-08 11:37:46.573465901 +0100
+++ gcc/gimple-fold.h   2017-09-14 11:26:37.598804415 +0100
@@ -127,6 +127,21 @@ gimple_convert_to_ptrofftype (gimple_seq
   return gimple_convert_to_ptrofftype (seq, UNKNOWN_LOCATION, op);
 }
 
+extern tree gimple_build_vector_from_val (gimple_seq *, location_t, tree,
+ tree);
+inline tree
+gimple_build_vector_from_val (gimple_seq *seq, tree type, tree op)
+{
+  return gimple_build_vector_from_val (seq, UNKNOWN_LOCATION, type, op);
+}
+
+extern tree gimple_build_vector (gimple_seq *, location_t, tree, vec);
+inline tree
+gimple_build_vector (gimple_seq *seq, tree type, vec elts)
+{
+  return gimple_build_vector (seq, UNKNOWN_LOCATION, type, elts);
+}
+
 extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);
 extern bool gimple_stmt_integer_valued_real_p (gimple *, int = 0);
 
Index: gcc/gimple-fold.c
===
--- gcc/gimple-fold.c   2017-09-14 11:24:42.666088258 +0100
+++ gcc/gimple-fold.c   2017-09-14 11:26:37.598804415 +0100
@@ -7058,6 +7058,58 @@ gimple_convert_to_ptrofftype (gimple_seq
   return gimple_convert (seq, loc, sizetype, op);
 }
 
+/* Build a vector of type TYPE in which each element has the value OP.
+   Return a gimple value for the result, appending any new statements
+   to SEQ.  */
+
+tree
+gimple_build_vector_from_val (gimple_seq *seq, location_t loc, tree type,
+ tree op)
+{
+  tree res, vec = build_vector_from_val (type, op);
+  if (is_gimple_val (vec))
+return vec;
+  if (gimple_in_ssa_p (cfun))
+res = make_ssa_name (type);
+  else
+res = create_tmp_reg (type);
+  gimple *stmt = gimple_build_assign (res, vec);
+  gimple_set_location (stmt, loc);
+  gimple_seq_add_stmt_without_update (seq, stmt);
+  return res;
+}
+
+/* Build a vector of type TYPE in which the elements have the values
+   given by ELTS.  Return a gimple value for the result, appending any
+   new instructions to SEQ.  */
+
+tree
+gimple_build_vector (gimple_seq *seq, location_t loc, tree type,
+vec elts)
+{
+  unsigned int nelts = elts.length ();
+  gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
+  for (unsigned int i = 0; i < nelts; ++i)
+if (!TREE_CONSTANT (elts[i]))
+  {
+   vec *v;
+   vec_alloc (v, nelts);
+   for (i = 0; i < nelts; ++i)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]);
+
+   tree res;
+   if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type);
+   else
+ res = create_tmp_reg (type);
+   gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
+   gimple_set_location (stmt, loc);
+   gimple_seq_add_stmt_without_update (seq, stmt);
+   return res;
+  }
+  return build_vector (type, elts);
+}
+
 /* Return true if the result of assignment STMT is known to be non-negative.
If the return value is based on the assumption that signed overflow is
undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
Index: gcc/tree-vect-loop.c
===
--- gcc/tree-vect-loop.c2017-09-14 11:25:32.164167193 +0100
+++ gcc/tree-vect-loop.c2017-09-14 11:26:37.599804415 +0100
@@ -4044,33 +4044,18 @@ get_initial_def_for_reduction (gimple *s
 else
   def_for_init = build_int_cst (scalar_type, int_init_val);
 
-/* Create a vector of '0' or '1' except the first element.  */
-   auto_vec elts (nunits);
-   elts.quick_grow (nunits);
-f