From 26ab4d6560546274638560855bd16b29319818a4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 5 Jan 2019 06:39:04 -0500 Subject: [PATCH] tcg: Reference count labels Increment when adding branches, and decrement when removing them. Backports commit d88a117eaa39b1d0eb1a79fe84c81840a39eb233 from qemu --- qemu/tcg/tcg-op.c | 2 ++ qemu/tcg/tcg-op.h | 1 + qemu/tcg/tcg.c | 20 ++++++++++++++++++++ qemu/tcg/tcg.h | 3 ++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 46b408b5..472bc843 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -240,6 +240,7 @@ void tcg_gen_brcond_i32(TCGContext *s, TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg if (cond == TCG_COND_ALWAYS) { tcg_gen_br(s, l); } else if (cond != TCG_COND_NEVER) { + l->refs++; tcg_gen_op4ii_i32(s, INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(s, l)); } } @@ -1412,6 +1413,7 @@ void tcg_gen_brcond_i64(TCGContext *s, TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg if (cond == TCG_COND_ALWAYS) { tcg_gen_br(s, l); } else if (cond != TCG_COND_NEVER) { + l->refs++; if (TCG_TARGET_REG_BITS == 32) { tcg_gen_op6ii_i32(s, INDEX_op_brcond2_i32, TCGV_LOW(s, arg1), TCGV_HIGH(s, arg1), TCGV_LOW(s, arg2), diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 0aefa047..92fdd1f2 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -273,6 +273,7 @@ static inline void gen_set_label(TCGContext *s, TCGLabel *l) static inline void tcg_gen_br(TCGContext *s, TCGLabel *l) { + l->refs++; tcg_gen_op1(s, INDEX_op_br, label_arg(s, l)); } diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index d841491e..3ef03b57 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -1678,6 +1678,26 @@ static void process_op_defs(TCGContext *s) void tcg_op_remove(TCGContext *s, TCGOp *op) { + TCGLabel *label; + + switch (op->opc) { + case INDEX_op_br: + label = arg_label(s, op->args[0]); + label->refs--; + break; + case INDEX_op_brcond_i32: + case INDEX_op_brcond_i64: + label = arg_label(s, op->args[3]); + label->refs--; + break; + case INDEX_op_brcond2_i32: + label = arg_label(s, op->args[5]); + label->refs--; + break; + default: + break; + } + QTAILQ_REMOVE(&s->ops, op, link); QTAILQ_INSERT_TAIL(&s->free_ops, op, link); s->nb_ops--; diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index fab7857e..b4097b56 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -250,7 +250,8 @@ typedef struct TCGRelocation { typedef struct TCGLabel { unsigned has_value : 1; - unsigned id : 31; + unsigned id : 15; + unsigned refs : 16; union { uintptr_t value; tcg_insn_unit *value_ptr;