On 18/12/22 22:18, Philippe Mathieu-Daudé wrote:
From: Richard Henderson <richard.hender...@linaro.org>

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.hender...@linaro.org>
[PMD: Split patch in two]
Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
  accel/tcg/plugin-gen.c     | 10 ++++-----
  include/exec/helper-head.h |  2 --
  include/tcg/tcg.h          | 46 +++++++++++++-------------------------
  tcg/tcg.c                  | 35 +++++++++++++++++++++--------
  4 files changed, 47 insertions(+), 46 deletions(-)


diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3f172cb1d6..ccbe947222 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -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;

We can move this assignation before the 'found' label.

+ /* Check for bitfield overflow. */
+    tcg_debug_assert(op->nargs == nargs);
+
+    s->nb_ops++;
      return op;
  }

Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org>


Reply via email to