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:
parent
c790e3ece6
commit
ecdcd56094
@ -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_
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user