Make gimple_build_vector take a tree_vector_builder

Message ID 87vahj98uk.fsf_-_@linaro.org
State New
Headers show
Series
  • Make gimple_build_vector take a tree_vector_builder
Related show

Commit Message

Richard Sandiford Dec. 6, 2017, 3:25 p.m.
This patch changes gimple_build_vector so that it takes a
tree_vector_builder instead of a size and a vector of trees.

Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
Also spot-checked on sparc64-linux-gnu.  OK to install?

Thanks,
Richard


2017-12-06  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* vector-builder.h (vector_builder::derived): New const overload.
	(vector_builder::elt): New function.
	* tree-vector-builder.h (tree_vector_builder::type): New function.
	(tree_vector_builder::apply_step): Declare.
	* tree-vector-builder.c (tree_vector_builder::apply_step): New
	function.
	* gimple-fold.h (tree_vector_builder): Declare.
	(gimple_build_vector): Take a tree_vector_builder instead of a
	type and vector of elements.
	* gimple-fold.c (gimple_build_vector): Likewise.
	* tree-vect-loop.c (get_initial_def_for_reduction): Update call
	accordingly.
	(get_initial_defs_for_reduction): Likewise.
	(vectorizable_induction): Likewise.

Comments

Richard Biener Dec. 7, 2017, 11:08 a.m. | #1
On Wed, Dec 6, 2017 at 4:25 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> This patch changes gimple_build_vector so that it takes a

> tree_vector_builder instead of a size and a vector of trees.

>

> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.

> Also spot-checked on sparc64-linux-gnu.  OK to install?


Ok.

Richard.

> Thanks,

> Richard

>

>

> 2017-12-06  Richard Sandiford  <richard.sandiford@linaro.org>

>

> gcc/

>         * vector-builder.h (vector_builder::derived): New const overload.

>         (vector_builder::elt): New function.

>         * tree-vector-builder.h (tree_vector_builder::type): New function.

>         (tree_vector_builder::apply_step): Declare.

>         * tree-vector-builder.c (tree_vector_builder::apply_step): New

>         function.

>         * gimple-fold.h (tree_vector_builder): Declare.

>         (gimple_build_vector): Take a tree_vector_builder instead of a

>         type and vector of elements.

>         * gimple-fold.c (gimple_build_vector): Likewise.

>         * tree-vect-loop.c (get_initial_def_for_reduction): Update call

>         accordingly.

>         (get_initial_defs_for_reduction): Likewise.

>         (vectorizable_induction): Likewise.

>

> Index: gcc/vector-builder.h

> ===================================================================

> --- gcc/vector-builder.h        2017-12-06 14:46:14.133599820 +0000

> +++ gcc/vector-builder.h        2017-12-06 14:49:04.289693414 +0000

> @@ -68,6 +68,10 @@ #define GCC_VECTOR_BUILDER_H

>           given integral_p (ELT1) && integral_p (ELT2).  There is no fixed

>           choice of StepType.

>

> +      T apply_step (T base, unsigned int factor, StepType step) const;

> +

> +         Return a vector element with the value BASE + FACTOR * STEP.

> +

>        bool can_elide_p (T elt) const;

>

>           Return true if we can drop element ELT, even if the retained

> @@ -91,6 +95,7 @@ #define GCC_VECTOR_BUILDER_H

>    unsigned int nelts_per_pattern () const { return m_nelts_per_pattern; }

>    unsigned int encoded_nelts () const;

>    bool encoded_full_vector_p () const;

> +  T elt (unsigned int) const;

>

>    void finalize ();

>

> @@ -163,6 +168,38 @@ vector_builder<T, Derived>::new_vector (

>    this->truncate (0);

>  }

>

> +/* Return the value of vector element I, which might or might not be

> +   encoded explicitly.  */

> +

> +template<typename T, typename Derived>

> +T

> +vector_builder<T, Derived>::elt (unsigned int i) const

