c++: Tweak reshape_init_array_1 [PR94124]
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Mar 2020 07:28:05 +0000 (08:28 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 12 Mar 2020 07:28:05 +0000 (08:28 +0100)
Isn't it wasteful to first copy perhaps a large constructor (recursively)
and then truncate it to very few elts (zero in this case)?

> 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.

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-12  Jakub Jelinek  <jakub@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/ChangeLog
gcc/cp/decl.c

index 8cde300..b94e3bb 100644 (file)
@@ -1,3 +1,10 @@
+2020-03-12  Jakub Jelinek  <jakub@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.
+
 2020-03-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/93907
@@ -27,7 +34,7 @@
 
 2020-03-10  Jason Merrill  <jason@redhat.com>
 
-       PR c++/93956
+       PR c++/93596
        * pt.c (maybe_aggr_guide): Check BRACE_ENCLOSED_INITIALIZER_P.
 
 2020-03-10  Jason Merrill  <jason@redhat.com>
index aa58e5f..d240436 100644 (file)
@@ -6066,10 +6066,21 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
         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;
+         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;