mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 09:51:05 +00:00
tcg: Improve move ops in liveness_pass_2
If the output of the move is dead, then the last use is in the store. If we propagate the input to the store, then we can remove the move opcode entirely. Backports commit 61f15c487fc2aea14f6b0e52c459ae8b7d252a65 from qemu
This commit is contained in:
parent
6b91e9bae1
commit
0e68fa345e
|
@ -2420,34 +2420,68 @@ static bool liveness_pass_2(TCGContext *s)
|
|||
}
|
||||
|
||||
/* Outputs become available. */
|
||||
for (i = 0; i < nb_oargs; i++) {
|
||||
arg_ts = arg_temp(op->args[i]);
|
||||
if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
|
||||
arg_ts = arg_temp(op->args[0]);
|
||||
dir_ts = arg_ts->state_ptr;
|
||||
if (!dir_ts) {
|
||||
continue;
|
||||
if (dir_ts) {
|
||||
op->args[0] = temp_arg(dir_ts);
|
||||
changes = true;
|
||||
|
||||
/* The output is now live and modified. */
|
||||
arg_ts->state = 0;
|
||||
|
||||
if (NEED_SYNC_ARG(0)) {
|
||||
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_st_i32
|
||||
: INDEX_op_st_i64);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc);
|
||||
TCGTemp *out_ts = dir_ts;
|
||||
|
||||
if (IS_DEAD_ARG(0)) {
|
||||
out_ts = arg_temp(op->args[1]);
|
||||
arg_ts->state = TS_DEAD;
|
||||
tcg_op_remove(s, op);
|
||||
} else {
|
||||
arg_ts->state = TS_MEM;
|
||||
}
|
||||
|
||||
sop->args[0] = temp_arg(out_ts);
|
||||
sop->args[1] = temp_arg(arg_ts->mem_base);
|
||||
sop->args[2] = arg_ts->mem_offset;
|
||||
} else {
|
||||
tcg_debug_assert(!IS_DEAD_ARG(0));
|
||||
}
|
||||
}
|
||||
op->args[i] = temp_arg(dir_ts);
|
||||
changes = true;
|
||||
} else {
|
||||
for (i = 0; i < nb_oargs; i++) {
|
||||
arg_ts = arg_temp(op->args[i]);
|
||||
dir_ts = arg_ts->state_ptr;
|
||||
if (!dir_ts) {
|
||||
continue;
|
||||
}
|
||||
op->args[i] = temp_arg(dir_ts);
|
||||
changes = true;
|
||||
|
||||
/* The output is now live and modified. */
|
||||
arg_ts->state = 0;
|
||||
/* The output is now live and modified. */
|
||||
arg_ts->state = 0;
|
||||
|
||||
/* Sync outputs upon their last write. */
|
||||
if (NEED_SYNC_ARG(i)) {
|
||||
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_st_i32
|
||||
: INDEX_op_st_i64);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc);
|
||||
/* Sync outputs upon their last write. */
|
||||
if (NEED_SYNC_ARG(i)) {
|
||||
TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
|
||||
? INDEX_op_st_i32
|
||||
: INDEX_op_st_i64);
|
||||
TCGOp *sop = tcg_op_insert_after(s, op, sopc);
|
||||
|
||||
sop->args[0] = temp_arg(dir_ts);
|
||||
sop->args[1] = temp_arg(arg_ts->mem_base);
|
||||
sop->args[2] = arg_ts->mem_offset;
|
||||
sop->args[0] = temp_arg(dir_ts);
|
||||
sop->args[1] = temp_arg(arg_ts->mem_base);
|
||||
sop->args[2] = arg_ts->mem_offset;
|
||||
|
||||
arg_ts->state = TS_MEM;
|
||||
}
|
||||
/* Drop outputs that are dead. */
|
||||
if (IS_DEAD_ARG(i)) {
|
||||
arg_ts->state = TS_DEAD;
|
||||
arg_ts->state = TS_MEM;
|
||||
}
|
||||
/* Drop outputs that are dead. */
|
||||
if (IS_DEAD_ARG(i)) {
|
||||
arg_ts->state = TS_DEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue