tcg: Vary the allocation size for TCGOp

We have been allocating a worst case number of arguments
to support calls.  Instead, allow the size to vary.
By default leave space for 4 args, to maximize reuse,
but allow calls to increase the number of args to 32.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[PMD: Split patch in two]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20221218211832.73312-3-philmd@linaro.org>
This commit is contained in:
Richard Henderson 2022-12-18 22:18:32 +01:00
parent d44789434b
commit cb10bc63b7
4 changed files with 47 additions and 46 deletions

View file

@ -1513,7 +1513,12 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
}
}
max_args = ARRAY_SIZE(op->args);
/*
* A Call op needs up to 4 + 2N parameters on 32-bit archs,
* and up to 4 + N parameters on 64-bit archs
* (N = number of input arguments + output arguments).
*/
max_args = (64 / TCG_TARGET_REG_BITS) * nargs + 4;
op = tcg_emit_op(INDEX_op_call, max_args);
pi = 0;
@ -2298,19 +2303,31 @@ void tcg_remove_ops_after(TCGOp *op)
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs)
{
TCGContext *s = tcg_ctx;
TCGOp *op;
TCGOp *op = NULL;
assert(nargs < ARRAY_SIZE(op->args));
if (likely(QTAILQ_EMPTY(&s->free_ops))) {
op = tcg_malloc(sizeof(TCGOp));
} else {
op = QTAILQ_FIRST(&s->free_ops);
QTAILQ_REMOVE(&s->free_ops, op, link);
if (unlikely(!QTAILQ_EMPTY(&s->free_ops))) {
QTAILQ_FOREACH(op, &s->free_ops, link) {
if (nargs <= op->nargs) {
QTAILQ_REMOVE(&s->free_ops, op, link);
nargs = op->nargs;
goto found;
}
}
}
/* Most opcodes have 3 or 4 operands: reduce fragmentation. */
nargs = MAX(4, nargs);
op = tcg_malloc(sizeof(TCGOp) + sizeof(TCGArg) * nargs);
found:
memset(op, 0, offsetof(TCGOp, link));
op->opc = opc;
s->nb_ops++;
op->nargs = nargs;
/* Check for bitfield overflow. */
tcg_debug_assert(op->nargs == nargs);
s->nb_ops++;
return op;
}