> +{

> +  /* This only makes sense if the encoding has been fully populated.  */

> +  gcc_checking_assert (encoded_nelts () <= this->length ());

> +

> +  /* First handle elements that are already present in the underlying

> +     vector, regardless of whether they're part of the encoding or not.  */

> +  if (i < this->length ())

> +    return (*this)[i];

> +

> +  /* Identify the pattern that contains element I and work out the index of

> +     the last encoded element for that pattern.  */

> +  unsigned int pattern = i % m_npatterns;

> +  unsigned int count = i / m_npatterns;

> +  unsigned int final_i = encoded_nelts () - m_npatterns + pattern;

> +  T final = (*this)[final_i];

> +

> +  /* If there are no steps, the final encoded value is the right one.  */

> +  if (m_nelts_per_pattern <= 2)

> +    return final;

> +

> +  /* Otherwise work out the value from the last two encoded elements.  */

> +  T prev = (*this)[final_i - m_npatterns];

> +  return derived ()->apply_step (final, count - 2,

> +                                derived ()->step (prev, final));

> +}

> +

>  /* Change the encoding to NPATTERNS patterns of NELTS_PER_PATTERN each,

>     but without changing the underlying vector.  */

>

> Index: gcc/tree-vector-builder.h

> ===================================================================

> --- gcc/tree-vector-builder.h   2017-12-06 14:49:00.386854068 +0000

> +++ gcc/tree-vector-builder.h   2017-12-06 14:49:04.289693414 +0000

> @@ -45,6 +45,7 @@ #define GCC_TREE_VECTOR_BUILDER_H

>    bool allow_steps_p () const;

>    bool integral_p (const_tree) const;

>    wide_int step (const_tree, const_tree) const;

> +  tree apply_step (tree, unsigned int, const wide_int &) const;

>    bool can_elide_p (const_tree) const;

>    void note_representative (tree *, tree);

>

> Index: gcc/tree-vector-builder.c

> ===================================================================

> --- gcc/tree-vector-builder.c   2017-12-06 14:49:00.386854068 +0000

> +++ gcc/tree-vector-builder.c   2017-12-06 14:49:04.289693414 +0000

> @@ -96,6 +96,16 @@ tree_vector_builder::new_binary_operatio

>    return true;

>  }

>

> +/* Return a vector element with the value BASE + FACTOR * STEP.  */

> +

> +tree

> +tree_vector_builder::apply_step (tree base, unsigned int factor,

> +                                const wide_int &step) const

> +{

> +  return wide_int_to_tree (TREE_TYPE (base),

> +                          wi::to_wide (base) + factor * step);

> +}

> +

>  /* Return a VECTOR_CST for the current constant.  */

>

>  tree

> Index: gcc/gimple-fold.h

> ===================================================================

> --- gcc/gimple-fold.h   2017-11-29 11:06:33.003002371 +0000

> +++ gcc/gimple-fold.h   2017-12-06 14:49:04.288693455 +0000

> @@ -135,11 +135,13 @@ gimple_build_vector_from_val (gimple_seq

>    return gimple_build_vector_from_val (seq, UNKNOWN_LOCATION, type, op);

>  }

>

> -extern tree gimple_build_vector (gimple_seq *, location_t, tree, vec<tree>);

> +class tree_vector_builder;

> +extern tree gimple_build_vector (gimple_seq *, location_t,

> +                                tree_vector_builder *);

>  inline tree

> -gimple_build_vector (gimple_seq *seq, tree type, vec<tree> elts)

> +gimple_build_vector (gimple_seq *seq, tree_vector_builder *builder)

>  {

> -  return gimple_build_vector (seq, UNKNOWN_LOCATION, type, elts);

> +  return gimple_build_vector (seq, UNKNOWN_LOCATION, builder);

>  }

>

>  extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);

> Index: gcc/gimple-fold.c

> ===================================================================

> --- gcc/gimple-fold.c   2017-12-06 14:48:52.888162175 +0000

> +++ gcc/gimple-fold.c   2017-12-06 14:49:04.288693455 +0000

> @@ -7178,23 +7178,30 @@ gimple_build_vector_from_val (gimple_seq

>    return res;

>  }

>

> -/* Build a vector of type TYPE in which the elements have the values

> -   given by ELTS.  Return a gimple value for the result, appending any

> -   new instructions to SEQ.  */

> +/* Build a vector from BUILDER, handling the case in which some elements

> +   are non-constant.  Return a gimple value for the result, appending any

> +   new instructions to SEQ.

> +

> +   BUILDER must not have a stepped encoding on entry.  This is because

> +   the function is not geared up to handle the arithmetic that would

> +   be needed in the variable case, and any code building a vector that

> +   is known to be constant should use BUILDER->build () directly.  */

>

