On Wed, Feb 01, 2017 at 03:03:15PM +0100, Richard Biener wrote:
> 2017-02-01  Richard Biener  <rguent...@suse.de>
> 
>       PR cp/14179
>       cp/
>       * cp-gimplify.c (cp_fold): When folding a CONSTRUCTOR copy
>       it lazily on the first changed element only and copy it
>       fully upfront, only storing changed elements.
> 
> Index: gcc/cp/cp-gimplify.c
> ===================================================================
> --- gcc/cp/cp-gimplify.c      (revision 245094)
> +++ gcc/cp/cp-gimplify.c      (working copy)
> @@ -2361,12 +2361,9 @@ cp_fold (tree x)
>       bool changed = false;
>       vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
>       vec<constructor_elt, va_gc> *nelts = NULL;
> -     vec_safe_reserve (nelts, vec_safe_length (elts));
>       FOR_EACH_VEC_SAFE_ELT (elts, i, p)
>         {
>           tree op = cp_fold (p->value);
> -         constructor_elt e = { p->index, op };
> -         nelts->quick_push (e);
>           if (op != p->value)
>             {
>               if (op == error_mark_node)
> @@ -2375,7 +2372,13 @@ cp_fold (tree x)
>                   changed = false;
>                   break;
>                 }
> -             changed = true;
> +             if (! changed)
> +               {
> +                 nelts = elts->copy ();

Isn't the above part unnecessarily expensive, e.g. for the case
where you have huge CONSTRUCTOR and recursive cp_fold changes already
the very first value?  Wouldn't it be better to just do:
                    vec_safe_reserve (nelts, vec_safe_length (elts));
                    vec_quick_grow (nelts, i);
                    memcpy (nelts->address (), elts->address (),
                            i * sizeof (constructor_elt));
and then:

> +                 changed = true;
> +               }

> +             constructor_elt e = { p->index, op };
> +             (*nelts)[i] = e;

Remove the above two lines:
>             }

and add:
            if (changed)
              {
                constructor_elt e = { p->index, op };
                nelts->quick_push (e);
              }

>         }
>       if (changed)

Otherwise it looks good to me, but Jason should have his last word.

        Jakub

Reply via email to