Reduce accumulated garbage in constexpr evaluation.

We want to evaluate the arguments to a call before looking into the cache so
that we have constant values, but if we then find the call in the cache we
end up with a TREE_LIST that we don't end up using; in highly recursive
constexpr evaluation this ends up being a large proportion of the garbage
generated.

The cxx_eval_increment_expression hunk is less important, but it's an easy
tweak; we only use the MODIFY_EXPR to evaluate it, so after that it's
garbage.

	* constexpr.c (cxx_eval_call_expression): ggc_free any bindings we
	don't save.
	(cxx_eval_increment_expression): ggc_free the MODIFY_EXPR after
	evaluating it.

From-SVN: r271909
This commit is contained in:
Jason Merrill 2019-06-04 10:47:40 -04:00 committed by Jason Merrill
parent c790e3ece6
commit ecdcd56094
2 changed files with 33 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2019-06-04 Jason Merrill <jason@redhat.com>
Reduce accumulated garbage in constexpr evaluation.
* constexpr.c (cxx_eval_call_expression): ggc_free any bindings we
don't save.
(cxx_eval_increment_expression): ggc_free the MODIFY_EXPR after
evaluating it.
2019-06-04 Jakub Jelinek <jakub@redhat.com>
* cp-tree.h (CP_OMP_CLAUSE_INFO): Allow for any clauses up to _condvar_

View File

@ -1733,6 +1733,29 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
bool non_constant_args = false;
cxx_bind_parameters_in_call (ctx, t, &new_call,
non_constant_p, overflow_p, &non_constant_args);
/* We build up the bindings list before we know whether we already have this
call cached. If we don't end up saving these bindings, ggc_free them when
this function exits. */
struct free_bindings
{
tree &bindings;
bool do_free;
free_bindings (tree &b): bindings (b), do_free(true) { }
void preserve () { do_free = false; }
~free_bindings () {
if (do_free)
{
while (bindings)
{
tree b = bindings;
bindings = TREE_CHAIN (bindings);
ggc_free (b);
}
}
}
} fb (new_call.bindings);
if (*non_constant_p)
return t;
@ -1760,6 +1783,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
slot can move in the call to cxx_eval_builtin_function_call. */
*slot = entry = ggc_alloc<constexpr_call> ();
*entry = new_call;
fb.preserve ();
}
/* Calls that are in progress have their result set to NULL,
so that we can detect circular dependencies. */
@ -4002,6 +4026,7 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
tree store = build2 (MODIFY_EXPR, type, op, mod);
cxx_eval_constant_expression (ctx, store,
true, non_constant_p, overflow_p);
ggc_free (store);
/* And the value of the expression. */
if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)