Message ID | 87d16ty1kd.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Use vec<> in build_vector | expand |
On Thu, Sep 14, 2017 at 1:14 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > This patch makes build_vector take the elements as a vec<> rather > than a tree *. This is useful for SVE because it bundles the number > of elements with the elements themselves, and enforces the fact that > the number is constant. Also, I think things like the folds can be used > with any generic GNU vector, not just those that match machine vectors, > so the arguments to XALLOCAVEC had no clear limit. > > Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. > OK to install? Ok. Richard. > Richard > > > 2017-09-14 Richard Sandiford <richard.sandiford@linaro.org> > Alan Hayward <alan.hayward@arm.com> > David Sherwood <david.sherwood@arm.com> > > gcc/ > * tree.h (build_vector): Take a vec<tree> instead of a tree *. > * tree.c (build_vector): Likewise. > (build_vector_from_ctor): Update accordingly. > (build_vector_from_val): Likewise. > * gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise. > * tree-ssa-forwprop.c (simplify_vector_constructor): Likewise. > * tree-vect-generic.c (add_rshift): Likewise. > (expand_vector_divmod): Likewise. > (optimize_vector_constructor): Likewise. > * tree-vect-slp.c (vect_get_constant_vectors): Likewise. > (vect_transform_slp_perm_load): Likewise. > (vect_schedule_slp_instance): Likewise. > * tree-vect-stmts.c (vectorizable_bswap): Likewise. > (vectorizable_call): Likewise. > (vect_gen_perm_mask_any): Likewise. Add elements in order. > * expmed.c (make_tree): Likewise. > * fold-const.c (fold_negate_expr_1): Use auto_vec<tree> when building > a vector passed to build_vector. > (fold_convert_const): Likewise. > (exact_inverse): Likewise. > (fold_ternary_loc): Likewise. > (fold_relational_const): Likewise. > (const_binop): Likewise. Use VECTOR_CST_ELT directly when operating > on VECTOR_CSTs, rather than going through vec_cst_ctor_to_array. > (const_unop): Likewise. Store the reduction accumulator in a > variable rather than an array. > (vec_cst_ctor_to_array): Take the number of elements as a parameter. > (fold_vec_perm): Update calls accordingly. Use auto_vec<tree> for > the new vector, rather than constructing it after the input arrays. > (native_interpret_vector): Use auto_vec<tree> when building > a vector passed to build_vector. Add elements in order. > * tree-vect-loop.c (get_initial_defs_for_reduction): Use > auto_vec<tree> when building a vector passed to build_vector. > (vect_create_epilog_for_reduction): Likewise. > (vectorizable_induction): Likewise. > (get_initial_def_for_reduction): Likewise. Fix indentation of > case statements. > * config/sparc/sparc.c (sparc_handle_vis_mul8x16): Change n_elts > to a vec<tree> *. > (sparc_fold_builtin): Use auto_vec<tree> when building a vector > passed to build_vector. > > Index: gcc/tree.h > =================================================================== > --- gcc/tree.h 2017-09-14 11:23:57.004947653 +0100 > +++ gcc/tree.h 2017-09-14 11:24:42.669777533 +0100 > @@ -4026,7 +4026,7 @@ extern tree build_int_cst (tree, HOST_WI > extern tree build_int_cstu (tree type, unsigned HOST_WIDE_INT cst); > extern tree build_int_cst_type (tree, HOST_WIDE_INT); > extern tree make_vector (unsigned CXX_MEM_STAT_INFO); > -extern tree build_vector (tree, tree * CXX_MEM_STAT_INFO); > +extern tree build_vector (tree, vec<tree> CXX_MEM_STAT_INFO); > extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *); > extern tree build_vector_from_val (tree, tree); > extern void recompute_constructor_flags (tree); > Index: gcc/tree.c > =================================================================== > --- gcc/tree.c 2017-09-14 11:23:57.004947653 +0100 > +++ gcc/tree.c 2017-09-14 11:24:42.669777533 +0100 > @@ -1702,18 +1702,20 @@ make_vector (unsigned len MEM_STAT_DECL) > } > > /* Return a new VECTOR_CST node whose type is TYPE and whose values > - are in a list pointed to by VALS. */ > + are given by VALS. */ > > tree > -build_vector (tree type, tree *vals MEM_STAT_DECL) > +build_vector (tree type, vec<tree> vals MEM_STAT_DECL) > { > + unsigned int nelts = vals.length (); > + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type)); > int over = 0; > unsigned cnt = 0; > - tree v = make_vector (TYPE_VECTOR_SUBPARTS (type)); > + tree v = make_vector (nelts); > TREE_TYPE (v) = type; > > /* Iterate through elements and check for overflow. */ > - for (cnt = 0; cnt < TYPE_VECTOR_SUBPARTS (type); ++cnt) > + for (cnt = 0; cnt < nelts; ++cnt) > { > tree value = vals[cnt]; > > @@ -1736,20 +1738,21 @@ build_vector (tree type, tree *vals MEM_ > tree > build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v) > { > - tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); > - unsigned HOST_WIDE_INT idx, pos = 0; > + unsigned int nelts = TYPE_VECTOR_SUBPARTS (type); > + unsigned HOST_WIDE_INT idx; > tree value; > > + auto_vec<tree, 32> vec (nelts); > FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) > { > if (TREE_CODE (value) == VECTOR_CST) > for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i) > - vec[pos++] = VECTOR_CST_ELT (value, i); > + vec.quick_push (VECTOR_CST_ELT (value, i)); > else > - vec[pos++] = value; > + vec.quick_push (value); > } > - while (pos < TYPE_VECTOR_SUBPARTS (type)) > - vec[pos++] = build_zero_cst (TREE_TYPE (type)); > + while (vec.length () < nelts) > + vec.quick_push (build_zero_cst (TREE_TYPE (type))); > > return build_vector (type, vec); > } > @@ -1774,9 +1777,9 @@ build_vector_from_val (tree vectype, tre > > if (CONSTANT_CLASS_P (sc)) > { > - tree *v = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> v (nunits); > for (i = 0; i < nunits; ++i) > - v[i] = sc; > + v.quick_push (sc); > return build_vector (vectype, v); > } > else > Index: gcc/gimple-fold.c > =================================================================== > --- gcc/gimple-fold.c 2017-09-13 18:03:47.077908038 +0100 > +++ gcc/gimple-fold.c 2017-09-14 11:24:42.666088258 +0100 > @@ -5919,18 +5919,18 @@ gimple_fold_stmt_to_constant_1 (gimple * > && (CONSTRUCTOR_NELTS (rhs) > == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)))) > { > - unsigned i; > - tree val, *vec; > + unsigned i, nelts; > + tree val; > > - vec = XALLOCAVEC (tree, > - TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))); > + nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)); > + auto_vec<tree, 32> vec (nelts); > FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) > { > val = (*valueize) (val); > if (TREE_CODE (val) == INTEGER_CST > || TREE_CODE (val) == REAL_CST > || TREE_CODE (val) == FIXED_CST) > - vec[i] = val; > + vec.quick_push (val); > else > return NULL_TREE; > } > Index: gcc/tree-ssa-forwprop.c > =================================================================== > --- gcc/tree-ssa-forwprop.c 2017-08-21 15:50:48.662709938 +0100 > +++ gcc/tree-ssa-forwprop.c 2017-09-14 11:24:42.667010577 +0100 > @@ -2051,7 +2051,7 @@ simplify_vector_constructor (gimple_stmt > } > else > { > - tree mask_type, *mask_elts; > + tree mask_type; > > if (!can_vec_perm_p (TYPE_MODE (type), false, sel)) > return false; > @@ -2062,9 +2062,9 @@ simplify_vector_constructor (gimple_stmt > || GET_MODE_SIZE (TYPE_MODE (mask_type)) > != GET_MODE_SIZE (TYPE_MODE (type))) > return false; > - mask_elts = XALLOCAVEC (tree, nelts); > + auto_vec<tree, 32> mask_elts (nelts); > for (i = 0; i < nelts; i++) > - mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]); > + mask_elts.quick_push (build_int_cst (TREE_TYPE (mask_type), sel[i])); > op2 = build_vector (mask_type, mask_elts); > if (conv_code == ERROR_MARK) > gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2); > Index: gcc/tree-vect-generic.c > =================================================================== > --- gcc/tree-vect-generic.c 2017-09-12 14:24:48.541917623 +0100 > +++ gcc/tree-vect-generic.c 2017-09-14 11:24:42.667010577 +0100 > @@ -398,9 +398,9 @@ add_rshift (gimple_stmt_iterator *gsi, t > if (op != unknown_optab > && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing) > { > - tree *vec = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> vec (nunits); > for (i = 0; i < nunits; i++) > - vec[i] = build_int_cst (TREE_TYPE (type), shiftcnts[i]); > + vec.quick_push (build_int_cst (TREE_TYPE (type), shiftcnts[i])); > return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0, > build_vector (type, vec)); > } > @@ -429,7 +429,6 @@ expand_vector_divmod (gimple_stmt_iterat > unsigned int i; > signop sign_p = TYPE_SIGN (TREE_TYPE (type)); > unsigned HOST_WIDE_INT mask = GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type))); > - tree *vec; > tree cur_op, mulcst, tem; > optab op; > > @@ -593,8 +592,6 @@ expand_vector_divmod (gimple_stmt_iterat > mode = -2; > } > > - vec = XALLOCAVEC (tree, nunits); > - > if (use_pow2) > { > tree addend = NULL_TREE; > @@ -638,10 +635,11 @@ expand_vector_divmod (gimple_stmt_iterat > mask_type = build_same_sized_truth_vector_type (type); > zero = build_zero_cst (type); > cond = build2 (LT_EXPR, mask_type, op0, zero); > + auto_vec<tree, 32> vec (nunits); > for (i = 0; i < nunits; i++) > - vec[i] = build_int_cst (TREE_TYPE (type), > - (HOST_WIDE_INT_1U > - << shifts[i]) - 1); > + vec.quick_push (build_int_cst (TREE_TYPE (type), > + (HOST_WIDE_INT_1U > + << shifts[i]) - 1)); > cst = build_vector (type, vec); > addend = make_ssa_name (type); > stmt = gimple_build_assign (addend, VEC_COND_EXPR, cond, > @@ -676,10 +674,11 @@ expand_vector_divmod (gimple_stmt_iterat > else > { > tree mask; > + auto_vec<tree, 32> vec (nunits); > for (i = 0; i < nunits; i++) > - vec[i] = build_int_cst (TREE_TYPE (type), > - (HOST_WIDE_INT_1U > - << shifts[i]) - 1); > + vec.quick_push (build_int_cst (TREE_TYPE (type), > + (HOST_WIDE_INT_1U > + << shifts[i]) - 1)); > mask = build_vector (type, vec); > op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default); > if (op != unknown_optab > @@ -754,8 +753,9 @@ expand_vector_divmod (gimple_stmt_iterat > return NULL_TREE; > } > > + auto_vec<tree, 32> vec (nunits); > for (i = 0; i < nunits; i++) > - vec[i] = build_int_cst (TREE_TYPE (type), mulc[i]); > + vec.quick_push (build_int_cst (TREE_TYPE (type), mulc[i])); > mulcst = build_vector (type, vec); > > cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst); > @@ -1066,7 +1066,6 @@ optimize_vector_constructor (gimple_stmt > unsigned int i, j, nelts = TYPE_VECTOR_SUBPARTS (type); > bool all_same = true; > constructor_elt *elt; > - tree *cst; > gimple *g; > tree base = NULL_TREE; > optab op; > @@ -1105,22 +1104,23 @@ optimize_vector_constructor (gimple_stmt > } > if (all_same) > return; > - cst = XALLOCAVEC (tree, nelts); > + auto_vec<tree, 32> cst (nelts); > for (i = 0; i < nelts; i++) > { > - tree this_base = CONSTRUCTOR_ELT (rhs, i)->value;; > - cst[i] = build_zero_cst (TREE_TYPE (base)); > + tree this_base = CONSTRUCTOR_ELT (rhs, i)->value; > + tree elt = build_zero_cst (TREE_TYPE (base)); > while (this_base != base) > { > g = SSA_NAME_DEF_STMT (this_base); > - cst[i] = fold_binary (PLUS_EXPR, TREE_TYPE (base), > - cst[i], gimple_assign_rhs2 (g)); > - if (cst[i] == NULL_TREE > - || TREE_CODE (cst[i]) != INTEGER_CST > - || TREE_OVERFLOW (cst[i])) > + elt = fold_binary (PLUS_EXPR, TREE_TYPE (base), > + elt, gimple_assign_rhs2 (g)); > + if (elt == NULL_TREE > + || TREE_CODE (elt) != INTEGER_CST > + || TREE_OVERFLOW (elt)) > return; > this_base = gimple_assign_rhs1 (g); > } > + cst.quick_push (elt); > } > for (i = 0; i < nelts; i++) > CONSTRUCTOR_ELT (rhs, i)->value = base; > Index: gcc/tree-vect-slp.c > =================================================================== > --- gcc/tree-vect-slp.c 2017-08-30 12:19:19.719220029 +0100 > +++ gcc/tree-vect-slp.c 2017-09-14 11:24:42.667932896 +0100 > @@ -3105,7 +3105,6 @@ vect_get_constant_vectors (tree op, slp_ > stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); > unsigned nunits; > tree vec_cst; > - tree *elts; > unsigned j, number_of_places_left_in_vector; > tree vector_type; > tree vop; > @@ -3158,7 +3157,8 @@ vect_get_constant_vectors (tree op, slp_ > > number_of_places_left_in_vector = nunits; > constant_p = true; > - elts = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> elts (nunits); > + elts.quick_grow (nunits); > bool place_after_defs = false; > for (j = 0; j < number_of_copies; j++) > { > @@ -3600,10 +3600,10 @@ vect_transform_slp_perm_load (slp_tree n > > if (! noop_p) > { > - tree *mask_elts = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> mask_elts (nunits); > for (int l = 0; l < nunits; ++l) > - mask_elts[l] = build_int_cst (mask_element_type, > - mask[l]); > + mask_elts.quick_push (build_int_cst (mask_element_type, > + mask[l])); > mask_vec = build_vector (mask_type, mask_elts); > } > > @@ -3759,13 +3759,14 @@ vect_schedule_slp_instance (slp_tree nod > unsigned k = 0, l; > for (j = 0; j < v0.length (); ++j) > { > - tree *melts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (vectype)); > - for (l = 0; l < TYPE_VECTOR_SUBPARTS (vectype); ++l) > + unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype); > + auto_vec<tree, 32> melts (nunits); > + for (l = 0; l < nunits; ++l) > { > if (k >= group_size) > k = 0; > - melts[l] = build_int_cst > - (meltype, mask[k++] * TYPE_VECTOR_SUBPARTS (vectype) + l); > + tree t = build_int_cst (meltype, mask[k++] * nunits + l); > + melts.quick_push (t); > } > tmask = build_vector (mvectype, melts); > > Index: gcc/tree-vect-stmts.c > =================================================================== > --- gcc/tree-vect-stmts.c 2017-09-06 20:47:36.983150825 +0100 > +++ gcc/tree-vect-stmts.c 2017-09-14 11:24:42.668855214 +0100 > @@ -2480,10 +2480,10 @@ vectorizable_bswap (gimple *stmt, gimple > if (! char_vectype) > return false; > > - unsigned char *elts > - = XALLOCAVEC (unsigned char, TYPE_VECTOR_SUBPARTS (char_vectype)); > + unsigned int num_bytes = TYPE_VECTOR_SUBPARTS (char_vectype); > + unsigned char *elts = XALLOCAVEC (unsigned char, num_bytes); > unsigned char *elt = elts; > - unsigned word_bytes = TYPE_VECTOR_SUBPARTS (char_vectype) / nunits; > + unsigned word_bytes = num_bytes / nunits; > for (unsigned i = 0; i < nunits; ++i) > for (unsigned j = 0; j < word_bytes; ++j) > *elt++ = (i + 1) * word_bytes - j - 1; > @@ -2507,9 +2507,9 @@ vectorizable_bswap (gimple *stmt, gimple > return true; > } > > - tree *telts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (char_vectype)); > - for (unsigned i = 0; i < TYPE_VECTOR_SUBPARTS (char_vectype); ++i) > - telts[i] = build_int_cst (char_type_node, elts[i]); > + auto_vec<tree, 32> telts (num_bytes); > + for (unsigned i = 0; i < num_bytes; ++i) > + telts.quick_push (build_int_cst (char_type_node, elts[i])); > tree bswap_vconst = build_vector (char_vectype, telts); > > /* Transform. */ > @@ -2928,10 +2928,10 @@ vectorizable_call (gimple *gs, gimple_st > if (gimple_call_internal_p (stmt) > && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE) > { > - tree *v = XALLOCAVEC (tree, nunits_out); > - int k; > - for (k = 0; k < nunits_out; ++k) > - v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k); > + auto_vec<tree, 32> v (nunits_out); > + for (int k = 0; k < nunits_out; ++k) > + v.quick_push (build_int_cst (unsigned_type_node, > + j * nunits_out + k)); > tree cst = build_vector (vectype_out, v); > tree new_var > = vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_"); > @@ -6505,7 +6505,7 @@ vectorizable_store (gimple *stmt, gimple > tree > vect_gen_perm_mask_any (tree vectype, const unsigned char *sel) > { > - tree mask_elt_type, mask_type, mask_vec, *mask_elts; > + tree mask_elt_type, mask_type, mask_vec; > int i, nunits; > > nunits = TYPE_VECTOR_SUBPARTS (vectype); > @@ -6514,9 +6514,9 @@ vect_gen_perm_mask_any (tree vectype, co > (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))).require (), 1); > mask_type = get_vectype_for_scalar_type (mask_elt_type); > > - mask_elts = XALLOCAVEC (tree, nunits); > - for (i = nunits - 1; i >= 0; i--) > - mask_elts[i] = build_int_cst (mask_elt_type, sel[i]); > + auto_vec<tree, 32> mask_elts (nunits); > + for (i = 0; i < nunits; ++i) > + mask_elts.quick_push (build_int_cst (mask_elt_type, sel[i])); > mask_vec = build_vector (mask_type, mask_elts); > > return mask_vec; > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c 2017-09-14 11:23:44.291407202 +0100 > +++ gcc/expmed.c 2017-09-14 11:24:42.664243620 +0100 > @@ -5180,15 +5180,14 @@ make_tree (tree type, rtx x) > { > int units = CONST_VECTOR_NUNITS (x); > tree itype = TREE_TYPE (type); > - tree *elts; > int i; > > /* Build a tree with vector elements. */ > - elts = XALLOCAVEC (tree, units); > - for (i = units - 1; i >= 0; --i) > + auto_vec<tree, 32> elts (units); > + for (i = 0; i < units; ++i) > { > rtx elt = CONST_VECTOR_ELT (x, i); > - elts[i] = make_tree (itype, elt); > + elts.quick_push (make_tree (itype, elt)); > } > > return build_vector (type, elts); > Index: gcc/fold-const.c > =================================================================== > --- gcc/fold-const.c 2017-09-14 11:23:57.004041291 +0100 > +++ gcc/fold-const.c 2017-09-14 11:24:42.666088258 +0100 > @@ -136,7 +136,6 @@ static tree fold_not_const (const_tree, > static tree fold_relational_const (enum tree_code, tree, tree, tree); > static tree fold_convert_const (enum tree_code, tree, tree); > static tree fold_view_convert_expr (tree, tree); > -static bool vec_cst_ctor_to_array (tree, tree *); > static tree fold_negate_expr (location_t, tree); > > > @@ -565,13 +564,14 @@ fold_negate_expr_1 (location_t loc, tree > case VECTOR_CST: > { > int count = VECTOR_CST_NELTS (t), i; > - tree *elts = XALLOCAVEC (tree, count); > > + auto_vec<tree, 32> elts (count); > for (i = 0; i < count; i++) > { > - elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); > - if (elts[i] == NULL_TREE) > + tree elt = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); > + if (elt == NULL_TREE) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1414,19 +1414,20 @@ const_binop (enum tree_code code, tree a > { > tree type = TREE_TYPE (arg1); > int count = VECTOR_CST_NELTS (arg1), i; > - tree *elts = XALLOCAVEC (tree, count); > > + auto_vec<tree, 32> elts (count); > for (i = 0; i < count; i++) > { > tree elem1 = VECTOR_CST_ELT (arg1, i); > tree elem2 = VECTOR_CST_ELT (arg2, i); > > - elts[i] = const_binop (code, elem1, elem2); > + tree elt = const_binop (code, elem1, elem2); > > /* It is possible that const_binop cannot handle the given > code and return NULL_TREE */ > - if (elts[i] == NULL_TREE) > + if (elt == NULL_TREE) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1438,18 +1439,19 @@ const_binop (enum tree_code code, tree a > { > tree type = TREE_TYPE (arg1); > int count = VECTOR_CST_NELTS (arg1), i; > - tree *elts = XALLOCAVEC (tree, count); > > + auto_vec<tree, 32> elts (count); > for (i = 0; i < count; i++) > { > tree elem1 = VECTOR_CST_ELT (arg1, i); > > - elts[i] = const_binop (code, elem1, arg2); > + tree elt = const_binop (code, elem1, arg2); > > /* It is possible that const_binop cannot handle the given > code and return NULL_TREE. */ > - if (elts[i] == NULL_TREE) > + if (elt == NULL_TREE) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1481,7 +1483,6 @@ const_binop (enum tree_code code, tree t > case VEC_PACK_TRUNC_EXPR: > case VEC_PACK_FIX_TRUNC_EXPR: > { > - tree *elts; > unsigned int out_nelts, in_nelts, i; > > if (TREE_CODE (arg1) != VECTOR_CST > @@ -1493,18 +1494,18 @@ const_binop (enum tree_code code, tree t > gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2) > && out_nelts == TYPE_VECTOR_SUBPARTS (type)); > > - elts = XALLOCAVEC (tree, out_nelts); > - if (!vec_cst_ctor_to_array (arg1, elts) > - || !vec_cst_ctor_to_array (arg2, elts + in_nelts)) > - return NULL_TREE; > - > + auto_vec<tree, 32> elts (out_nelts); > for (i = 0; i < out_nelts; i++) > { > - elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR > - ? NOP_EXPR : FIX_TRUNC_EXPR, > - TREE_TYPE (type), elts[i]); > - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) > + tree elt = (i < in_nelts > + ? VECTOR_CST_ELT (arg1, i) > + : VECTOR_CST_ELT (arg2, i - in_nelts)); > + elt = fold_convert_const (code == VEC_PACK_TRUNC_EXPR > + ? NOP_EXPR : FIX_TRUNC_EXPR, > + TREE_TYPE (type), elt); > + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1516,7 +1517,6 @@ const_binop (enum tree_code code, tree t > case VEC_WIDEN_MULT_ODD_EXPR: > { > unsigned int out_nelts, in_nelts, out, ofs, scale; > - tree *elts; > > if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST) > return NULL_TREE; > @@ -1526,11 +1526,6 @@ const_binop (enum tree_code code, tree t > gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2) > && out_nelts == TYPE_VECTOR_SUBPARTS (type)); > > - elts = XALLOCAVEC (tree, in_nelts * 2); > - if (!vec_cst_ctor_to_array (arg1, elts) > - || !vec_cst_ctor_to_array (arg2, elts + in_nelts)) > - return NULL_TREE; > - > if (code == VEC_WIDEN_MULT_LO_EXPR) > scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0; > else if (code == VEC_WIDEN_MULT_HI_EXPR) > @@ -1540,20 +1535,21 @@ const_binop (enum tree_code code, tree t > else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */ > scale = 1, ofs = 1; > > + auto_vec<tree, 32> elts (out_nelts); > for (out = 0; out < out_nelts; out++) > { > - unsigned int in1 = (out << scale) + ofs; > - unsigned int in2 = in1 + in_nelts; > - tree t1, t2; > - > - t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]); > - t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in2]); > + unsigned int in = (out << scale) + ofs; > + tree t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), > + VECTOR_CST_ELT (arg1, in)); > + tree t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), > + VECTOR_CST_ELT (arg2, in)); > > if (t1 == NULL_TREE || t2 == NULL_TREE) > return NULL_TREE; > - elts[out] = const_binop (MULT_EXPR, t1, t2); > - if (elts[out] == NULL_TREE || !CONSTANT_CLASS_P (elts[out])) > + tree elt = const_binop (MULT_EXPR, t1, t2); > + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1638,18 +1634,17 @@ const_unop (enum tree_code code, tree ty > /* Perform BIT_NOT_EXPR on each element individually. */ > else if (TREE_CODE (arg0) == VECTOR_CST) > { > - tree *elements; > tree elem; > unsigned count = VECTOR_CST_NELTS (arg0), i; > > - elements = XALLOCAVEC (tree, count); > + auto_vec<tree, 32> elements (count); > for (i = 0; i < count; i++) > { > elem = VECTOR_CST_ELT (arg0, i); > elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem); > if (elem == NULL_TREE) > break; > - elements[i] = elem; > + elements.quick_push (elem); > } > if (i == count) > return build_vector (type, elements); > @@ -1677,7 +1672,6 @@ const_unop (enum tree_code code, tree ty > case VEC_UNPACK_FLOAT_HI_EXPR: > { > unsigned int out_nelts, in_nelts, i; > - tree *elts; > enum tree_code subcode; > > if (TREE_CODE (arg0) != VECTOR_CST) > @@ -1687,24 +1681,24 @@ const_unop (enum tree_code code, tree ty > out_nelts = in_nelts / 2; > gcc_assert (out_nelts == TYPE_VECTOR_SUBPARTS (type)); > > - elts = XALLOCAVEC (tree, in_nelts); > - if (!vec_cst_ctor_to_array (arg0, elts)) > - return NULL_TREE; > - > + unsigned int offset = 0; > if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR > || code == VEC_UNPACK_FLOAT_LO_EXPR)) > - elts += out_nelts; > + offset = out_nelts; > > if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR) > subcode = NOP_EXPR; > else > subcode = FLOAT_EXPR; > > + auto_vec<tree, 32> elts (out_nelts); > for (i = 0; i < out_nelts; i++) > { > - elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]); > - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) > + tree elt = fold_convert_const (subcode, TREE_TYPE (type), > + VECTOR_CST_ELT (arg0, i + offset)); > + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) > return NULL_TREE; > + elts.quick_push (elt); > } > > return build_vector (type, elts); > @@ -1715,17 +1709,12 @@ const_unop (enum tree_code code, tree ty > case REDUC_PLUS_EXPR: > { > unsigned int nelts, i; > - tree *elts; > enum tree_code subcode; > > if (TREE_CODE (arg0) != VECTOR_CST) > return NULL_TREE; > nelts = VECTOR_CST_NELTS (arg0); > > - elts = XALLOCAVEC (tree, nelts); > - if (!vec_cst_ctor_to_array (arg0, elts)) > - return NULL_TREE; > - > switch (code) > { > case REDUC_MIN_EXPR: subcode = MIN_EXPR; break; > @@ -1734,14 +1723,15 @@ const_unop (enum tree_code code, tree ty > default: gcc_unreachable (); > } > > + tree res = VECTOR_CST_ELT (arg0, 0); > for (i = 1; i < nelts; i++) > { > - elts[0] = const_binop (subcode, elts[0], elts[i]); > - if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0])) > + res = const_binop (subcode, res, VECTOR_CST_ELT (arg0, i)); > + if (res == NULL_TREE || !CONSTANT_CLASS_P (res)) > return NULL_TREE; > } > > - return elts[0]; > + return res; > } > > default: > @@ -2163,14 +2153,14 @@ fold_convert_const (enum tree_code code, > { > int len = VECTOR_CST_NELTS (arg1); > tree elttype = TREE_TYPE (type); > - tree *v = XALLOCAVEC (tree, len); > + auto_vec<tree, 32> v (len); > for (int i = 0; i < len; ++i) > { > tree elt = VECTOR_CST_ELT (arg1, i); > tree cvt = fold_convert_const (code, elttype, elt); > if (cvt == NULL_TREE) > return NULL_TREE; > - v[i] = cvt; > + v.quick_push (cvt); > } > return build_vector (type, v); > } > @@ -7392,7 +7382,6 @@ native_interpret_vector (tree type, cons > { > tree etype, elem; > int i, size, count; > - tree *elements; > > etype = TREE_TYPE (type); > size = GET_MODE_SIZE (SCALAR_TYPE_MODE (etype)); > @@ -7400,13 +7389,13 @@ native_interpret_vector (tree type, cons > if (size * count > len) > return NULL_TREE; > > - elements = XALLOCAVEC (tree, count); > - for (i = count - 1; i >= 0; i--) > + auto_vec<tree, 32> elements (count); > + for (i = 0; i < count; ++i) > { > elem = native_interpret_expr (etype, ptr+(i*size), size); > if (!elem) > return NULL_TREE; > - elements[i] = elem; > + elements.quick_push (elem); > } > return build_vector (type, elements); > } > @@ -8761,12 +8750,13 @@ fold_mult_zconjz (location_t loc, tree t > > > /* Helper function for fold_vec_perm. Store elements of VECTOR_CST or > - CONSTRUCTOR ARG into array ELTS and return true if successful. */ > + CONSTRUCTOR ARG into array ELTS, which has NELTS elements, and return > + true if successful. */ > > static bool > -vec_cst_ctor_to_array (tree arg, tree *elts) > +vec_cst_ctor_to_array (tree arg, unsigned int nelts, tree *elts) > { > - unsigned int nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)), i; > + unsigned int i; > > if (TREE_CODE (arg) == VECTOR_CST) > { > @@ -8799,7 +8789,6 @@ vec_cst_ctor_to_array (tree arg, tree *e > fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) > { > unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; > - tree *elts; > bool need_ctor = false; > > gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts > @@ -8808,16 +8797,17 @@ fold_vec_perm (tree type, tree arg0, tre > || TREE_TYPE (TREE_TYPE (arg1)) != TREE_TYPE (type)) > return NULL_TREE; > > - elts = XALLOCAVEC (tree, nelts * 3); > - if (!vec_cst_ctor_to_array (arg0, elts) > - || !vec_cst_ctor_to_array (arg1, elts + nelts)) > + tree *in_elts = XALLOCAVEC (tree, nelts * 2); > + if (!vec_cst_ctor_to_array (arg0, nelts, in_elts) > + || !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts)) > return NULL_TREE; > > + auto_vec<tree, 32> out_elts (nelts); > for (i = 0; i < nelts; i++) > { > - if (!CONSTANT_CLASS_P (elts[sel[i]])) > + if (!CONSTANT_CLASS_P (in_elts[sel[i]])) > need_ctor = true; > - elts[i + 2 * nelts] = unshare_expr (elts[sel[i]]); > + out_elts.quick_push (unshare_expr (in_elts[sel[i]])); > } > > if (need_ctor) > @@ -8825,11 +8815,11 @@ fold_vec_perm (tree type, tree arg0, tre > vec<constructor_elt, va_gc> *v; > vec_alloc (v, nelts); > for (i = 0; i < nelts; i++) > - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[2 * nelts + i]); > + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, out_elts[i]); > return build_constructor (type, v); > } > else > - return build_vector (type, &elts[2 * nelts]); > + return build_vector (type, out_elts); > } > > /* Try to fold a pointer difference of type TYPE two address expressions of > @@ -8879,7 +8869,7 @@ fold_addr_of_array_ref_difference (locat > exact_inverse (tree type, tree cst) > { > REAL_VALUE_TYPE r; > - tree unit_type, *elts; > + tree unit_type; > machine_mode mode; > unsigned vec_nelts, i; > > @@ -8894,20 +8884,22 @@ exact_inverse (tree type, tree cst) > return NULL_TREE; > > case VECTOR_CST: > - vec_nelts = VECTOR_CST_NELTS (cst); > - elts = XALLOCAVEC (tree, vec_nelts); > - unit_type = TREE_TYPE (type); > - mode = TYPE_MODE (unit_type); > + { > + vec_nelts = VECTOR_CST_NELTS (cst); > + unit_type = TREE_TYPE (type); > + mode = TYPE_MODE (unit_type); > > - for (i = 0; i < vec_nelts; i++) > - { > - r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); > - if (!exact_real_inverse (mode, &r)) > - return NULL_TREE; > - elts[i] = build_real (unit_type, r); > - } > + auto_vec<tree, 32> elts (vec_nelts); > + for (i = 0; i < vec_nelts; i++) > + { > + r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); > + if (!exact_real_inverse (mode, &r)) > + return NULL_TREE; > + elts.quick_push (build_real (unit_type, r)); > + } > > - return build_vector (type, elts); > + return build_vector (type, elts); > + } > > default: > return NULL_TREE; > @@ -11596,9 +11588,9 @@ fold_ternary_loc (location_t loc, enum t > if (n == 1) > return VECTOR_CST_ELT (arg0, idx); > > - tree *vals = XALLOCAVEC (tree, n); > + auto_vec<tree, 32> vals (n); > for (unsigned i = 0; i < n; ++i) > - vals[i] = VECTOR_CST_ELT (arg0, idx + i); > + vals.quick_push (VECTOR_CST_ELT (arg0, idx + i)); > return build_vector (type, vals); > } > } > @@ -11731,10 +11723,10 @@ fold_ternary_loc (location_t loc, enum t > > if (need_mask_canon && arg2 == op2) > { > - tree *tsel = XALLOCAVEC (tree, nelts); > tree eltype = TREE_TYPE (TREE_TYPE (arg2)); > + auto_vec<tree, 32> tsel (nelts); > for (i = 0; i < nelts; i++) > - tsel[i] = build_int_cst (eltype, sel[i]); > + tsel.quick_push (build_int_cst (eltype, sel[i])); > op2 = build_vector (TREE_TYPE (arg2), tsel); > changed = true; > } > @@ -11775,8 +11767,10 @@ fold_ternary_loc (location_t loc, enum t > else > { > unsigned int nelts = VECTOR_CST_NELTS (arg0); > - tree *elts = XALLOCAVEC (tree, nelts); > - memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts); > + auto_vec<tree, 32> elts (nelts); > + elts.quick_grow (nelts); > + memcpy (&elts[0], VECTOR_CST_ELTS (arg0), > + sizeof (tree) * nelts); > elts[k] = arg1; > return build_vector (type, elts); > } > @@ -13894,10 +13888,10 @@ fold_relational_const (enum tree_code co > return constant_boolean_node (true, type); > } > unsigned count = VECTOR_CST_NELTS (op0); > - tree *elts = XALLOCAVEC (tree, count); > gcc_assert (VECTOR_CST_NELTS (op1) == count > && TYPE_VECTOR_SUBPARTS (type) == count); > > + auto_vec<tree, 32> elts (count); > for (unsigned i = 0; i < count; i++) > { > tree elem_type = TREE_TYPE (type); > @@ -13910,7 +13904,8 @@ fold_relational_const (enum tree_code co > if (tem == NULL_TREE) > return NULL_TREE; > > - elts[i] = build_int_cst (elem_type, integer_zerop (tem) ? 0 : -1); > + elts.quick_push (build_int_cst (elem_type, > + integer_zerop (tem) ? 0 : -1)); > } > > return build_vector (type, elts); > Index: gcc/tree-vect-loop.c > =================================================================== > --- gcc/tree-vect-loop.c 2017-08-30 12:19:19.718220029 +0100 > +++ gcc/tree-vect-loop.c 2017-09-14 11:24:42.667932896 +0100 > @@ -3969,7 +3969,6 @@ get_initial_def_for_reduction (gimple *s > enum tree_code code = gimple_assign_rhs_code (stmt); > tree def_for_init; > tree init_def; > - tree *elts; > int i; > bool nested_in_vect_loop = false; > REAL_VALUE_TYPE real_init_val = dconst0; > @@ -4015,15 +4014,16 @@ get_initial_def_for_reduction (gimple *s > > switch (code) > { > - case WIDEN_SUM_EXPR: > - case DOT_PROD_EXPR: > - case SAD_EXPR: > - case PLUS_EXPR: > - case MINUS_EXPR: > - case BIT_IOR_EXPR: > - case BIT_XOR_EXPR: > - case MULT_EXPR: > - case BIT_AND_EXPR: > + case WIDEN_SUM_EXPR: > + case DOT_PROD_EXPR: > + case SAD_EXPR: > + case PLUS_EXPR: > + case MINUS_EXPR: > + case BIT_IOR_EXPR: > + case BIT_XOR_EXPR: > + case MULT_EXPR: > + case BIT_AND_EXPR: > + { > /* ADJUSMENT_DEF is NULL when called from > vect_create_epilog_for_reduction to vectorize double reduction. */ > if (adjustment_def) > @@ -4044,17 +4044,19 @@ get_initial_def_for_reduction (gimple *s > def_for_init = build_int_cst (scalar_type, int_init_val); > > /* Create a vector of '0' or '1' except the first element. */ > - elts = XALLOCAVEC (tree, nunits); > + 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) > - { > + if (adjustment_def) > + { > elts[0] = def_for_init; > - init_def = build_vector (vectype, elts); > - break; > - } > + > + init_def = build_vector (vectype, elts); > + break; > + } > > /* Option2: the first element is INIT_VAL. */ > elts[0] = init_val; > @@ -4069,12 +4071,13 @@ get_initial_def_for_reduction (gimple *s > CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); > init_def = build_constructor (vectype, v); > } > + } > + break; > > - break; > - > - case MIN_EXPR: > - case MAX_EXPR: > - case COND_EXPR: > + case MIN_EXPR: > + case MAX_EXPR: > + case COND_EXPR: > + { > if (adjustment_def) > { > *adjustment_def = NULL_TREE; > @@ -4088,10 +4091,11 @@ get_initial_def_for_reduction (gimple *s > 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); > - break; > + } > + break; > > - default: > - gcc_unreachable (); > + default: > + gcc_unreachable (); > } > > return init_def; > @@ -4111,7 +4115,6 @@ get_initial_defs_for_reduction (slp_tree > stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); > unsigned nunits; > tree vec_cst; > - tree *elts; > unsigned j, number_of_places_left_in_vector; > tree vector_type, scalar_type; > tree vop; > @@ -4195,7 +4198,8 @@ get_initial_defs_for_reduction (slp_tree > > number_of_places_left_in_vector = nunits; > constant_p = true; > - elts = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> elts (nunits); > + elts.quick_grow (nunits); > for (j = 0; j < number_of_copies; j++) > { > for (i = group_size - 1; stmts.iterate (i, &stmt); i--) > @@ -4533,9 +4537,9 @@ vect_create_epilog_for_reduction (vec<tr > vector size (STEP). */ > > /* Create a {1,2,3,...} vector. */ > - tree *vtemp = XALLOCAVEC (tree, nunits_out); > + auto_vec<tree, 32> vtemp (nunits_out); > for (k = 0; k < nunits_out; ++k) > - vtemp[k] = build_int_cst (cr_index_scalar_type, k + 1); > + vtemp.quick_push (build_int_cst (cr_index_scalar_type, k + 1)); > tree series_vect = build_vector (cr_index_vector_type, vtemp); > > /* Create a vector of the step value. */ > @@ -6731,7 +6735,7 @@ vectorizable_induction (gimple *phi, > unsigned ivn; > for (ivn = 0; ivn < nivs; ++ivn) > { > - tree *elts = XALLOCAVEC (tree, nunits); > + auto_vec<tree, 32> elts (nunits); > bool constant_p = true; > for (unsigned eltn = 0; eltn < nunits; ++eltn) > { > @@ -6749,7 +6753,7 @@ vectorizable_induction (gimple *phi, > } > if (! CONSTANT_CLASS_P (elt)) > constant_p = false; > - elts[eltn] = elt; > + elts.quick_push (elt); > } > if (constant_p) > new_vec = build_vector (vectype, elts); > Index: gcc/config/sparc/sparc.c > =================================================================== > --- gcc/config/sparc/sparc.c 2017-09-14 11:23:44.419204251 +0100 > +++ gcc/config/sparc/sparc.c 2017-09-14 11:24:42.664243620 +0100 > @@ -11446,7 +11446,7 @@ sparc_vis_mul8x16 (int e8, int e16) > the result into the array N_ELTS, whose elements are of INNER_TYPE. */ > > static void > -sparc_handle_vis_mul8x16 (tree *n_elts, enum sparc_builtins fncode, > +sparc_handle_vis_mul8x16 (vec<tree> *n_elts, enum sparc_builtins fncode, > tree inner_type, tree cst0, tree cst1) > { > unsigned i, num = VECTOR_CST_NELTS (cst0); > @@ -11460,7 +11460,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, > int val > = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), > TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, i))); > - n_elts[i] = build_int_cst (inner_type, val); > + n_elts->quick_push (build_int_cst (inner_type, val)); > } > break; > > @@ -11472,7 +11472,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, > int val > = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), > scale); > - n_elts[i] = build_int_cst (inner_type, val); > + n_elts->quick_push (build_int_cst (inner_type, val)); > } > break; > > @@ -11484,7 +11484,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, > int val > = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), > scale); > - n_elts[i] = build_int_cst (inner_type, val); > + n_elts->quick_push (build_int_cst (inner_type, val)); > } > break; > > @@ -11533,14 +11533,15 @@ sparc_fold_builtin (tree fndecl, int n_a > if (TREE_CODE (arg0) == VECTOR_CST) > { > tree inner_type = TREE_TYPE (rtype); > - tree *n_elts; > unsigned i; > > - n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); > + auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0)); > for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) > - n_elts[i] = build_int_cst (inner_type, > - TREE_INT_CST_LOW > - (VECTOR_CST_ELT (arg0, i)) << 4); > + { > + unsigned HOST_WIDE_INT val > + = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg0, i)); > + n_elts.quick_push (build_int_cst (inner_type, val << 4)); > + } > return build_vector (rtype, n_elts); > } > break; > @@ -11556,8 +11557,8 @@ sparc_fold_builtin (tree fndecl, int n_a > if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) > { > tree inner_type = TREE_TYPE (rtype); > - tree *n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); > - sparc_handle_vis_mul8x16 (n_elts, code, inner_type, arg0, arg1); > + auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0)); > + sparc_handle_vis_mul8x16 (&n_elts, code, inner_type, arg0, arg1); > return build_vector (rtype, n_elts); > } > break; > @@ -11570,12 +11571,12 @@ sparc_fold_builtin (tree fndecl, int n_a > > if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) > { > - tree *n_elts = XALLOCAVEC (tree, 2 * VECTOR_CST_NELTS (arg0)); > + auto_vec<tree, 32> n_elts (2 * VECTOR_CST_NELTS (arg0)); > unsigned i; > for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) > { > - n_elts[2*i] = VECTOR_CST_ELT (arg0, i); > - n_elts[2*i+1] = VECTOR_CST_ELT (arg1, i); > + n_elts.quick_push (VECTOR_CST_ELT (arg0, i)); > + n_elts.quick_push (VECTOR_CST_ELT (arg1, i)); > } > > return build_vector (rtype, n_elts);
Index: gcc/tree.h =================================================================== --- gcc/tree.h 2017-09-14 11:23:57.004947653 +0100 +++ gcc/tree.h 2017-09-14 11:24:42.669777533 +0100 @@ -4026,7 +4026,7 @@ extern tree build_int_cst (tree, HOST_WI extern tree build_int_cstu (tree type, unsigned HOST_WIDE_INT cst); extern tree build_int_cst_type (tree, HOST_WIDE_INT); extern tree make_vector (unsigned CXX_MEM_STAT_INFO); -extern tree build_vector (tree, tree * CXX_MEM_STAT_INFO); +extern tree build_vector (tree, vec<tree> CXX_MEM_STAT_INFO); extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *); extern tree build_vector_from_val (tree, tree); extern void recompute_constructor_flags (tree); Index: gcc/tree.c =================================================================== --- gcc/tree.c 2017-09-14 11:23:57.004947653 +0100 +++ gcc/tree.c 2017-09-14 11:24:42.669777533 +0100 @@ -1702,18 +1702,20 @@ make_vector (unsigned len MEM_STAT_DECL) } /* Return a new VECTOR_CST node whose type is TYPE and whose values - are in a list pointed to by VALS. */ + are given by VALS. */ tree -build_vector (tree type, tree *vals MEM_STAT_DECL) +build_vector (tree type, vec<tree> vals MEM_STAT_DECL) { + unsigned int nelts = vals.length (); + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type)); int over = 0; unsigned cnt = 0; - tree v = make_vector (TYPE_VECTOR_SUBPARTS (type)); + tree v = make_vector (nelts); TREE_TYPE (v) = type; /* Iterate through elements and check for overflow. */ - for (cnt = 0; cnt < TYPE_VECTOR_SUBPARTS (type); ++cnt) + for (cnt = 0; cnt < nelts; ++cnt) { tree value = vals[cnt]; @@ -1736,20 +1738,21 @@ build_vector (tree type, tree *vals MEM_ tree build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v) { - tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); - unsigned HOST_WIDE_INT idx, pos = 0; + unsigned int nelts = TYPE_VECTOR_SUBPARTS (type); + unsigned HOST_WIDE_INT idx; tree value; + auto_vec<tree, 32> vec (nelts); FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) { if (TREE_CODE (value) == VECTOR_CST) for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i) - vec[pos++] = VECTOR_CST_ELT (value, i); + vec.quick_push (VECTOR_CST_ELT (value, i)); else - vec[pos++] = value; + vec.quick_push (value); } - while (pos < TYPE_VECTOR_SUBPARTS (type)) - vec[pos++] = build_zero_cst (TREE_TYPE (type)); + while (vec.length () < nelts) + vec.quick_push (build_zero_cst (TREE_TYPE (type))); return build_vector (type, vec); } @@ -1774,9 +1777,9 @@ build_vector_from_val (tree vectype, tre if (CONSTANT_CLASS_P (sc)) { - tree *v = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> v (nunits); for (i = 0; i < nunits; ++i) - v[i] = sc; + v.quick_push (sc); return build_vector (vectype, v); } else Index: gcc/gimple-fold.c =================================================================== --- gcc/gimple-fold.c 2017-09-13 18:03:47.077908038 +0100 +++ gcc/gimple-fold.c 2017-09-14 11:24:42.666088258 +0100 @@ -5919,18 +5919,18 @@ gimple_fold_stmt_to_constant_1 (gimple * && (CONSTRUCTOR_NELTS (rhs) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)))) { - unsigned i; - tree val, *vec; + unsigned i, nelts; + tree val; - vec = XALLOCAVEC (tree, - TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))); + nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)); + auto_vec<tree, 32> vec (nelts); FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) { val = (*valueize) (val); if (TREE_CODE (val) == INTEGER_CST || TREE_CODE (val) == REAL_CST || TREE_CODE (val) == FIXED_CST) - vec[i] = val; + vec.quick_push (val); else return NULL_TREE; } Index: gcc/tree-ssa-forwprop.c =================================================================== --- gcc/tree-ssa-forwprop.c 2017-08-21 15:50:48.662709938 +0100 +++ gcc/tree-ssa-forwprop.c 2017-09-14 11:24:42.667010577 +0100 @@ -2051,7 +2051,7 @@ simplify_vector_constructor (gimple_stmt } else { - tree mask_type, *mask_elts; + tree mask_type; if (!can_vec_perm_p (TYPE_MODE (type), false, sel)) return false; @@ -2062,9 +2062,9 @@ simplify_vector_constructor (gimple_stmt || GET_MODE_SIZE (TYPE_MODE (mask_type)) != GET_MODE_SIZE (TYPE_MODE (type))) return false; - mask_elts = XALLOCAVEC (tree, nelts); + auto_vec<tree, 32> mask_elts (nelts); for (i = 0; i < nelts; i++) - mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]); + mask_elts.quick_push (build_int_cst (TREE_TYPE (mask_type), sel[i])); op2 = build_vector (mask_type, mask_elts); if (conv_code == ERROR_MARK) gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2); Index: gcc/tree-vect-generic.c =================================================================== --- gcc/tree-vect-generic.c 2017-09-12 14:24:48.541917623 +0100 +++ gcc/tree-vect-generic.c 2017-09-14 11:24:42.667010577 +0100 @@ -398,9 +398,9 @@ add_rshift (gimple_stmt_iterator *gsi, t if (op != unknown_optab && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing) { - tree *vec = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> vec (nunits); for (i = 0; i < nunits; i++) - vec[i] = build_int_cst (TREE_TYPE (type), shiftcnts[i]); + vec.quick_push (build_int_cst (TREE_TYPE (type), shiftcnts[i])); return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0, build_vector (type, vec)); } @@ -429,7 +429,6 @@ expand_vector_divmod (gimple_stmt_iterat unsigned int i; signop sign_p = TYPE_SIGN (TREE_TYPE (type)); unsigned HOST_WIDE_INT mask = GET_MODE_MASK (TYPE_MODE (TREE_TYPE (type))); - tree *vec; tree cur_op, mulcst, tem; optab op; @@ -593,8 +592,6 @@ expand_vector_divmod (gimple_stmt_iterat mode = -2; } - vec = XALLOCAVEC (tree, nunits); - if (use_pow2) { tree addend = NULL_TREE; @@ -638,10 +635,11 @@ expand_vector_divmod (gimple_stmt_iterat mask_type = build_same_sized_truth_vector_type (type); zero = build_zero_cst (type); cond = build2 (LT_EXPR, mask_type, op0, zero); + auto_vec<tree, 32> vec (nunits); for (i = 0; i < nunits; i++) - vec[i] = build_int_cst (TREE_TYPE (type), - (HOST_WIDE_INT_1U - << shifts[i]) - 1); + vec.quick_push (build_int_cst (TREE_TYPE (type), + (HOST_WIDE_INT_1U + << shifts[i]) - 1)); cst = build_vector (type, vec); addend = make_ssa_name (type); stmt = gimple_build_assign (addend, VEC_COND_EXPR, cond, @@ -676,10 +674,11 @@ expand_vector_divmod (gimple_stmt_iterat else { tree mask; + auto_vec<tree, 32> vec (nunits); for (i = 0; i < nunits; i++) - vec[i] = build_int_cst (TREE_TYPE (type), - (HOST_WIDE_INT_1U - << shifts[i]) - 1); + vec.quick_push (build_int_cst (TREE_TYPE (type), + (HOST_WIDE_INT_1U + << shifts[i]) - 1)); mask = build_vector (type, vec); op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default); if (op != unknown_optab @@ -754,8 +753,9 @@ expand_vector_divmod (gimple_stmt_iterat return NULL_TREE; } + auto_vec<tree, 32> vec (nunits); for (i = 0; i < nunits; i++) - vec[i] = build_int_cst (TREE_TYPE (type), mulc[i]); + vec.quick_push (build_int_cst (TREE_TYPE (type), mulc[i])); mulcst = build_vector (type, vec); cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst); @@ -1066,7 +1066,6 @@ optimize_vector_constructor (gimple_stmt unsigned int i, j, nelts = TYPE_VECTOR_SUBPARTS (type); bool all_same = true; constructor_elt *elt; - tree *cst; gimple *g; tree base = NULL_TREE; optab op; @@ -1105,22 +1104,23 @@ optimize_vector_constructor (gimple_stmt } if (all_same) return; - cst = XALLOCAVEC (tree, nelts); + auto_vec<tree, 32> cst (nelts); for (i = 0; i < nelts; i++) { - tree this_base = CONSTRUCTOR_ELT (rhs, i)->value;; - cst[i] = build_zero_cst (TREE_TYPE (base)); + tree this_base = CONSTRUCTOR_ELT (rhs, i)->value; + tree elt = build_zero_cst (TREE_TYPE (base)); while (this_base != base) { g = SSA_NAME_DEF_STMT (this_base); - cst[i] = fold_binary (PLUS_EXPR, TREE_TYPE (base), - cst[i], gimple_assign_rhs2 (g)); - if (cst[i] == NULL_TREE - || TREE_CODE (cst[i]) != INTEGER_CST - || TREE_OVERFLOW (cst[i])) + elt = fold_binary (PLUS_EXPR, TREE_TYPE (base), + elt, gimple_assign_rhs2 (g)); + if (elt == NULL_TREE + || TREE_CODE (elt) != INTEGER_CST + || TREE_OVERFLOW (elt)) return; this_base = gimple_assign_rhs1 (g); } + cst.quick_push (elt); } for (i = 0; i < nelts; i++) CONSTRUCTOR_ELT (rhs, i)->value = base; Index: gcc/tree-vect-slp.c =================================================================== --- gcc/tree-vect-slp.c 2017-08-30 12:19:19.719220029 +0100 +++ gcc/tree-vect-slp.c 2017-09-14 11:24:42.667932896 +0100 @@ -3105,7 +3105,6 @@ vect_get_constant_vectors (tree op, slp_ stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); unsigned nunits; tree vec_cst; - tree *elts; unsigned j, number_of_places_left_in_vector; tree vector_type; tree vop; @@ -3158,7 +3157,8 @@ vect_get_constant_vectors (tree op, slp_ number_of_places_left_in_vector = nunits; constant_p = true; - elts = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> elts (nunits); + elts.quick_grow (nunits); bool place_after_defs = false; for (j = 0; j < number_of_copies; j++) { @@ -3600,10 +3600,10 @@ vect_transform_slp_perm_load (slp_tree n if (! noop_p) { - tree *mask_elts = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> mask_elts (nunits); for (int l = 0; l < nunits; ++l) - mask_elts[l] = build_int_cst (mask_element_type, - mask[l]); + mask_elts.quick_push (build_int_cst (mask_element_type, + mask[l])); mask_vec = build_vector (mask_type, mask_elts); } @@ -3759,13 +3759,14 @@ vect_schedule_slp_instance (slp_tree nod unsigned k = 0, l; for (j = 0; j < v0.length (); ++j) { - tree *melts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (vectype)); - for (l = 0; l < TYPE_VECTOR_SUBPARTS (vectype); ++l) + unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype); + auto_vec<tree, 32> melts (nunits); + for (l = 0; l < nunits; ++l) { if (k >= group_size) k = 0; - melts[l] = build_int_cst - (meltype, mask[k++] * TYPE_VECTOR_SUBPARTS (vectype) + l); + tree t = build_int_cst (meltype, mask[k++] * nunits + l); + melts.quick_push (t); } tmask = build_vector (mvectype, melts); Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-09-06 20:47:36.983150825 +0100 +++ gcc/tree-vect-stmts.c 2017-09-14 11:24:42.668855214 +0100 @@ -2480,10 +2480,10 @@ vectorizable_bswap (gimple *stmt, gimple if (! char_vectype) return false; - unsigned char *elts - = XALLOCAVEC (unsigned char, TYPE_VECTOR_SUBPARTS (char_vectype)); + unsigned int num_bytes = TYPE_VECTOR_SUBPARTS (char_vectype); + unsigned char *elts = XALLOCAVEC (unsigned char, num_bytes); unsigned char *elt = elts; - unsigned word_bytes = TYPE_VECTOR_SUBPARTS (char_vectype) / nunits; + unsigned word_bytes = num_bytes / nunits; for (unsigned i = 0; i < nunits; ++i) for (unsigned j = 0; j < word_bytes; ++j) *elt++ = (i + 1) * word_bytes - j - 1; @@ -2507,9 +2507,9 @@ vectorizable_bswap (gimple *stmt, gimple return true; } - tree *telts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (char_vectype)); - for (unsigned i = 0; i < TYPE_VECTOR_SUBPARTS (char_vectype); ++i) - telts[i] = build_int_cst (char_type_node, elts[i]); + auto_vec<tree, 32> telts (num_bytes); + for (unsigned i = 0; i < num_bytes; ++i) + telts.quick_push (build_int_cst (char_type_node, elts[i])); tree bswap_vconst = build_vector (char_vectype, telts); /* Transform. */ @@ -2928,10 +2928,10 @@ vectorizable_call (gimple *gs, gimple_st if (gimple_call_internal_p (stmt) && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE) { - tree *v = XALLOCAVEC (tree, nunits_out); - int k; - for (k = 0; k < nunits_out; ++k) - v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k); + auto_vec<tree, 32> v (nunits_out); + for (int k = 0; k < nunits_out; ++k) + v.quick_push (build_int_cst (unsigned_type_node, + j * nunits_out + k)); tree cst = build_vector (vectype_out, v); tree new_var = vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_"); @@ -6505,7 +6505,7 @@ vectorizable_store (gimple *stmt, gimple tree vect_gen_perm_mask_any (tree vectype, const unsigned char *sel) { - tree mask_elt_type, mask_type, mask_vec, *mask_elts; + tree mask_elt_type, mask_type, mask_vec; int i, nunits; nunits = TYPE_VECTOR_SUBPARTS (vectype); @@ -6514,9 +6514,9 @@ vect_gen_perm_mask_any (tree vectype, co (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))).require (), 1); mask_type = get_vectype_for_scalar_type (mask_elt_type); - mask_elts = XALLOCAVEC (tree, nunits); - for (i = nunits - 1; i >= 0; i--) - mask_elts[i] = build_int_cst (mask_elt_type, sel[i]); + auto_vec<tree, 32> mask_elts (nunits); + for (i = 0; i < nunits; ++i) + mask_elts.quick_push (build_int_cst (mask_elt_type, sel[i])); mask_vec = build_vector (mask_type, mask_elts); return mask_vec; Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-09-14 11:23:44.291407202 +0100 +++ gcc/expmed.c 2017-09-14 11:24:42.664243620 +0100 @@ -5180,15 +5180,14 @@ make_tree (tree type, rtx x) { int units = CONST_VECTOR_NUNITS (x); tree itype = TREE_TYPE (type); - tree *elts; int i; /* Build a tree with vector elements. */ - elts = XALLOCAVEC (tree, units); - for (i = units - 1; i >= 0; --i) + auto_vec<tree, 32> elts (units); + for (i = 0; i < units; ++i) { rtx elt = CONST_VECTOR_ELT (x, i); - elts[i] = make_tree (itype, elt); + elts.quick_push (make_tree (itype, elt)); } return build_vector (type, elts); Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c 2017-09-14 11:23:57.004041291 +0100 +++ gcc/fold-const.c 2017-09-14 11:24:42.666088258 +0100 @@ -136,7 +136,6 @@ static tree fold_not_const (const_tree, static tree fold_relational_const (enum tree_code, tree, tree, tree); static tree fold_convert_const (enum tree_code, tree, tree); static tree fold_view_convert_expr (tree, tree); -static bool vec_cst_ctor_to_array (tree, tree *); static tree fold_negate_expr (location_t, tree); @@ -565,13 +564,14 @@ fold_negate_expr_1 (location_t loc, tree case VECTOR_CST: { int count = VECTOR_CST_NELTS (t), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { - elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); - if (elts[i] == NULL_TREE) + tree elt = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1414,19 +1414,20 @@ const_binop (enum tree_code code, tree a { tree type = TREE_TYPE (arg1); int count = VECTOR_CST_NELTS (arg1), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { tree elem1 = VECTOR_CST_ELT (arg1, i); tree elem2 = VECTOR_CST_ELT (arg2, i); - elts[i] = const_binop (code, elem1, elem2); + tree elt = const_binop (code, elem1, elem2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE */ - if (elts[i] == NULL_TREE) + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1438,18 +1439,19 @@ const_binop (enum tree_code code, tree a { tree type = TREE_TYPE (arg1); int count = VECTOR_CST_NELTS (arg1), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { tree elem1 = VECTOR_CST_ELT (arg1, i); - elts[i] = const_binop (code, elem1, arg2); + tree elt = const_binop (code, elem1, arg2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE. */ - if (elts[i] == NULL_TREE) + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1481,7 +1483,6 @@ const_binop (enum tree_code code, tree t case VEC_PACK_TRUNC_EXPR: case VEC_PACK_FIX_TRUNC_EXPR: { - tree *elts; unsigned int out_nelts, in_nelts, i; if (TREE_CODE (arg1) != VECTOR_CST @@ -1493,18 +1494,18 @@ const_binop (enum tree_code code, tree t gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2) && out_nelts == TYPE_VECTOR_SUBPARTS (type)); - elts = XALLOCAVEC (tree, out_nelts); - if (!vec_cst_ctor_to_array (arg1, elts) - || !vec_cst_ctor_to_array (arg2, elts + in_nelts)) - return NULL_TREE; - + auto_vec<tree, 32> elts (out_nelts); for (i = 0; i < out_nelts; i++) { - elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR - ? NOP_EXPR : FIX_TRUNC_EXPR, - TREE_TYPE (type), elts[i]); - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) + tree elt = (i < in_nelts + ? VECTOR_CST_ELT (arg1, i) + : VECTOR_CST_ELT (arg2, i - in_nelts)); + elt = fold_convert_const (code == VEC_PACK_TRUNC_EXPR + ? NOP_EXPR : FIX_TRUNC_EXPR, + TREE_TYPE (type), elt); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1516,7 +1517,6 @@ const_binop (enum tree_code code, tree t case VEC_WIDEN_MULT_ODD_EXPR: { unsigned int out_nelts, in_nelts, out, ofs, scale; - tree *elts; if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST) return NULL_TREE; @@ -1526,11 +1526,6 @@ const_binop (enum tree_code code, tree t gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2) && out_nelts == TYPE_VECTOR_SUBPARTS (type)); - elts = XALLOCAVEC (tree, in_nelts * 2); - if (!vec_cst_ctor_to_array (arg1, elts) - || !vec_cst_ctor_to_array (arg2, elts + in_nelts)) - return NULL_TREE; - if (code == VEC_WIDEN_MULT_LO_EXPR) scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0; else if (code == VEC_WIDEN_MULT_HI_EXPR) @@ -1540,20 +1535,21 @@ const_binop (enum tree_code code, tree t else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */ scale = 1, ofs = 1; + auto_vec<tree, 32> elts (out_nelts); for (out = 0; out < out_nelts; out++) { - unsigned int in1 = (out << scale) + ofs; - unsigned int in2 = in1 + in_nelts; - tree t1, t2; - - t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]); - t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in2]); + unsigned int in = (out << scale) + ofs; + tree t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), + VECTOR_CST_ELT (arg1, in)); + tree t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), + VECTOR_CST_ELT (arg2, in)); if (t1 == NULL_TREE || t2 == NULL_TREE) return NULL_TREE; - elts[out] = const_binop (MULT_EXPR, t1, t2); - if (elts[out] == NULL_TREE || !CONSTANT_CLASS_P (elts[out])) + tree elt = const_binop (MULT_EXPR, t1, t2); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1638,18 +1634,17 @@ const_unop (enum tree_code code, tree ty /* Perform BIT_NOT_EXPR on each element individually. */ else if (TREE_CODE (arg0) == VECTOR_CST) { - tree *elements; tree elem; unsigned count = VECTOR_CST_NELTS (arg0), i; - elements = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elements (count); for (i = 0; i < count; i++) { elem = VECTOR_CST_ELT (arg0, i); elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem); if (elem == NULL_TREE) break; - elements[i] = elem; + elements.quick_push (elem); } if (i == count) return build_vector (type, elements); @@ -1677,7 +1672,6 @@ const_unop (enum tree_code code, tree ty case VEC_UNPACK_FLOAT_HI_EXPR: { unsigned int out_nelts, in_nelts, i; - tree *elts; enum tree_code subcode; if (TREE_CODE (arg0) != VECTOR_CST) @@ -1687,24 +1681,24 @@ const_unop (enum tree_code code, tree ty out_nelts = in_nelts / 2; gcc_assert (out_nelts == TYPE_VECTOR_SUBPARTS (type)); - elts = XALLOCAVEC (tree, in_nelts); - if (!vec_cst_ctor_to_array (arg0, elts)) - return NULL_TREE; - + unsigned int offset = 0; if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_FLOAT_LO_EXPR)) - elts += out_nelts; + offset = out_nelts; if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR) subcode = NOP_EXPR; else subcode = FLOAT_EXPR; + auto_vec<tree, 32> elts (out_nelts); for (i = 0; i < out_nelts; i++) { - elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]); - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) + tree elt = fold_convert_const (subcode, TREE_TYPE (type), + VECTOR_CST_ELT (arg0, i + offset)); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1715,17 +1709,12 @@ const_unop (enum tree_code code, tree ty case REDUC_PLUS_EXPR: { unsigned int nelts, i; - tree *elts; enum tree_code subcode; if (TREE_CODE (arg0) != VECTOR_CST) return NULL_TREE; nelts = VECTOR_CST_NELTS (arg0); - elts = XALLOCAVEC (tree, nelts); - if (!vec_cst_ctor_to_array (arg0, elts)) - return NULL_TREE; - switch (code) { case REDUC_MIN_EXPR: subcode = MIN_EXPR; break; @@ -1734,14 +1723,15 @@ const_unop (enum tree_code code, tree ty default: gcc_unreachable (); } + tree res = VECTOR_CST_ELT (arg0, 0); for (i = 1; i < nelts; i++) { - elts[0] = const_binop (subcode, elts[0], elts[i]); - if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0])) + res = const_binop (subcode, res, VECTOR_CST_ELT (arg0, i)); + if (res == NULL_TREE || !CONSTANT_CLASS_P (res)) return NULL_TREE; } - return elts[0]; + return res; } default: @@ -2163,14 +2153,14 @@ fold_convert_const (enum tree_code code, { int len = VECTOR_CST_NELTS (arg1); tree elttype = TREE_TYPE (type); - tree *v = XALLOCAVEC (tree, len); + auto_vec<tree, 32> v (len); for (int i = 0; i < len; ++i) { tree elt = VECTOR_CST_ELT (arg1, i); tree cvt = fold_convert_const (code, elttype, elt); if (cvt == NULL_TREE) return NULL_TREE; - v[i] = cvt; + v.quick_push (cvt); } return build_vector (type, v); } @@ -7392,7 +7382,6 @@ native_interpret_vector (tree type, cons { tree etype, elem; int i, size, count; - tree *elements; etype = TREE_TYPE (type); size = GET_MODE_SIZE (SCALAR_TYPE_MODE (etype)); @@ -7400,13 +7389,13 @@ native_interpret_vector (tree type, cons if (size * count > len) return NULL_TREE; - elements = XALLOCAVEC (tree, count); - for (i = count - 1; i >= 0; i--) + auto_vec<tree, 32> elements (count); + for (i = 0; i < count; ++i) { elem = native_interpret_expr (etype, ptr+(i*size), size); if (!elem) return NULL_TREE; - elements[i] = elem; + elements.quick_push (elem); } return build_vector (type, elements); } @@ -8761,12 +8750,13 @@ fold_mult_zconjz (location_t loc, tree t /* Helper function for fold_vec_perm. Store elements of VECTOR_CST or - CONSTRUCTOR ARG into array ELTS and return true if successful. */ + CONSTRUCTOR ARG into array ELTS, which has NELTS elements, and return + true if successful. */ static bool -vec_cst_ctor_to_array (tree arg, tree *elts) +vec_cst_ctor_to_array (tree arg, unsigned int nelts, tree *elts) { - unsigned int nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)), i; + unsigned int i; if (TREE_CODE (arg) == VECTOR_CST) { @@ -8799,7 +8789,6 @@ vec_cst_ctor_to_array (tree arg, tree *e fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) { unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts; bool need_ctor = false; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts @@ -8808,16 +8797,17 @@ fold_vec_perm (tree type, tree arg0, tre || TREE_TYPE (TREE_TYPE (arg1)) != TREE_TYPE (type)) return NULL_TREE; - elts = XALLOCAVEC (tree, nelts * 3); - if (!vec_cst_ctor_to_array (arg0, elts) - || !vec_cst_ctor_to_array (arg1, elts + nelts)) + tree *in_elts = XALLOCAVEC (tree, nelts * 2); + if (!vec_cst_ctor_to_array (arg0, nelts, in_elts) + || !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts)) return NULL_TREE; + auto_vec<tree, 32> out_elts (nelts); for (i = 0; i < nelts; i++) { - if (!CONSTANT_CLASS_P (elts[sel[i]])) + if (!CONSTANT_CLASS_P (in_elts[sel[i]])) need_ctor = true; - elts[i + 2 * nelts] = unshare_expr (elts[sel[i]]); + out_elts.quick_push (unshare_expr (in_elts[sel[i]])); } if (need_ctor) @@ -8825,11 +8815,11 @@ fold_vec_perm (tree type, tree arg0, tre vec<constructor_elt, va_gc> *v; vec_alloc (v, nelts); for (i = 0; i < nelts; i++) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[2 * nelts + i]); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, out_elts[i]); return build_constructor (type, v); } else - return build_vector (type, &elts[2 * nelts]); + return build_vector (type, out_elts); } /* Try to fold a pointer difference of type TYPE two address expressions of @@ -8879,7 +8869,7 @@ fold_addr_of_array_ref_difference (locat exact_inverse (tree type, tree cst) { REAL_VALUE_TYPE r; - tree unit_type, *elts; + tree unit_type; machine_mode mode; unsigned vec_nelts, i; @@ -8894,20 +8884,22 @@ exact_inverse (tree type, tree cst) return NULL_TREE; case VECTOR_CST: - vec_nelts = VECTOR_CST_NELTS (cst); - elts = XALLOCAVEC (tree, vec_nelts); - unit_type = TREE_TYPE (type); - mode = TYPE_MODE (unit_type); + { + vec_nelts = VECTOR_CST_NELTS (cst); + unit_type = TREE_TYPE (type); + mode = TYPE_MODE (unit_type); - for (i = 0; i < vec_nelts; i++) - { - r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); - if (!exact_real_inverse (mode, &r)) - return NULL_TREE; - elts[i] = build_real (unit_type, r); - } + auto_vec<tree, 32> elts (vec_nelts); + for (i = 0; i < vec_nelts; i++) + { + r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); + if (!exact_real_inverse (mode, &r)) + return NULL_TREE; + elts.quick_push (build_real (unit_type, r)); + } - return build_vector (type, elts); + return build_vector (type, elts); + } default: return NULL_TREE; @@ -11596,9 +11588,9 @@ fold_ternary_loc (location_t loc, enum t if (n == 1) return VECTOR_CST_ELT (arg0, idx); - tree *vals = XALLOCAVEC (tree, n); + auto_vec<tree, 32> vals (n); for (unsigned i = 0; i < n; ++i) - vals[i] = VECTOR_CST_ELT (arg0, idx + i); + vals.quick_push (VECTOR_CST_ELT (arg0, idx + i)); return build_vector (type, vals); } } @@ -11731,10 +11723,10 @@ fold_ternary_loc (location_t loc, enum t if (need_mask_canon && arg2 == op2) { - tree *tsel = XALLOCAVEC (tree, nelts); tree eltype = TREE_TYPE (TREE_TYPE (arg2)); + auto_vec<tree, 32> tsel (nelts); for (i = 0; i < nelts; i++) - tsel[i] = build_int_cst (eltype, sel[i]); + tsel.quick_push (build_int_cst (eltype, sel[i])); op2 = build_vector (TREE_TYPE (arg2), tsel); changed = true; } @@ -11775,8 +11767,10 @@ fold_ternary_loc (location_t loc, enum t else { unsigned int nelts = VECTOR_CST_NELTS (arg0); - tree *elts = XALLOCAVEC (tree, nelts); - memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts); + auto_vec<tree, 32> elts (nelts); + elts.quick_grow (nelts); + memcpy (&elts[0], VECTOR_CST_ELTS (arg0), + sizeof (tree) * nelts); elts[k] = arg1; return build_vector (type, elts); } @@ -13894,10 +13888,10 @@ fold_relational_const (enum tree_code co return constant_boolean_node (true, type); } unsigned count = VECTOR_CST_NELTS (op0); - tree *elts = XALLOCAVEC (tree, count); gcc_assert (VECTOR_CST_NELTS (op1) == count && TYPE_VECTOR_SUBPARTS (type) == count); + auto_vec<tree, 32> elts (count); for (unsigned i = 0; i < count; i++) { tree elem_type = TREE_TYPE (type); @@ -13910,7 +13904,8 @@ fold_relational_const (enum tree_code co if (tem == NULL_TREE) return NULL_TREE; - elts[i] = build_int_cst (elem_type, integer_zerop (tem) ? 0 : -1); + elts.quick_push (build_int_cst (elem_type, + integer_zerop (tem) ? 0 : -1)); } return build_vector (type, elts); Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c 2017-08-30 12:19:19.718220029 +0100 +++ gcc/tree-vect-loop.c 2017-09-14 11:24:42.667932896 +0100 @@ -3969,7 +3969,6 @@ get_initial_def_for_reduction (gimple *s enum tree_code code = gimple_assign_rhs_code (stmt); tree def_for_init; tree init_def; - tree *elts; int i; bool nested_in_vect_loop = false; REAL_VALUE_TYPE real_init_val = dconst0; @@ -4015,15 +4014,16 @@ get_initial_def_for_reduction (gimple *s switch (code) { - case WIDEN_SUM_EXPR: - case DOT_PROD_EXPR: - case SAD_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case MULT_EXPR: - case BIT_AND_EXPR: + case WIDEN_SUM_EXPR: + case DOT_PROD_EXPR: + case SAD_EXPR: + case PLUS_EXPR: + case MINUS_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + case MULT_EXPR: + case BIT_AND_EXPR: + { /* ADJUSMENT_DEF is NULL when called from vect_create_epilog_for_reduction to vectorize double reduction. */ if (adjustment_def) @@ -4044,17 +4044,19 @@ get_initial_def_for_reduction (gimple *s def_for_init = build_int_cst (scalar_type, int_init_val); /* Create a vector of '0' or '1' except the first element. */ - elts = XALLOCAVEC (tree, nunits); + 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) - { + if (adjustment_def) + { elts[0] = def_for_init; - init_def = build_vector (vectype, elts); - break; - } + + init_def = build_vector (vectype, elts); + break; + } /* Option2: the first element is INIT_VAL. */ elts[0] = init_val; @@ -4069,12 +4071,13 @@ get_initial_def_for_reduction (gimple *s CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); init_def = build_constructor (vectype, v); } + } + break; - break; - - case MIN_EXPR: - case MAX_EXPR: - case COND_EXPR: + case MIN_EXPR: + case MAX_EXPR: + case COND_EXPR: + { if (adjustment_def) { *adjustment_def = NULL_TREE; @@ -4088,10 +4091,11 @@ get_initial_def_for_reduction (gimple *s 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); - break; + } + break; - default: - gcc_unreachable (); + default: + gcc_unreachable (); } return init_def; @@ -4111,7 +4115,6 @@ get_initial_defs_for_reduction (slp_tree stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); unsigned nunits; tree vec_cst; - tree *elts; unsigned j, number_of_places_left_in_vector; tree vector_type, scalar_type; tree vop; @@ -4195,7 +4198,8 @@ get_initial_defs_for_reduction (slp_tree number_of_places_left_in_vector = nunits; constant_p = true; - elts = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> elts (nunits); + elts.quick_grow (nunits); for (j = 0; j < number_of_copies; j++) { for (i = group_size - 1; stmts.iterate (i, &stmt); i--) @@ -4533,9 +4537,9 @@ vect_create_epilog_for_reduction (vec<tr vector size (STEP). */ /* Create a {1,2,3,...} vector. */ - tree *vtemp = XALLOCAVEC (tree, nunits_out); + auto_vec<tree, 32> vtemp (nunits_out); for (k = 0; k < nunits_out; ++k) - vtemp[k] = build_int_cst (cr_index_scalar_type, k + 1); + vtemp.quick_push (build_int_cst (cr_index_scalar_type, k + 1)); tree series_vect = build_vector (cr_index_vector_type, vtemp); /* Create a vector of the step value. */ @@ -6731,7 +6735,7 @@ vectorizable_induction (gimple *phi, unsigned ivn; for (ivn = 0; ivn < nivs; ++ivn) { - tree *elts = XALLOCAVEC (tree, nunits); + auto_vec<tree, 32> elts (nunits); bool constant_p = true; for (unsigned eltn = 0; eltn < nunits; ++eltn) { @@ -6749,7 +6753,7 @@ vectorizable_induction (gimple *phi, } if (! CONSTANT_CLASS_P (elt)) constant_p = false; - elts[eltn] = elt; + elts.quick_push (elt); } if (constant_p) new_vec = build_vector (vectype, elts); Index: gcc/config/sparc/sparc.c =================================================================== --- gcc/config/sparc/sparc.c 2017-09-14 11:23:44.419204251 +0100 +++ gcc/config/sparc/sparc.c 2017-09-14 11:24:42.664243620 +0100 @@ -11446,7 +11446,7 @@ sparc_vis_mul8x16 (int e8, int e16) the result into the array N_ELTS, whose elements are of INNER_TYPE. */ static void -sparc_handle_vis_mul8x16 (tree *n_elts, enum sparc_builtins fncode, +sparc_handle_vis_mul8x16 (vec<tree> *n_elts, enum sparc_builtins fncode, tree inner_type, tree cst0, tree cst1) { unsigned i, num = VECTOR_CST_NELTS (cst0); @@ -11460,7 +11460,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int val = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, i))); - n_elts[i] = build_int_cst (inner_type, val); + n_elts->quick_push (build_int_cst (inner_type, val)); } break; @@ -11472,7 +11472,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int val = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), scale); - n_elts[i] = build_int_cst (inner_type, val); + n_elts->quick_push (build_int_cst (inner_type, val)); } break; @@ -11484,7 +11484,7 @@ sparc_handle_vis_mul8x16 (tree *n_elts, int val = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), scale); - n_elts[i] = build_int_cst (inner_type, val); + n_elts->quick_push (build_int_cst (inner_type, val)); } break; @@ -11533,14 +11533,15 @@ sparc_fold_builtin (tree fndecl, int n_a if (TREE_CODE (arg0) == VECTOR_CST) { tree inner_type = TREE_TYPE (rtype); - tree *n_elts; unsigned i; - n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); + auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0)); for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) - n_elts[i] = build_int_cst (inner_type, - TREE_INT_CST_LOW - (VECTOR_CST_ELT (arg0, i)) << 4); + { + unsigned HOST_WIDE_INT val + = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg0, i)); + n_elts.quick_push (build_int_cst (inner_type, val << 4)); + } return build_vector (rtype, n_elts); } break; @@ -11556,8 +11557,8 @@ sparc_fold_builtin (tree fndecl, int n_a if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) { tree inner_type = TREE_TYPE (rtype); - tree *n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); - sparc_handle_vis_mul8x16 (n_elts, code, inner_type, arg0, arg1); + auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0)); + sparc_handle_vis_mul8x16 (&n_elts, code, inner_type, arg0, arg1); return build_vector (rtype, n_elts); } break; @@ -11570,12 +11571,12 @@ sparc_fold_builtin (tree fndecl, int n_a if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) { - tree *n_elts = XALLOCAVEC (tree, 2 * VECTOR_CST_NELTS (arg0)); + auto_vec<tree, 32> n_elts (2 * VECTOR_CST_NELTS (arg0)); unsigned i; for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) { - n_elts[2*i] = VECTOR_CST_ELT (arg0, i); - n_elts[2*i+1] = VECTOR_CST_ELT (arg1, i); + n_elts.quick_push (VECTOR_CST_ELT (arg0, i)); + n_elts.quick_push (VECTOR_CST_ELT (arg1, i)); } return build_vector (rtype, n_elts);