>  tree

> -gimple_build_vector (gimple_seq *seq, location_t loc, tree type,

> -                    vec<tree> elts)

> +gimple_build_vector (gimple_seq *seq, location_t loc,

> +                    tree_vector_builder *builder)

>  {

> -  unsigned int nelts = elts.length ();

> -  gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));

> -  for (unsigned int i = 0; i < nelts; ++i)

> -    if (!TREE_CONSTANT (elts[i]))

> +  gcc_assert (builder->nelts_per_pattern () <= 2);

> +  unsigned int encoded_nelts = builder->encoded_nelts ();

> +  for (unsigned int i = 0; i < encoded_nelts; ++i)

> +    if (!TREE_CONSTANT ((*builder)[i]))

>        {

> +       tree type = builder->type ();

> +       unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);

>         vec<constructor_elt, va_gc> *v;

>         vec_alloc (v, nelts);

>         for (i = 0; i < nelts; ++i)

> -         CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]);

> +         CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));

>

>         tree res;

>         if (gimple_in_ssa_p (cfun))

> @@ -7206,7 +7213,7 @@ gimple_build_vector (gimple_seq *seq, lo

>         gimple_seq_add_stmt_without_update (seq, stmt);

>         return res;

>        }

> -  return build_vector (type, elts);

> +  return builder->build ();

>  }

>

>  /* Return true if the result of assignment STMT is known to be non-negative.

> Index: gcc/tree-vect-loop.c

> ===================================================================

> --- gcc/tree-vect-loop.c        2017-12-06 14:48:52.889162134 +0000

> +++ gcc/tree-vect-loop.c        2017-12-06 14:49:04.289693414 +0000

> @@ -3968,11 +3968,9 @@ get_initial_def_for_reduction (gimple *s

>    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);

>    tree scalar_type = TREE_TYPE (init_val);

>    tree vectype = get_vectype_for_scalar_type (scalar_type);

> -  int nunits;

>    enum tree_code code = gimple_assign_rhs_code (stmt);

>    tree def_for_init;

>    tree init_def;

> -  int i;

>    bool nested_in_vect_loop = false;

>    REAL_VALUE_TYPE real_init_val = dconst0;

>    int int_init_val = 0;

> @@ -3980,7 +3978,6 @@ get_initial_def_for_reduction (gimple *s

>    gimple_seq stmts = NULL;

>

>    gcc_assert (vectype);

> -  nunits = TYPE_VECTOR_SUBPARTS (vectype);

>

>    gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type)

>               || SCALAR_FLOAT_TYPE_P (scalar_type));

> @@ -4053,11 +4050,10 @@ get_initial_def_for_reduction (gimple *s

>         else

>           {

>             /* Option2: the first element is INIT_VAL.  */

> -           auto_vec<tree, 32> elts (nunits);

> +           tree_vector_builder elts (vectype, 1, 2);

>             elts.quick_push (init_val);

> -           for (i = 1; i < nunits; ++i)

> -             elts.quick_push (def_for_init);

> -           init_def = gimple_build_vector (&stmts, vectype, elts);

> +           elts.quick_push (def_for_init);

> +           init_def = gimple_build_vector (&stmts, &elts);

>           }

>        }

>        break;

