Commit e98ebda0 by Jason Merrill

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.
parent d2b9548f
2020-01-31 Jason Merrill <jason@redhat.com> 2020-01-31 Jason Merrill <jason@redhat.com>
PR c++/14179 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 * parser.c (cp_parser_initializer_list): Suppress location wrappers
after 256 elements. after 256 elements.
......
...@@ -5931,7 +5931,7 @@ struct reshape_iter ...@@ -5931,7 +5931,7 @@ struct reshape_iter
constructor_elt *end; 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 /* 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 returned is the next FIELD_DECL (possibly FIELD itself) that can be
...@@ -5979,15 +5979,21 @@ is_direct_enum_init (tree type, tree init) ...@@ -5979,15 +5979,21 @@ is_direct_enum_init (tree type, tree init)
static tree static tree
reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, 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; tree new_init;
bool sized_array_p = (max_index && TREE_CONSTANT (max_index)); bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
unsigned HOST_WIDE_INT max_index_cst = 0; unsigned HOST_WIDE_INT max_index_cst = 0;
unsigned HOST_WIDE_INT index; unsigned HOST_WIDE_INT index;
/* The initializer for an array is always a CONSTRUCTOR. */ /* The initializer for an array is always a CONSTRUCTOR. If this is the
new_init = build_constructor (init_list_type_node, NULL); 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) if (sized_array_p)
{ {
...@@ -6014,12 +6020,20 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, ...@@ -6014,12 +6020,20 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
constructor_elt *old_cur = d->cur; constructor_elt *old_cur = d->cur;
check_array_designated_initializer (d->cur, index); 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); complain);
if (elt_init == error_mark_node) if (elt_init == error_mark_node)
return error_mark_node; return error_mark_node;
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), tree idx = size_int (index);
size_int (index), elt_init); 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)) if (!TREE_CONSTANT (elt_init))
TREE_CONSTANT (new_init) = false; TREE_CONSTANT (new_init) = false;
...@@ -6056,7 +6070,8 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d, ...@@ -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. */ Parameters are the same of reshape_init_r. */
static tree 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; tree max_index = NULL_TREE;
...@@ -6065,7 +6080,8 @@ reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain) ...@@ -6065,7 +6080,8 @@ reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
if (TYPE_DOMAIN (type)) if (TYPE_DOMAIN (type))
max_index = array_type_nelts (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. /* 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) ...@@ -6096,7 +6112,8 @@ reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain)
if (VECTOR_TYPE_P (type)) if (VECTOR_TYPE_P (type))
max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1); 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 /* 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, ...@@ -6179,7 +6196,8 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
break; break;
field_init = reshape_init_r (TREE_TYPE (field), d, 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) if (field_init == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -6230,11 +6248,11 @@ has_designator_problem (reshape_iter *d, tsubst_flags_t complain) ...@@ -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 /* 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 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. iterator within the CONSTRUCTOR which points to the initializer to process.
FIRST_INITIALIZER_P is true if this is the first initializer of the If this is the first initializer of the outermost CONSTRUCTOR node,
outermost CONSTRUCTOR node. */ FIRST_INITIALIZER_P is that CONSTRUCTOR; otherwise, it is NULL_TREE. */
static 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) tsubst_flags_t complain)
{ {
tree init = d->cur->value; tree init = d->cur->value;
...@@ -6431,7 +6449,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, ...@@ -6431,7 +6449,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
if (CLASS_TYPE_P (type)) if (CLASS_TYPE_P (type))
return reshape_init_class (type, d, first_initializer_p, complain); return reshape_init_class (type, d, first_initializer_p, complain);
else if (TREE_CODE (type) == ARRAY_TYPE) 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)) else if (VECTOR_TYPE_P (type))
return reshape_init_vector (type, d, complain); return reshape_init_vector (type, d, complain);
else else
...@@ -6495,7 +6513,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) ...@@ -6495,7 +6513,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain)
d.cur = &(*v)[0]; d.cur = &(*v)[0];
d.end = d.cur + v->length (); 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) if (new_init == error_mark_node)
return error_mark_node; return error_mark_node;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment