aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-06-26 22:59:44 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-06-26 22:59:44 -0400
commit307193b82cecb8ab79cf8880d642e1a3acb9c9f6 (patch)
treee8ecb61a6f283f91fee98716062463538c3c38f0
parent6147a53a9cb946ab08acb0177cff29a40aee937b (diff)
downloadgcc-307193b82cecb8ab79cf8880d642e1a3acb9c9f6.zip
gcc-307193b82cecb8ab79cf8880d642e1a3acb9c9f6.tar.gz
gcc-307193b82cecb8ab79cf8880d642e1a3acb9c9f6.tar.bz2
PR c++/86320 - memory-hog with std::array of pair
* typeck2.c (process_init_constructor_array): Only compute a constant initializer once. In this PR, we have a large std::array of pairs. Since the C array is wrapped in a class we don't go to build_vec_init, so we end up with digest_init wanting to build up the element initializer for each element of the array. In the more general case, like 80272, we have a data structure problem: we don't currently have a good way of expressing the same dynamic initialization of many elements within a CONSTRUCTOR. RANGE_EXPR probably ought to work, but will need more work at genericize or gimplify time. But in this case, the initialization for each element reduces to constant 0, so we don't even need to add anything to the CONSTRUCTOR. We just need to realize that if the initializer for one element is 0, the others will be as well, and we don't need to iterate over the whole array. For the trunk, I also use a RANGE_EXPR to handle constant initialization by a value other than 0. void foo () { std::array<std::pair<int, int>, 1024 * 1024> arr {}; } From-SVN: r262173
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/typeck2.c16
2 files changed, 19 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3043165..90d1545 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2018-06-26 Jason Merrill <jason@redhat.com>
+ PR c++/86320 - memory-hog with std::array of pair
+ * typeck2.c (process_init_constructor_array): Only compute a
+ constant initializer once.
+
PR c++/80290 - memory-hog with std::pair.
* pt.c (fn_type_unification): Add convs parameter.
(check_non_deducible_conversion): Remember conversion.
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 43e236d..91aa5a6 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1365,8 +1365,22 @@ process_init_constructor_array (tree type, tree init, int nested,
if (next)
{
flags |= picflag_from_initializer (next);
- CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
+ if (len > i+1
+ && (initializer_constant_valid_p (next, TREE_TYPE (next))
+ == null_pointer_node))
+ {
+ tree range = build2 (RANGE_EXPR, size_type_node,
+ build_int_cst (size_type_node, i),
+ build_int_cst (size_type_node, len - 1));
+ CONSTRUCTOR_APPEND_ELT (v, range, next);
+ break;
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
}
+ else
+ /* Don't bother checking all the other elements. */
+ break;
}
CONSTRUCTOR_ELTS (init) = v;