> @@ -4182,7 +4178,7 @@ get_initial_defs_for_reduction (slp_tree

>    number_of_copies = nunits * number_of_vectors / group_size;

>

>    number_of_places_left_in_vector = nunits;

> -  auto_vec<tree, 32> elts (nunits);

> +  tree_vector_builder elts (vector_type, nunits, 1);

>    elts.quick_grow (nunits);

>    for (j = 0; j < number_of_copies; j++)

>      {

> @@ -4205,12 +4201,14 @@ get_initial_defs_for_reduction (slp_tree

>            if (number_of_places_left_in_vector == 0)

>              {

>               gimple_seq ctor_seq = NULL;

> -             tree init = gimple_build_vector (&ctor_seq, vector_type, elts);

> +             tree init = gimple_build_vector (&ctor_seq, &elts);

>               if (ctor_seq != NULL)

>                 gsi_insert_seq_on_edge_immediate (pe, ctor_seq);

>               voprnds.quick_push (init);

>

>                number_of_places_left_in_vector = nunits;

> +             elts.new_vector (vector_type, nunits, 1);

> +             elts.quick_grow (nunits);

>              }

>          }

>      }

> @@ -6698,7 +6696,7 @@ vectorizable_induction (gimple *phi,

>        unsigned ivn;

>        for (ivn = 0; ivn < nivs; ++ivn)

>         {

> -         auto_vec<tree, 32> elts (nunits);

> +         tree_vector_builder elts (vectype, nunits, 1);

>           stmts = NULL;

>           for (unsigned eltn = 0; eltn < nunits; ++eltn)

>             {

> @@ -6708,7 +6706,7 @@ vectorizable_induction (gimple *phi,

>                                     elt, step_expr);

>               elts.quick_push (elt);

>             }

> -         vec_init = gimple_build_vector (&stmts, vectype, elts);

> +         vec_init = gimple_build_vector (&stmts, &elts);

>           if (stmts)

>             {

>               new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);

> @@ -6815,7 +6813,7 @@ vectorizable_induction (gimple *phi,

>        stmts = NULL;

>        new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);

>

> -      auto_vec<tree, 32> elts (nunits);

> +      tree_vector_builder elts (vectype, nunits, 1);

>        elts.quick_push (new_name);

>        for (i = 1; i < nunits; i++)

>         {

> @@ -6826,7 +6824,7 @@ vectorizable_induction (gimple *phi,

>         }

>        /* Create a vector from [new_name_0, new_name_1, ...,

>          new_name_nunits-1]  */

> -      vec_init = gimple_build_vector (&stmts, vectype, elts);

> +      vec_init = gimple_build_vector (&stmts, &elts);

>        if (stmts)

>         {

>           new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);

Patch

Index: gcc/vector-builder.h
===================================================================
--- gcc/vector-builder.h	2017-12-06 14:46:14.133599820 +0000
+++ gcc/vector-builder.h	2017-12-06 14:49:04.289693414 +0000
@@ -68,6 +68,10 @@  #define GCC_VECTOR_BUILDER_H
 	  given integral_p (ELT1) && integral_p (ELT2).  There is no fixed
 	  choice of StepType.
 
+      T apply_step (T base, unsigned int factor, StepType step) const;
+
+	  Return a vector element with the value BASE + FACTOR * STEP.
+
       bool can_elide_p (T elt) const;
 
 	  Return true if we can drop element ELT, even if the retained
@@ -91,6 +95,7 @@  #define GCC_VECTOR_BUILDER_H
   unsigned int nelts_per_pattern () const { return m_nelts_per_pattern; }
   unsigned int encoded_nelts () const;
   bool encoded_full_vector_p () const;
+  T elt (unsigned int) const;
 
   void finalize ();
 
@@ -163,6 +168,38 @@  vector_builder<T, Derived>::new_vector (
   this->truncate (0);
 }
 
+/* Return the value of vector element I, which might or might not be
+   encoded explicitly.  */
+
+template<typename T, typename Derived>
+T
+vector_builder<T, Derived>::elt (unsigned int i) const
+{
+  /* This only makes sense if the encoding has been fully populated.  */
+  gcc_checking_assert (encoded_nelts () <= this->length ());
+
+  /* First handle elements that are already present in the underlying
+     vector, regardless of whether they're part of the encoding or not.  */
+  if (i < this->length ())
+    return (*this)[i];
+
+  /* Identify the pattern that contains element I and work out the index of
+     the last encoded element for that pattern.  */
+  unsigned int pattern = i % m_npatterns;
+  unsigned int count = i / m_npatterns;
+  unsigned int final_i = encoded_nelts () - m_npatterns + pattern;
+  T final = (*this)[final_i];
+
+  /* If there are no steps, the final encoded value is the right one.  */
+  if (m_nelts_per_pattern <= 2)
+    return final;
+
+  /* Otherwise work out the value from the last two encoded elements.  */
+  T prev = (*this)[final_i - m_npatterns];
+  return derived ()->apply_step (final, count - 2,
+				 derived ()->step (prev, final));
+}
+
 /* Change the encoding to NPATTERNS patterns of NELTS_PER_PATTERN each,
    but without changing the underlying vector.  */
 
Index: gcc/tree-vector-builder.h
===================================================================
--- gcc/tree-vector-builder.h	2017-12-06 14:49:00.386854068 +0000
+++ gcc/tree-vector-builder.h	2017-12-06 14:49:04.289693414 +0000
@@ -45,6 +45,7 @@  #define GCC_TREE_VECTOR_BUILDER_H
   bool allow_steps_p () const;
   bool integral_p (const_tree) const;
   wide_int step (const_tree, const_tree) const;
+  tree apply_step (tree, unsigned int, const wide_int &) const;
   bool can_elide_p (const_tree) const;
   void note_representative (tree *, tree);
 
Index: gcc/tree-vector-builder.c
===================================================================
--- gcc/tree-vector-builder.c	2017-12-06 14:49:00.386854068 +0000
+++ gcc/tree-vector-builder.c	2017-12-06 14:49:04.289693414 +0000
@@ -96,6 +96,16 @@  tree_vector_builder::new_binary_operatio
   return true;
 }
 
+/* Return a vector element with the value BASE + FACTOR * STEP.  */
+
+tree
+tree_vector_builder::apply_step (tree base, unsigned int factor,
+				 const wide_int &step) const
+{
+  return wide_int_to_tree (TREE_TYPE (base),
+			   wi::to_wide (base) + factor * step);
+}
+
 /* Return a VECTOR_CST for the current constant.  */
 
 tree
Index: gcc/gimple-fold.h
===================================================================
--- gcc/gimple-fold.h	2017-11-29 11:06:33.003002371 +0000
+++ gcc/gimple-fold.h	2017-12-06 14:49:04.288693455 +0000
@@ -135,11 +135,13 @@  gimple_build_vector_from_val (gimple_seq
   return gimple_build_vector_from_val (seq, UNKNOWN_LOCATION, type, op);
 }
 
-extern tree gimple_build_vector (gimple_seq *, location_t, tree, vec<tree>);
+class tree_vector_builder;
+extern tree gimple_build_vector (gimple_seq *, location_t,
+				 tree_vector_builder *);
 inline tree
-gimple_build_vector (gimple_seq *seq, tree type, vec<tree> elts)
+gimple_build_vector (gimple_seq *seq, tree_vector_builder *builder)
 {
-  return gimple_build_vector (seq, UNKNOWN_LOCATION, type, elts);
+  return gimple_build_vector (seq, UNKNOWN_LOCATION, builder);
 }
 
 extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	2017-12-06 14:48:52.888162175 +0000
+++ gcc/gimple-fold.c	2017-12-06 14:49:04.288693455 +0000
@@ -7178,23 +7178,30 @@  gimple_build_vector_from_val (gimple_seq
   return res;
 }
 
-/* Build a vector of type TYPE in which the elements have the values
-   given by ELTS.  Return a gimple value for the result, appending any
-   new instructions to SEQ.  */
+/* Build a vector from BUILDER, handling the case in which some elements
+   are non-constant.  Return a gimple value for the result, appending any
+   new instructions to SEQ.
+
+   BUILDER must not have a stepped encoding on entry.  This is because
+   the function is not geared up to handle the arithmetic that would
+   be needed in the variable case, and any code building a vector that
+   is known to be constant should use BUILDER->build () directly.  */
 
 tree
-gimple_build_vector (gimple_seq *seq, location_t loc, tree type,
-		     vec<tree> elts)
+gimple_build_vector (gimple_seq *seq, location_t loc,
+		     tree_vector_builder *builder)
 {
-  unsigned int nelts = elts.length ();
-  gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
-  for (unsigned int i = 0; i < nelts; ++i)
-    if (!TREE_CONSTANT (elts[i]))
+  gcc_assert (builder->nelts_per_pattern () <= 2);
+  unsigned int encoded_nelts = builder->encoded_nelts ();
+  for (unsigned int i = 0; i < encoded_nelts; ++i)
+    if (!TREE_CONSTANT ((*builder)[i]))
       {
+	tree type = builder->type ();
+	unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
 	vec<constructor_elt, va_gc> *v;
 	vec_alloc (v, nelts);
 	for (i = 0; i < nelts; ++i)
-	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]);
+	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));
 
 	tree res;
 	if (gimple_in_ssa_p (cfun))
@@ -7206,7 +7213,7 @@  gimple_build_vector (gimple_seq *seq, lo
 	gimple_seq_add_stmt_without_update (seq, stmt);
 	return res;
       }
-  return build_vector (type, elts);
+  return builder->build ();
 }
 
 /* Return true if the result of assignment STMT is known to be non-negative.
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	2017-12-06 14:48:52.889162134 +0000
+++ gcc/tree-vect-loop.c	2017-12-06 14:49:04.289693414 +0000
@@ -3968,11 +3968,9 @@  get_initial_def_for_reduction (gimple *s
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   tree scalar_type = TREE_TYPE (init_val);
   tree vectype = get_vectype_for_scalar_type (scalar_type);
-  int nunits;
   enum tree_code code = gimple_assign_rhs_code (stmt);
   tree def_for_init;
   tree init_def;
-  int i;
   bool nested_in_vect_loop = false;
   REAL_VALUE_TYPE real_init_val = dconst0;
   int int_init_val = 0;
@@ -3980,7 +3978,6 @@  get_initial_def_for_reduction (gimple *s
   gimple_seq stmts = NULL;
 
   gcc_assert (vectype);
-  nunits = TYPE_VECTOR_SUBPARTS (vectype);
 
   gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type)
 	      || SCALAR_FLOAT_TYPE_P (scalar_type));
@@ -4053,11 +4050,10 @@  get_initial_def_for_reduction (gimple *s
 	else
 	  {
 	    /* Option2: the first element is INIT_VAL.  */
