From: Jason Merrill Date: Mon, 10 Jun 2019 19:32:30 +0000 (-0400) Subject: Reduce unsharing in constexpr call evaluation. X-Git-Tag: misc/cutover-git~4921 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b9eb42a4168c342e5cd71b13d21e63ba7e1b7ab;p=thirdparty%2Fgcc.git Reduce unsharing in constexpr call evaluation. * constexpr.c (unshare_constructor): Only unshare if T is itself a CONSTRUCTOR. (cxx_eval_call_expression): Don't call it on the result here. From-SVN: r272126 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7a782dc9f0f1..93d5f497400c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-06-10 Jason Merrill + * constexpr.c (unshare_constructor): Only unshare if T is itself a + CONSTRUCTOR. + (cxx_eval_call_expression): Don't call it on the result here. + Reduce constexpr_call memory consumption. * constexpr.c (cxx_bind_parameters_in_call): Use TREE_VEC rather than TREE_LIST. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 74752bc72dd1..d7adb469b45c 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1321,27 +1321,32 @@ adjust_temp_type (tree type, tree temp) return cp_fold_convert (type, temp); } -/* Callback for walk_tree used by unshare_constructor. */ +/* If T is a CONSTRUCTOR, return an unshared copy of T and any + sub-CONSTRUCTORs. Otherwise return T. -static tree -find_constructor (tree *tp, int *walk_subtrees, void *) -{ - if (TYPE_P (*tp)) - *walk_subtrees = 0; - if (TREE_CODE (*tp) == CONSTRUCTOR) - return *tp; - return NULL_TREE; -} - -/* If T is a CONSTRUCTOR or an expression that has a CONSTRUCTOR node as a - subexpression, return an unshared copy of T. Otherwise return T. */ + We use this whenever we initialize an object as a whole, whether it's a + parameter, a local variable, or a subobject, so that subsequent + modifications don't affect other places where it was used. */ tree unshare_constructor (tree t) { - tree ctor = walk_tree (&t, find_constructor, NULL, NULL); - if (ctor != NULL_TREE) - return unshare_expr (t); + if (!t || TREE_CODE (t) != CONSTRUCTOR) + return t; + auto_vec ptrs; + ptrs.safe_push (&t); + while (!ptrs.is_empty ()) + { + tree *p = ptrs.pop (); + tree n = copy_node (*p); + CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p)); + *p = n; + vec *v = CONSTRUCTOR_ELTS (n); + constructor_elt *ce; + for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i) + if (TREE_CODE (ce->value) == CONSTRUCTOR) + ptrs.safe_push (&ce->value); + } return t; } @@ -1898,7 +1903,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, clear_no_implicit_zero (result); pop_cx_call_context (); - return unshare_constructor (result); + return result; } /* FIXME speed this up, it's taking 16% of compile time on sieve testcase. */