Re: Add gimple_build_vector* helpers
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
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