On 3/11/20 6:28 PM, Jakub Jelinek 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 does nothing if nelts is 0, so this test seems unnecessary.
OK either way.
+ 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;
Jakub