提交 abebf925 编写于 作者: R Richard Henderson

tcg: Limit the number of ops in a TB

In 6001f772 we partially attempt to address the branch
displacement overflow caused by 15fa08f8.

However, gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vqtbX.c
is a testcase that contains a TB so large as to overflow anyway.
The limit here of 8000 ops produces a maximum output TB size of
24112 bytes on a ppc64le host with that test case.  This is still
much less than the maximum forward branch distance of 32764 bytes.

Cc: qemu-stable@nongnu.org
Fixes: 15fa08f8 ("tcg: Dynamically allocate TCGOps")
Reviewed-by: NLaurent Vivier <laurent@vivier.eu>
Reviewed-by: NPhilippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: NRichard Henderson <richard.henderson@linaro.org>
上级 7eb30ef0
...@@ -866,6 +866,7 @@ void tcg_func_start(TCGContext *s) ...@@ -866,6 +866,7 @@ void tcg_func_start(TCGContext *s)
/* No temps have been previously allocated for size or locality. */ /* No temps have been previously allocated for size or locality. */
memset(s->free_temps, 0, sizeof(s->free_temps)); memset(s->free_temps, 0, sizeof(s->free_temps));
s->nb_ops = 0;
s->nb_labels = 0; s->nb_labels = 0;
s->current_frame_offset = s->frame_start; s->current_frame_offset = s->frame_start;
...@@ -1956,6 +1957,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op) ...@@ -1956,6 +1957,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
{ {
QTAILQ_REMOVE(&s->ops, op, link); QTAILQ_REMOVE(&s->ops, op, link);
QTAILQ_INSERT_TAIL(&s->free_ops, op, link); QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
s->nb_ops--;
#ifdef CONFIG_PROFILER #ifdef CONFIG_PROFILER
atomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1); atomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
...@@ -1975,6 +1977,7 @@ static TCGOp *tcg_op_alloc(TCGOpcode opc) ...@@ -1975,6 +1977,7 @@ static TCGOp *tcg_op_alloc(TCGOpcode opc)
} }
memset(op, 0, offsetof(TCGOp, link)); memset(op, 0, offsetof(TCGOp, link));
op->opc = opc; op->opc = opc;
s->nb_ops++;
return op; return op;
} }
......
...@@ -655,6 +655,7 @@ struct TCGContext { ...@@ -655,6 +655,7 @@ struct TCGContext {
int nb_globals; int nb_globals;
int nb_temps; int nb_temps;
int nb_indirects; int nb_indirects;
int nb_ops;
/* goto_tb support */ /* goto_tb support */
tcg_insn_unit *code_buf; tcg_insn_unit *code_buf;
...@@ -844,7 +845,12 @@ static inline TCGOp *tcg_last_op(void) ...@@ -844,7 +845,12 @@ static inline TCGOp *tcg_last_op(void)
/* Test for whether to terminate the TB for using too many opcodes. */ /* Test for whether to terminate the TB for using too many opcodes. */
static inline bool tcg_op_buf_full(void) static inline bool tcg_op_buf_full(void)
{ {
return false; /* This is not a hard limit, it merely stops translation when
* we have produced "enough" opcodes. We want to limit TB size
* such that a RISC host can reasonably use a 16-bit signed
* branch within the TB.
*/
return tcg_ctx->nb_ops >= 8000;
} }
/* pool based memory allocation */ /* pool based memory allocation */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册