Commit 3c961dc7 by Jason Merrill Committed by Jason Merrill

Reduce constexpr_call memory consumption.

	* constexpr.c (cxx_bind_parameters_in_call): Use TREE_VEC rather
	than TREE_LIST.
	(constexpr_call_hasher::equal, cxx_bind_parameters_in_call)
	(cxx_eval_call_expression): Adjust.

From-SVN: r272125
parent c2f879e1
2019-06-10 Jason Merrill <jason@redhat.com>
Reduce constexpr_call memory consumption.
* constexpr.c (cxx_bind_parameters_in_call): Use TREE_VEC rather
than TREE_LIST.
(constexpr_call_hasher::equal, cxx_bind_parameters_in_call)
(cxx_eval_call_expression): Adjust.
2019-06-10 Jakub Jelinek <jakub@redhat.com> 2019-06-10 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_omp_clause_reduction): Don't sorry_at on inscan * parser.c (cp_parser_omp_clause_reduction): Don't sorry_at on inscan
......
...@@ -974,12 +974,7 @@ explain_invalid_constexpr_fn (tree fun) ...@@ -974,12 +974,7 @@ explain_invalid_constexpr_fn (tree fun)
struct GTY((for_user)) constexpr_call { struct GTY((for_user)) constexpr_call {
/* Description of the constexpr function definition. */ /* Description of the constexpr function definition. */
constexpr_fundef *fundef; constexpr_fundef *fundef;
/* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE /* Parameter bindings environment. A TREE_VEC of arguments. */
is a parameter _DECL and the TREE_VALUE is the value of the parameter.
Note: This arrangement is made to accommodate the use of
iterative_hash_template_arg (see pt.c). If you change this
representation, also change the hash calculation in
cxx_eval_call_expression. */
tree bindings; tree bindings;
/* Result of the call. /* Result of the call.
NULL means the call is being evaluated. NULL means the call is being evaluated.
...@@ -1069,8 +1064,6 @@ constexpr_call_hasher::hash (constexpr_call *info) ...@@ -1069,8 +1064,6 @@ constexpr_call_hasher::hash (constexpr_call *info)
bool bool
constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs) constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
{ {
tree lhs_bindings;
tree rhs_bindings;
if (lhs == rhs) if (lhs == rhs)
return true; return true;
if (lhs->hash != rhs->hash) if (lhs->hash != rhs->hash)
...@@ -1079,19 +1072,7 @@ constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs) ...@@ -1079,19 +1072,7 @@ constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
return false; return false;
if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef)) if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
return false; return false;
lhs_bindings = lhs->bindings; return cp_tree_equal (lhs->bindings, rhs->bindings);
rhs_bindings = rhs->bindings;
while (lhs_bindings != NULL && rhs_bindings != NULL)
{
tree lhs_arg = TREE_VALUE (lhs_bindings);
tree rhs_arg = TREE_VALUE (rhs_bindings);
gcc_assert (same_type_p (TREE_TYPE (lhs_arg), TREE_TYPE (rhs_arg)));
if (!cp_tree_equal (lhs_arg, rhs_arg))
return false;
lhs_bindings = TREE_CHAIN (lhs_bindings);
rhs_bindings = TREE_CHAIN (rhs_bindings);
}
return lhs_bindings == rhs_bindings;
} }
/* Initialize the constexpr call table, if needed. */ /* Initialize the constexpr call table, if needed. */
...@@ -1380,7 +1361,10 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, ...@@ -1380,7 +1361,10 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
tree fun = new_call->fundef->decl; tree fun = new_call->fundef->decl;
tree parms = new_call->fundef->parms; tree parms = new_call->fundef->parms;
int i; int i;
tree *p = &new_call->bindings; /* We don't record ellipsis args below. */
int nparms = list_length (parms);
int nbinds = nargs < nparms ? nargs : nparms;
tree binds = new_call->bindings = make_tree_vec (nbinds);
for (i = 0; i < nargs; ++i) for (i = 0; i < nargs; ++i)
{ {
tree x, arg; tree x, arg;
...@@ -1417,8 +1401,7 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, ...@@ -1417,8 +1401,7 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
arg = adjust_temp_type (type, arg); arg = adjust_temp_type (type, arg);
if (!TREE_CONSTANT (arg)) if (!TREE_CONSTANT (arg))
*non_constant_args = true; *non_constant_args = true;
*p = build_tree_list (parms, arg); TREE_VEC_ELT (binds, i) = arg;
p = &TREE_CHAIN (*p);
} }
parms = TREE_CHAIN (parms); parms = TREE_CHAIN (parms);
} }
...@@ -1745,14 +1728,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, ...@@ -1745,14 +1728,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
void preserve () { do_free = false; } void preserve () { do_free = false; }
~free_bindings () { ~free_bindings () {
if (do_free) if (do_free)
{ ggc_free (bindings);
while (bindings)
{
tree b = bindings;
bindings = TREE_CHAIN (bindings);
ggc_free (b);
}
}
} }
} fb (new_call.bindings); } fb (new_call.bindings);
...@@ -1833,15 +1809,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, ...@@ -1833,15 +1809,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
/* Associate the bindings with the remapped parms. */ /* Associate the bindings with the remapped parms. */
tree bound = new_call.bindings; tree bound = new_call.bindings;
tree remapped = parms; tree remapped = parms;
while (bound) for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
{ {
tree oparm = TREE_PURPOSE (bound); tree arg = TREE_VEC_ELT (bound, i);
tree arg = TREE_VALUE (bound);
gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm));
/* Don't share a CONSTRUCTOR that might be changed. */ /* Don't share a CONSTRUCTOR that might be changed. */
arg = unshare_constructor (arg); arg = unshare_constructor (arg);
ctx->values->put (remapped, arg); ctx->values->put (remapped, arg);
bound = TREE_CHAIN (bound);
remapped = DECL_CHAIN (remapped); remapped = DECL_CHAIN (remapped);
} }
/* Add the RESULT_DECL to the values map, too. */ /* Add the RESULT_DECL to the values map, too. */
......
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