On Thu, Sep 14, 2017 at 1:14 PM, Richard Sandiford
<richard.sandif...@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.sandif...@linaro.org>
>             Alan Hayward  <alan.hayw...@arm.com>
>             David Sherwood  <david.sherw...@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);

Reply via email to