aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-30 18:49:29 -0500
committerJason Merrill <jason@redhat.com>2020-01-31 18:19:31 -0500
commitd2b9548f38c77edc29ab0e24e516f1fb341ecea7 (patch)
tree37078747238504a649c820bb088f9f5d14890ce9
parent6775172431a8e6f0d20ac0c4946d6b5db2f46450 (diff)
downloadgcc-d2b9548f38c77edc29ab0e24e516f1fb341ecea7.zip
gcc-d2b9548f38c77edc29ab0e24e516f1fb341ecea7.tar.gz
gcc-d2b9548f38c77edc29ab0e24e516f1fb341ecea7.tar.bz2
c++: Reduce memory consumption for large static arrays.
PR14179 and the C counterpart PR12245 are about memory consumption of very large file-scope arrays. Recently, location wrappers increased memory consumption significantly: in an array of integer constants, each one will have a location wrapper, which added up to over 500MB in the 14179 testcase. For this kind of testcase tracking these locations isn't worth the cost, so this patch turns the wrappers off after 256 elements; any array that size or larger isn't likely to be interested in the location of individual integer constants. PR c++/14179 * parser.c (cp_parser_initializer_list): Suppress location wrappers after 256 elements.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c18
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f260d5d..f814088 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/14179
+ * parser.c (cp_parser_initializer_list): Suppress location wrappers
+ after 256 elements.
+
2020-01-29 Jason Merrill <jason@redhat.com>
PR c++/82521
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bd8e524..e0f7230 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23311,6 +23311,9 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
/* Assume all of the expressions are constant. */
*non_constant_p = false;
+ unsigned nelts = 0;
+ int suppress = suppress_location_wrappers;
+
/* Parse the rest of the list. */
while (true)
{
@@ -23450,6 +23453,19 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
if (token->type == CPP_CLOSE_BRACE)
break;
+ /* Suppress location wrappers in a long initializer to save memory
+ (14179). The cutoff is chosen arbitrarily. */
+ const unsigned loc_max = 256;
+ unsigned incr = 1;
+ if (TREE_CODE (initializer) == CONSTRUCTOR)
+ /* Look one level down because it's easy. Looking deeper would require
+ passing down a nelts pointer, and I don't think multi-level massive
+ initializers are common enough to justify this. */
+ incr = CONSTRUCTOR_NELTS (initializer);
+ nelts += incr;
+ if (nelts >= loc_max && (nelts - incr) < loc_max)
+ ++suppress_location_wrappers;
+
/* Consume the `,' token. */
cp_lexer_consume_token (parser->lexer);
}
@@ -23479,6 +23495,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
IDENTIFIER_MARKED (designator) = 0;
}
+ suppress_location_wrappers = suppress;
+
*designated = first_designator != NULL_TREE;
return v;
}