Message ID | 87377py19l.fsf@linaro.org |
---|---|
State | Accepted |
Commit | e7c45b6600acfdc0930b980a45a364f77844139a |
Headers | show |
Series | Add gimple_build_vector* helpers | expand |
On Thu, Sep 14, 2017 at 1:20 PM, Richard Sandiford <richard.sandiford@linaro.org> 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 <richard.sandiford@linaro.org> > Alan Hayward <alan.hayward@arm.com> > David Sherwood <david.sherwood@arm.com> > > 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<tree>); > +inline tree > +gimple_build_vector (gimple_seq *seq, tree type, vec<tree> 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<tree> 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<constructor_elt, va_gc> *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.c 2017-09-14 11:25:32.164167193 +0100 > +++ gcc/tree-vect-loop.c 2017-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<tree, 32> elts (nunits); > - elts.quick_grow (nunits); > - for (i = nunits - 2; i >= 0; --i) > - elts[i + 1] = def_for_init; > - > - /* Option1: the first element is '0' or '1' as well. */ > if (adjustment_def) > + /* Option1: the first element is '0' or '1' as well. */ > + init_def = gimple_build_vector_from_val (&stmts, vectype, > + def_for_init); > + else > { > - elts[0] = def_for_init; > - > - init_def = build_vector (vectype, elts); > - break; > - } > - > - /* Option2: the first element is INIT_VAL. */ > - elts[0] = init_val; > - if (TREE_CONSTANT (init_val)) > - init_def = build_vector (vectype, elts); > - else > - { > - vec<constructor_elt, va_gc> *v; > - vec_alloc (v, nunits); > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_val); > + /* Option2: the first element is INIT_VAL. */ > + auto_vec<tree, 32> elts (nunits); > + elts.quick_push (init_val); > for (i = 1; i < nunits; ++i) > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); > - init_def = build_constructor (vectype, v); > + elts.quick_push (def_for_init); > + init_def = gimple_build_vector (&stmts, vectype, elts); > } > } > break; > @@ -4089,9 +4074,7 @@ get_initial_def_for_reduction (gimple *s > } > } > init_val = gimple_convert (&stmts, TREE_TYPE (vectype), init_val); > - if (! gimple_seq_empty_p (stmts)) > - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); > - init_def = build_vector_from_val (vectype, init_val); > + init_def = gimple_build_vector_from_val (&stmts, vectype, init_val); > } > break; > > @@ -4099,6 +4082,8 @@ get_initial_def_for_reduction (gimple *s > gcc_unreachable (); > } > > + if (stmts) > + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); > return init_def; > } > > @@ -4115,7 +4100,6 @@ get_initial_defs_for_reduction (slp_tree > gimple *stmt = stmts[0]; > stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); > unsigned nunits; > - tree vec_cst; > unsigned j, number_of_places_left_in_vector; > tree vector_type, scalar_type; > tree vop; > @@ -4124,10 +4108,8 @@ get_initial_defs_for_reduction (slp_tree > unsigned number_of_copies = 1; > vec<tree> voprnds; > voprnds.create (number_of_vectors); > - bool constant_p; > tree neutral_op = NULL; > struct loop *loop; > - gimple_seq ctor_seq = NULL; > > vector_type = STMT_VINFO_VECTYPE (stmt_vinfo); > scalar_type = TREE_TYPE (vector_type); > @@ -4137,6 +4119,7 @@ get_initial_defs_for_reduction (slp_tree > > loop = (gimple_bb (stmt))->loop_father; > gcc_assert (loop); > + edge pe = loop_preheader_edge (loop); > > /* op is the reduction operand of the first stmt already. */ > /* For additional copies (see the explanation of NUMBER_OF_COPIES below) > @@ -4170,8 +4153,7 @@ get_initial_defs_for_reduction (slp_tree > if (! reduc_chain) > neutral_op = NULL; > else > - neutral_op = PHI_ARG_DEF_FROM_EDGE (stmt, > - loop_preheader_edge (loop)); > + neutral_op = PHI_ARG_DEF_FROM_EDGE (stmt, pe); > break; > > default: > @@ -4198,7 +4180,6 @@ get_initial_defs_for_reduction (slp_tree > number_of_copies = nunits * number_of_vectors / group_size; > > number_of_places_left_in_vector = nunits; > - constant_p = true; > auto_vec<tree, 32> elts (nunits); > elts.quick_grow (nunits); > for (j = 0; j < number_of_copies; j++) > @@ -4213,42 +4194,21 @@ get_initial_defs_for_reduction (slp_tree > && neutral_op) > op = neutral_op; > else > - op = PHI_ARG_DEF_FROM_EDGE (stmt, > - loop_preheader_edge (loop)); > + op = PHI_ARG_DEF_FROM_EDGE (stmt, pe); > > /* Create 'vect_ = {op0,op1,...,opn}'. */ > number_of_places_left_in_vector--; > elts[number_of_places_left_in_vector] = op; > - if (!CONSTANT_CLASS_P (op)) > - constant_p = false; > > if (number_of_places_left_in_vector == 0) > { > - if (constant_p) > - vec_cst = build_vector (vector_type, elts); > - else > - { > - vec<constructor_elt, va_gc> *v; > - unsigned k; > - vec_alloc (v, nunits); > - for (k = 0; k < nunits; ++k) > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[k]); > - vec_cst = build_constructor (vector_type, v); > - } > - tree init; > - gimple_stmt_iterator gsi; > - init = vect_init_vector (stmt, vec_cst, vector_type, NULL); > + gimple_seq ctor_seq = NULL; > + tree init = gimple_build_vector (&ctor_seq, vector_type, elts); > if (ctor_seq != NULL) > - { > - gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (init)); > - gsi_insert_seq_before_without_update (&gsi, ctor_seq, > - GSI_SAME_STMT); > - ctor_seq = NULL; > - } > + gsi_insert_seq_on_edge_immediate (pe, ctor_seq); > voprnds.quick_push (init); > > number_of_places_left_in_vector = nunits; > - constant_p = true; > } > } > } > @@ -4268,15 +4228,19 @@ get_initial_defs_for_reduction (slp_tree > group of stmts, NUMBER_OF_VECTORS to be created is greater than > NUMBER_OF_SCALARS/NUNITS or NUNITS/NUMBER_OF_SCALARS, and hence we have > to replicate the vectors. */ > + tree neutral_vec = NULL; > while (number_of_vectors > vec_oprnds->length ()) > { > - tree neutral_vec = NULL; > - > if (neutral_op) > { > if (!neutral_vec) > - neutral_vec = build_vector_from_val (vector_type, neutral_op); > - > + { > + gimple_seq ctor_seq = NULL; > + neutral_vec = gimple_build_vector_from_val > + (&ctor_seq, vector_type, neutral_op); > + if (ctor_seq != NULL) > + gsi_insert_seq_on_edge_immediate (pe, ctor_seq); > + } > vec_oprnds->quick_push (neutral_vec); > } > else > @@ -4455,14 +4419,8 @@ vect_create_epilog_for_reduction (vec<tr > /* Set phi nodes arguments. */ > FOR_EACH_VEC_ELT (reduction_phis, i, phi) > { > - tree vec_init_def, def; > - gimple_seq stmts; > - vec_init_def = force_gimple_operand (vec_initial_defs[i], &stmts, > - true, NULL_TREE); > - if (stmts) > - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); > - > - def = vect_defs[i]; > + tree vec_init_def = vec_initial_defs[i]; > + tree def = vect_defs[i]; > for (j = 0; j < ncopies; j++) > { > if (j != 0) > @@ -5405,7 +5363,7 @@ vect_create_epilog_for_reduction (vec<tr > { > stmt_vec_info use_stmt_vinfo; > stmt_vec_info new_phi_vinfo; > - tree vect_phi_init, preheader_arg, vect_phi_res, init_def; > + tree vect_phi_init, preheader_arg, vect_phi_res; > basic_block bb = gimple_bb (use_stmt); > gimple *use; > > @@ -5438,10 +5396,8 @@ vect_create_epilog_for_reduction (vec<tr > /* Create vs0 - initial def of the double reduction phi. */ > preheader_arg = PHI_ARG_DEF_FROM_EDGE (use_stmt, > loop_preheader_edge (outer_loop)); > - init_def = get_initial_def_for_reduction (stmt, > - preheader_arg, NULL); > - vect_phi_init = vect_init_vector (use_stmt, init_def, > - vectype, NULL); > + vect_phi_init = get_initial_def_for_reduction > + (stmt, preheader_arg, NULL); > > /* Update phi node arguments with vs0 and vs2. */ > add_phi_arg (vect_phi, vect_phi_init, > @@ -6738,36 +6694,21 @@ vectorizable_induction (gimple *phi, > for (ivn = 0; ivn < nivs; ++ivn) > { > auto_vec<tree, 32> elts (nunits); > - bool constant_p = true; > + stmts = NULL; > for (unsigned eltn = 0; eltn < nunits; ++eltn) > { > if (ivn*nunits + eltn >= group_size > && (ivn*nunits + eltn) % group_size == 0) > - { > - stmts = NULL; > - elt = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (elt), > - elt, step_expr); > - if (stmts) > - { > - new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); > - gcc_assert (!new_bb); > - } > - } > - if (! CONSTANT_CLASS_P (elt)) > - constant_p = false; > + elt = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (elt), > + elt, step_expr); > elts.quick_push (elt); > } > - if (constant_p) > - new_vec = build_vector (vectype, elts); > - else > + vec_init = gimple_build_vector (&stmts, vectype, elts); > + if (stmts) > { > - vec<constructor_elt, va_gc> *v; > - vec_alloc (v, nunits); > - for (i = 0; i < nunits; ++i) > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); > - new_vec = build_constructor (vectype, v); > + new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); > + gcc_assert (!new_bb); > } > - vec_init = vect_init_vector (phi, new_vec, vectype, NULL); > > /* Create the induction-phi that defines the induction-operand. */ > vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_"); > @@ -6864,37 +6805,28 @@ vectorizable_induction (gimple *phi, > } > else > { > - vec<constructor_elt, va_gc> *v; > - > /* iv_loop is the loop to be vectorized. Create: > vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ > stmts = NULL; > new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr); > > - vec_alloc (v, nunits); > - bool constant_p = is_gimple_min_invariant (new_name); > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name); > + auto_vec<tree, 32> elts (nunits); > + elts.quick_push (new_name); > for (i = 1; i < nunits; i++) > { > /* Create: new_name_i = new_name + step_expr */ > new_name = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (new_name), > new_name, step_expr); > - if (!is_gimple_min_invariant (new_name)) > - constant_p = false; > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name); > + elts.quick_push (new_name); > } > + /* Create a vector from [new_name_0, new_name_1, ..., > + new_name_nunits-1] */ > + vec_init = gimple_build_vector (&stmts, vectype, elts); > if (stmts) > { > new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); > gcc_assert (!new_bb); > } > - > - /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1] */ > - if (constant_p) > - new_vec = build_vector_from_ctor (vectype, v); > - else > - new_vec = build_constructor (vectype, v); > - vec_init = vect_init_vector (phi, new_vec, vectype, NULL); > } > >
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<tree>); +inline tree +gimple_build_vector (gimple_seq *seq, tree type, vec<tree> 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<tree> 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<constructor_elt, va_gc> *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.c 2017-09-14 11:25:32.164167193 +0100 +++ gcc/tree-vect-loop.c 2017-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<tree, 32> elts (nunits); - elts.quick_grow (nunits); - for (i = nunits - 2; i >= 0; --i) - elts[i + 1] = def_for_init; - - /* Option1: the first element is '0' or '1' as well. */ if (adjustment_def) + /* Option1: the first element is '0' or '1' as well. */ + init_def = gimple_build_vector_from_val (&stmts, vectype, + def_for_init); + else { - elts[0] = def_for_init; - - init_def = build_vector (vectype, elts); - break; - } - - /* Option2: the first element is INIT_VAL. */ - elts[0] = init_val; - if (TREE_CONSTANT (init_val)) - init_def = build_vector (vectype, elts); - else - { - vec<constructor_elt, va_gc> *v; - vec_alloc (v, nunits); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_val); + /* Option2: the first element is INIT_VAL. */ + auto_vec<tree, 32> elts (nunits); + elts.quick_push (init_val); for (i = 1; i < nunits; ++i) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); - init_def = build_constructor (vectype, v); + elts.quick_push (def_for_init); + init_def = gimple_build_vector (&stmts, vectype, elts); } } break; @@ -4089,9 +4074,7 @@ get_initial_def_for_reduction (gimple *s } } init_val = gimple_convert (&stmts, TREE_TYPE (vectype), init_val); - if (! gimple_seq_empty_p (stmts)) - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); - init_def = build_vector_from_val (vectype, init_val); + init_def = gimple_build_vector_from_val (&stmts, vectype, init_val); } break; @@ -4099,6 +4082,8 @@ get_initial_def_for_reduction (gimple *s gcc_unreachable (); } + if (stmts) + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); return init_def; } @@ -4115,7 +4100,6 @@ get_initial_defs_for_reduction (slp_tree gimple *stmt = stmts[0]; stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); unsigned nunits; - tree vec_cst; unsigned j, number_of_places_left_in_vector; tree vector_type, scalar_type; tree vop; @@ -4124,10 +4108,8 @@ get_initial_defs_for_reduction (slp_tree unsigned number_of_copies = 1; vec<tree> voprnds; voprnds.create (number_of_vectors); - bool constant_p; tree neutral_op = NULL; struct loop *loop; - gimple_seq ctor_seq = NULL; vector_type = STMT_VINFO_VECTYPE (stmt_vinfo); scalar_type = TREE_TYPE (vector_type); @@ -4137,6 +4119,7 @@ get_initial_defs_for_reduction (slp_tree loop = (gimple_bb (stmt))->loop_father; gcc_assert (loop); + edge pe = loop_preheader_edge (loop); /* op is the reduction operand of the first stmt already. */ /* For additional copies (see the explanation of NUMBER_OF_COPIES below) @@ -4170,8 +4153,7 @@ get_initial_defs_for_reduction (slp_tree if (! reduc_chain) neutral_op = NULL; else - neutral_op = PHI_ARG_DEF_FROM_EDGE (stmt, - loop_preheader_edge (loop)); + neutral_op = PHI_ARG_DEF_FROM_EDGE (stmt, pe); break; default: @@ -4198,7 +4180,6 @@ get_initial_defs_for_reduction (slp_tree number_of_copies = nunits * number_of_vectors / group_size; number_of_places_left_in_vector = nunits; - constant_p = true; auto_vec<tree, 32> elts (nunits); elts.quick_grow (nunits); for (j = 0; j < number_of_copies; j++) @@ -4213,42 +4194,21 @@ get_initial_defs_for_reduction (slp_tree && neutral_op) op = neutral_op; else - op = PHI_ARG_DEF_FROM_EDGE (stmt, - loop_preheader_edge (loop)); + op = PHI_ARG_DEF_FROM_EDGE (stmt, pe); /* Create 'vect_ = {op0,op1,...,opn}'. */ number_of_places_left_in_vector--; elts[number_of_places_left_in_vector] = op; - if (!CONSTANT_CLASS_P (op)) - constant_p = false; if (number_of_places_left_in_vector == 0) { - if (constant_p) - vec_cst = build_vector (vector_type, elts); - else - { - vec<constructor_elt, va_gc> *v; - unsigned k; - vec_alloc (v, nunits); - for (k = 0; k < nunits; ++k) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[k]); - vec_cst = build_constructor (vector_type, v); - } - tree init; - gimple_stmt_iterator gsi; - init = vect_init_vector (stmt, vec_cst, vector_type, NULL); + gimple_seq ctor_seq = NULL; + tree init = gimple_build_vector (&ctor_seq, vector_type, elts); if (ctor_seq != NULL) - { - gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (init)); - gsi_insert_seq_before_without_update (&gsi, ctor_seq, - GSI_SAME_STMT); - ctor_seq = NULL; - } + gsi_insert_seq_on_edge_immediate (pe, ctor_seq); voprnds.quick_push (init); number_of_places_left_in_vector = nunits; - constant_p = true; } } } @@ -4268,15 +4228,19 @@ get_initial_defs_for_reduction (slp_tree group of stmts, NUMBER_OF_VECTORS to be created is greater than NUMBER_OF_SCALARS/NUNITS or NUNITS/NUMBER_OF_SCALARS, and hence we have to replicate the vectors. */ + tree neutral_vec = NULL; while (number_of_vectors > vec_oprnds->length ()) { - tree neutral_vec = NULL; - if (neutral_op) { if (!neutral_vec) - neutral_vec = build_vector_from_val (vector_type, neutral_op); - + { + gimple_seq ctor_seq = NULL; + neutral_vec = gimple_build_vector_from_val + (&ctor_seq, vector_type, neutral_op); + if (ctor_seq != NULL) + gsi_insert_seq_on_edge_immediate (pe, ctor_seq); + } vec_oprnds->quick_push (neutral_vec); } else @@ -4455,14 +4419,8 @@ vect_create_epilog_for_reduction (vec<tr /* Set phi nodes arguments. */ FOR_EACH_VEC_ELT (reduction_phis, i, phi) { - tree vec_init_def, def; - gimple_seq stmts; - vec_init_def = force_gimple_operand (vec_initial_defs[i], &stmts, - true, NULL_TREE); - if (stmts) - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); - - def = vect_defs[i]; + tree vec_init_def = vec_initial_defs[i]; + tree def = vect_defs[i]; for (j = 0; j < ncopies; j++) { if (j != 0) @@ -5405,7 +5363,7 @@ vect_create_epilog_for_reduction (vec<tr { stmt_vec_info use_stmt_vinfo; stmt_vec_info new_phi_vinfo; - tree vect_phi_init, preheader_arg, vect_phi_res, init_def; + tree vect_phi_init, preheader_arg, vect_phi_res; basic_block bb = gimple_bb (use_stmt); gimple *use; @@ -5438,10 +5396,8 @@ vect_create_epilog_for_reduction (vec<tr /* Create vs0 - initial def of the double reduction phi. */ preheader_arg = PHI_ARG_DEF_FROM_EDGE (use_stmt, loop_preheader_edge (outer_loop)); - init_def = get_initial_def_for_reduction (stmt, - preheader_arg, NULL); - vect_phi_init = vect_init_vector (use_stmt, init_def, - vectype, NULL); + vect_phi_init = get_initial_def_for_reduction + (stmt, preheader_arg, NULL); /* Update phi node arguments with vs0 and vs2. */ add_phi_arg (vect_phi, vect_phi_init, @@ -6738,36 +6694,21 @@ vectorizable_induction (gimple *phi, for (ivn = 0; ivn < nivs; ++ivn) { auto_vec<tree, 32> elts (nunits); - bool constant_p = true; + stmts = NULL; for (unsigned eltn = 0; eltn < nunits; ++eltn) { if (ivn*nunits + eltn >= group_size && (ivn*nunits + eltn) % group_size == 0) - { - stmts = NULL; - elt = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (elt), - elt, step_expr); - if (stmts) - { - new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); - gcc_assert (!new_bb); - } - } - if (! CONSTANT_CLASS_P (elt)) - constant_p = false; + elt = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (elt), + elt, step_expr); elts.quick_push (elt); } - if (constant_p) - new_vec = build_vector (vectype, elts); - else + vec_init = gimple_build_vector (&stmts, vectype, elts); + if (stmts) { - vec<constructor_elt, va_gc> *v; - vec_alloc (v, nunits); - for (i = 0; i < nunits; ++i) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); - new_vec = build_constructor (vectype, v); + new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); + gcc_assert (!new_bb); } - vec_init = vect_init_vector (phi, new_vec, vectype, NULL); /* Create the induction-phi that defines the induction-operand. */ vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_"); @@ -6864,37 +6805,28 @@ vectorizable_induction (gimple *phi, } else { - vec<constructor_elt, va_gc> *v; - /* iv_loop is the loop to be vectorized. Create: vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ stmts = NULL; new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr); - vec_alloc (v, nunits); - bool constant_p = is_gimple_min_invariant (new_name); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name); + auto_vec<tree, 32> elts (nunits); + elts.quick_push (new_name); for (i = 1; i < nunits; i++) { /* Create: new_name_i = new_name + step_expr */ new_name = gimple_build (&stmts, PLUS_EXPR, TREE_TYPE (new_name), new_name, step_expr); - if (!is_gimple_min_invariant (new_name)) - constant_p = false; - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name); + elts.quick_push (new_name); } + /* Create a vector from [new_name_0, new_name_1, ..., + new_name_nunits-1] */ + vec_init = gimple_build_vector (&stmts, vectype, elts); if (stmts) { new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); gcc_assert (!new_bb); } - - /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1] */ - if (constant_p) - new_vec = build_vector_from_ctor (vectype, v); - else - new_vec = build_constructor (vectype, v); - vec_init = vect_init_vector (phi, new_vec, vectype, NULL); }