From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35767) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9ej8-0006jL-4I for qemu-devel@nongnu.org; Thu, 17 Dec 2015 15:00:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a9ej5-0000JK-D5 for qemu-devel@nongnu.org; Thu, 17 Dec 2015 15:00:37 -0500 Received: from mail-ob0-x235.google.com ([2607:f8b0:4003:c01::235]:34726) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9ej5-0000JG-6S for qemu-devel@nongnu.org; Thu, 17 Dec 2015 15:00:35 -0500 Received: by mail-ob0-x235.google.com with SMTP id iw8so64796819obc.1 for ; Thu, 17 Dec 2015 12:00:35 -0800 (PST) Sender: Richard Henderson From: Richard Henderson Date: Thu, 17 Dec 2015 12:00:33 -0800 Message-Id: <1450382433-6066-1-git-send-email-rth@twiddle.net> In-Reply-To: <1450382320-5383-1-git-send-email-rth@twiddle.net> References: <1450382320-5383-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH v2 12/14] tcg: Allocate indirect_base temporaries in a different order List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mark.cave-ayland@ilande.co.uk, aurelien@aurel32.net Since we've not got liveness analysis for indirect bases, placing them at the end of the call-saved registers makes it more likely that it'll stay live. Signed-off-by: Richard Henderson --- tcg/tcg.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 7150a3f..1b17827 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -317,6 +317,8 @@ static const TCGHelperInfo all_helpers[] = { #include "exec/helper-tcg.h" }; +static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)]; + void tcg_context_init(TCGContext *s) { int op, total_args, n, i; @@ -359,6 +361,21 @@ void tcg_context_init(TCGContext *s) } tcg_target_init(s); + + /* Reverse the order of the saved registers, assuming they're all at + the start of tcg_target_reg_alloc_order. */ + for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) { + int r = tcg_target_reg_alloc_order[n]; + if (tcg_regset_test_reg(tcg_target_call_clobber_regs, r)) { + break; + } + } + for (i = 0; i < n; ++i) { + indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i]; + } + for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) { + indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i]; + } } void tcg_prologue_init(TCGContext *s) @@ -1700,24 +1717,26 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs) /* Allocate a register belonging to reg1 & ~reg2 */ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs, - TCGRegSet allocated_regs) + TCGRegSet allocated_regs, bool rev) { - int i; + int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order); + const int *order; TCGReg reg; TCGRegSet reg_ct; tcg_regset_andnot(reg_ct, desired_regs, allocated_regs); + order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order; /* first try free registers */ - for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { - reg = tcg_target_reg_alloc_order[i]; + for(i = 0; i < n; i++) { + reg = order[i]; if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL) return reg; } /* XXX: do better spill choice */ - for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { - reg = tcg_target_reg_alloc_order[i]; + for(i = 0; i < n; i++) { + reg = order[i]; if (tcg_regset_test_reg(reg_ct, reg)) { tcg_reg_free(s, reg, allocated_regs); return reg; @@ -1738,12 +1757,12 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, case TEMP_VAL_REG: return; case TEMP_VAL_CONST: - reg = tcg_reg_alloc(s, desired_regs, allocated_regs); + reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base); tcg_out_movi(s, ts->type, reg, ts->val); ts->mem_coherent = 0; break; case TEMP_VAL_MEM: - reg = tcg_reg_alloc(s, desired_regs, allocated_regs); + reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base); if (ts->indirect_reg) { tcg_regset_set_reg(allocated_regs, reg); temp_load(s, ts->mem_base, @@ -1980,7 +1999,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, input one. */ tcg_regset_set_reg(allocated_regs, ts->reg); ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype], - allocated_regs); + allocated_regs, ots->indirect_base); } tcg_out_mov(s, otype, ots->reg, ts->reg); } @@ -2065,7 +2084,8 @@ static void tcg_reg_alloc_op(TCGContext *s, allocate_in_reg: /* allocate a new register matching the constraint and move the temporary register into it */ - reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); + reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs, + ts->indirect_base); tcg_out_mov(s, ts->type, reg, ts->reg); } new_args[i] = reg; @@ -2114,7 +2134,8 @@ static void tcg_reg_alloc_op(TCGContext *s, tcg_regset_test_reg(arg_ct->u.regs, reg)) { goto oarg_end; } - reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); + reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs, + ts->indirect_base); } tcg_regset_set_reg(allocated_regs, reg); /* if a fixed register is used, then a move will be done afterwards */ -- 2.5.0