From e98ebda074bf8fc5f630a93085af81f52437d851 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 31 Jan 2020 00:21:44 -0500 Subject: [PATCH] c++: Reduce memory consumption for arrays of non-aggregate type. The remaining low-hanging fruit for improvement on memory consumption in the 14179 testcase was the duplication of the CONSTRUCTOR for the array by reshape_init. This patch changes reshape_init to reuse a single constructor for an array of non-aggregate type such as the one in the testcase. PR c++/14179 * decl.c (reshape_init_array_1): Reuse a single CONSTRUCTOR with non-aggregate elements. (reshape_init_array): Add first_initializer_p parm. (reshape_init_r): Change first_initializer_p from bool to tree. (reshape_init): Pass init to it. --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 50 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8140885dab..cae1c918d30 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2020-01-31 Jason Merrill + PR c++/14179 + * decl.c (reshape_init_array_1): Reuse a single CONSTRUCTOR with + non-aggregate elements. + (reshape_init_array): Add first_initializer_p parm. + (reshape_init_r): Change first_initializer_p from bool to tree. + (reshape_init): Pass init to it. + PR c++/14179 * parser.c (cp_parser_initializer_list): Suppress location wrappers after 256 elements. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6ad558eef9e..ef34f436fdf 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5931,7 +5931,7 @@ struct reshape_iter constructor_elt *end; }; -static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t); +static tree reshape_init_r (tree, reshape_iter *, tree, tsubst_flags_t); /* FIELD is a FIELD_DECL or NULL. In the former case, the value returned is the next FIELD_DECL (possibly FIELD itself) that can be @@ -5979,15 +5979,21 @@ is_direct_enum_init (tree type, tree init) static tree reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, - tsubst_flags_t complain) + tree first_initializer_p, tsubst_flags_t complain) { tree new_init; bool sized_array_p = (max_index && TREE_CONSTANT (max_index)); unsigned HOST_WIDE_INT max_index_cst = 0; unsigned HOST_WIDE_INT index; - /* The initializer for an array is always a CONSTRUCTOR. */ - new_init = build_constructor (init_list_type_node, NULL); + /* The initializer for an array is always a CONSTRUCTOR. If this is the + outermost CONSTRUCTOR and the element type is non-aggregate, we don't need + to build a new one. */ + bool reuse = first_initializer_p && !CP_AGGREGATE_TYPE_P (elt_type); + if (reuse) + new_init = first_initializer_p; + else + new_init = build_constructor (init_list_type_node, NULL); if (sized_array_p) { @@ -6014,12 +6020,20 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, constructor_elt *old_cur = d->cur; check_array_designated_initializer (d->cur, index); - elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false, + elt_init = reshape_init_r (elt_type, d, + /*first_initializer_p=*/NULL_TREE, complain); if (elt_init == error_mark_node) return error_mark_node; - CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), - size_int (index), elt_init); + tree idx = size_int (index); + if (reuse) + { + old_cur->index = idx; + old_cur->value = elt_init; + } + else + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), + idx, elt_init); if (!TREE_CONSTANT (elt_init)) TREE_CONSTANT (new_init) = false; @@ -6056,7 +6070,8 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, Parameters are the same of reshape_init_r. */ static tree -reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain) +reshape_init_array (tree type, reshape_iter *d, tree first_initializer_p, + tsubst_flags_t complain) { tree max_index = NULL_TREE; @@ -6065,7 +6080,8 @@ reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain) if (TYPE_DOMAIN (type)) max_index = array_type_nelts (type); - return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain); + return reshape_init_array_1 (TREE_TYPE (type), max_index, d, + first_initializer_p, complain); } /* Subroutine of reshape_init_r, processes the initializers for vectors. @@ -6096,7 +6112,8 @@ reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain) if (VECTOR_TYPE_P (type)) max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1); - return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain); + return reshape_init_array_1 (TREE_TYPE (type), max_index, d, + NULL_TREE, complain); } /* Subroutine of reshape_init_r, processes the initializers for classes @@ -6179,7 +6196,8 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, break; field_init = reshape_init_r (TREE_TYPE (field), d, - /*first_initializer_p=*/false, complain); + /*first_initializer_p=*/NULL_TREE, + complain); if (field_init == error_mark_node) return error_mark_node; @@ -6230,11 +6248,11 @@ has_designator_problem (reshape_iter *d, tsubst_flags_t complain) /* Subroutine of reshape_init, which processes a single initializer (part of a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the iterator within the CONSTRUCTOR which points to the initializer to process. - FIRST_INITIALIZER_P is true if this is the first initializer of the - outermost CONSTRUCTOR node. */ + If this is the first initializer of the outermost CONSTRUCTOR node, + FIRST_INITIALIZER_P is that CONSTRUCTOR; otherwise, it is NULL_TREE. */ static tree -reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, +reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p, tsubst_flags_t complain) { tree init = d->cur->value; @@ -6431,7 +6449,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, if (CLASS_TYPE_P (type)) return reshape_init_class (type, d, first_initializer_p, complain); else if (TREE_CODE (type) == ARRAY_TYPE) - return reshape_init_array (type, d, complain); + return reshape_init_array (type, d, first_initializer_p, complain); else if (VECTOR_TYPE_P (type)) return reshape_init_vector (type, d, complain); else @@ -6495,7 +6513,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) d.cur = &(*v)[0]; d.end = d.cur + v->length (); - new_init = reshape_init_r (type, &d, true, complain); + new_init = reshape_init_r (type, &d, init, complain); if (new_init == error_mark_node) return error_mark_node; -- 2.30.2