On Wed, Mar 11, 2020 at 11:28:01PM +0100, Jakub Jelinek via Gcc-patches wrote:
> On Wed, Mar 11, 2020 at 04:02:51PM -0400, Jason Merrill via Gcc-patches wrote:
> > We should certainly avoid copying if they're the same.  The code above for
> > only copying the bits that aren't going to be thrown away seems pretty
> > straightforward, might as well use it even if the savings aren't likely to
> > be large.
> 
> So like this if it passes bootstrap/regtest?
> Calling vec_safe_truncate with the same number of elts the vector already
> has is a nop, so IMHO we just should make sure we only unshare if it
> changed.
> 
> 2020-03-11  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR c++/94124
>       * decl.c (reshape_init_array_1): Don't unshare constructor if there
>       aren't any trailing zero elts, otherwise only unshare the first
>       nelts.
> 
> --- gcc/cp/decl.c.jj  2020-03-11 09:28:53.966213943 +0100
> +++ gcc/cp/decl.c     2020-03-11 23:19:08.832780798 +0100
> @@ -6066,10 +6066,22 @@ reshape_init_array_1 (tree elt_type, tre
>        overload resolution.  E.g., initializing a class from
>        {{0}} might be invalid while initializing the same class
>        from {{}} might be valid.  */
> -      if (reuse)
> -     new_init = unshare_constructor (new_init);
> -
> -      vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts);
> +      if (reuse && nelts < CONSTRUCTOR_NELTS (new_init))
> +     {
> +       vec<constructor_elt, va_gc> *v = NULL;
> +       if (nelts)
> +         vec_alloc (v, nelts);
> +       for (unsigned int i = 0; i < nelts; i++)
> +         {
> +           constructor_elt elt = *CONSTRUCTOR_ELT (new_init, i);
> +           if (TREE_CODE (elt.value) == CONSTRUCTOR)
> +             elt.value = unshare_constructor (elt.value);
> +           v->quick_push (elt);
> +         }
> +       new_init = build_constructor (TREE_TYPE (new_init), v);
> +     }
> +      else
> +     vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts);
>      }
>  
>    return new_init;

LGTM.

Marek

Reply via email to