From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:35901) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJ7Iv-0007uA-7Z for qemu-devel@nongnu.org; Tue, 02 Oct 2012 14:34:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TJ7Ip-0008DH-Br for qemu-devel@nongnu.org; Tue, 02 Oct 2012 14:34:49 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:43010) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJ7Ip-0008DD-5r for qemu-devel@nongnu.org; Tue, 02 Oct 2012 14:34:43 -0400 Received: by padfb10 with SMTP id fb10so5569920pad.4 for ; Tue, 02 Oct 2012 11:34:42 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Tue, 2 Oct 2012 11:32:29 -0700 Message-Id: <1349202750-16815-10-git-send-email-rth@twiddle.net> In-Reply-To: <1349202750-16815-1-git-send-email-rth@twiddle.net> References: <1349202750-16815-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH 09/10] tcg: Optimize half-dead add2/sub2 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Aurelien Jarno When x86_64 guest is not in 64-bit mode, the high-part of the 64-bit add is dead. When the host is 32-bit, we can simplify to 32-bit arithmetic. Signed-off-by: Richard Henderson --- tcg/tcg.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index c069e44..21c1074 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1306,8 +1306,39 @@ static void tcg_liveness_analysis(TCGContext *s) break; case INDEX_op_end: break; - /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ + + case INDEX_op_add2_i32: + case INDEX_op_sub2_i32: + args -= 6; + nb_iargs = 4; + nb_oargs = 2; + /* Test if the high part of the operation is dead, but not + the low part. The result can be optimized to a simple + add or sub. This happens often for x86_64 guest when the + cpu mode is set to 32 bit. */ + if (dead_temps[args[1]]) { + if (dead_temps[args[0]]) { + goto do_remove; + } + /* Create the single operation plus nop. */ + if (op == INDEX_op_add2_i32) { + op = INDEX_op_add_i32; + } else { + op = INDEX_op_sub_i32; + } + gen_opc_buf[op_index] = op; + args[1] = args[2]; + args[2] = args[4]; + assert(gen_opc_buf[op_index + 1] == INDEX_op_nop); + tcg_set_nop(s, gen_opc_buf + op_index + 1, args + 3, 3); + /* Fall through and mark the single-word operation live. */ + nb_iargs = 2; + nb_oargs = 1; + } + goto do_not_remove; + default: + /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ args -= def->nb_args; nb_iargs = def->nb_iargs; nb_oargs = def->nb_oargs; @@ -1321,6 +1352,7 @@ static void tcg_liveness_analysis(TCGContext *s) if (!dead_temps[arg]) goto do_not_remove; } + do_remove: tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args); #ifdef CONFIG_PROFILER s->del_op_count++; -- 1.7.11.4