-	    auto_vec<tree, 32> elts (nunits);
+	    tree_vector_builder elts (vectype, 1, 2);
 	    elts.quick_push (init_val);
-	    for (i = 1; i < nunits; ++i)
-	      elts.quick_push (def_for_init);
-	    init_def = gimple_build_vector (&stmts, vectype, elts);
+	    elts.quick_push (def_for_init);
+	    init_def = gimple_build_vector (&stmts, &elts);
 	  }
       }
       break;
@@ -4182,7 +4178,7 @@  get_initial_defs_for_reduction (slp_tree
   number_of_copies = nunits * number_of_vectors / group_size;
 
   number_of_places_left_in_vector = nunits;
-  auto_vec<tree, 32> elts (nunits);
+  tree_vector_builder elts (vector_type, nunits, 1);
   elts.quick_grow (nunits);
   for (j = 0; j < number_of_copies; j++)
     {
@@ -4205,12 +4201,14 @@  get_initial_defs_for_reduction (slp_tree
           if (number_of_places_left_in_vector == 0)
             {
 	      gimple_seq ctor_seq = NULL;
-	      tree init = gimple_build_vector (&ctor_seq, vector_type, elts);
+	      tree init = gimple_build_vector (&ctor_seq, &elts);
 	      if (ctor_seq != NULL)
 		gsi_insert_seq_on_edge_immediate (pe, ctor_seq);
 	      voprnds.quick_push (init);
 
               number_of_places_left_in_vector = nunits;
+	      elts.new_vector (vector_type, nunits, 1);
+	      elts.quick_grow (nunits);
             }
         }
     }
@@ -6698,7 +6696,7 @@  vectorizable_induction (gimple *phi,
       unsigned ivn;
       for (ivn = 0; ivn < nivs; ++ivn)
 	{
-	  auto_vec<tree, 32> elts (nunits);
+	  tree_vector_builder elts (vectype, nunits, 1);
 	  stmts = NULL;
 	  for (unsigned eltn = 0; eltn < nunits; ++eltn)
 	    {
@@ -6708,7 +6706,7 @@  vectorizable_induction (gimple *phi,
 				    elt, step_expr);
 	      elts.quick_push (elt);
 	    }
-	  vec_init = gimple_build_vector (&stmts, vectype, elts);
+	  vec_init = gimple_build_vector (&stmts, &elts);
 	  if (stmts)
 	    {
 	      new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
@@ -6815,7 +6813,7 @@  vectorizable_induction (gimple *phi,
       stmts = NULL;
       new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);
 
-      auto_vec<tree, 32> elts (nunits);
+      tree_vector_builder elts (vectype, nunits, 1);
       elts.quick_push (new_name);
       for (i = 1; i < nunits; i++)
 	{
@@ -6826,7 +6824,7 @@  vectorizable_induction (gimple *phi,
 	}
       /* Create a vector from [new_name_0, new_name_1, ...,
 	 new_name_nunits-1]  */
-      vec_init = gimple_build_vector (&stmts, vectype, elts);
+      vec_init = gimple_build_vector (&stmts, &elts);
       if (stmts)
 	{
 	  new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);