tcg: Optimize half-dead add2/sub2
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 <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
212c328d61
commit
1305c451e6
34
tcg/tcg.c
34
tcg/tcg.c
@ -1307,8 +1307,39 @@ static void tcg_liveness_analysis(TCGContext *s)
|
|||||||
break;
|
break;
|
||||||
case INDEX_op_end:
|
case INDEX_op_end:
|
||||||
break;
|
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:
|
default:
|
||||||
|
/* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
|
||||||
args -= def->nb_args;
|
args -= def->nb_args;
|
||||||
nb_iargs = def->nb_iargs;
|
nb_iargs = def->nb_iargs;
|
||||||
nb_oargs = def->nb_oargs;
|
nb_oargs = def->nb_oargs;
|
||||||
@ -1322,6 +1353,7 @@ static void tcg_liveness_analysis(TCGContext *s)
|
|||||||
if (!dead_temps[arg])
|
if (!dead_temps[arg])
|
||||||
goto do_not_remove;
|
goto do_not_remove;
|
||||||
}
|
}
|
||||||
|
do_remove:
|
||||||
tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
|
tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
s->del_op_count++;
|
s->del_op_count++;
|
||||||
|
Loading…
Reference in New Issue
Block a user