mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-23 06:25:12 +00:00
tcg: Optimize fence instructions
This commit optimizes fence instructions. Two optimizations are currently implemented: (1) unnecessary duplicate fence instructions, and (2) merging weaker fences into a stronger fence. [rth: Merge tcg_optimize_mb back into tcg_optimize, so that we only loop over the opcode stream once. Merge "unrelated" weaker barriers into one stronger barrier.] Backports commit 34f939218ce78163171addd63750e1e0300376ab from qemu
This commit is contained in:
parent
533e083495
commit
16d71f0f10
|
@ -553,6 +553,7 @@ void tcg_optimize(TCGContext *s)
|
|||
{
|
||||
struct tcg_temp_info *temps = s->temps2;
|
||||
int oi, oi_next, nb_temps, nb_globals;
|
||||
TCGArg *prev_mb_args = NULL;
|
||||
|
||||
/* Array VALS has an element for each temp.
|
||||
If this temp holds a constant then its value is kept in VALS' element.
|
||||
|
@ -1306,5 +1307,43 @@ void tcg_optimize(TCGContext *s)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Eliminate duplicate and redundant fence instructions. */
|
||||
if (prev_mb_args) {
|
||||
switch (opc) {
|
||||
case INDEX_op_mb:
|
||||
/* Merge two barriers of the same type into one,
|
||||
* or a weaker barrier into a stronger one,
|
||||
* or two weaker barriers into a stronger one.
|
||||
* mb X; mb Y => mb X|Y
|
||||
* mb; strl => mb; st
|
||||
* ldaq; mb => ld; mb
|
||||
* ldaq; strl => ld; mb; st
|
||||
* Other combinations are also merged into a strong
|
||||
* barrier. This is stricter than specified but for
|
||||
* the purposes of TCG is better than not optimizing.
|
||||
*/
|
||||
prev_mb_args[0] |= args[0];
|
||||
tcg_op_remove(s, op);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Opcodes that end the block stop the optimization. */
|
||||
if ((def->flags & TCG_OPF_BB_END) == 0) {
|
||||
break;
|
||||
}
|
||||
/* fallthru */
|
||||
case INDEX_op_qemu_ld_i32:
|
||||
case INDEX_op_qemu_ld_i64:
|
||||
case INDEX_op_qemu_st_i32:
|
||||
case INDEX_op_qemu_st_i64:
|
||||
case INDEX_op_call:
|
||||
/* Opcodes that touch guest memory stop the optimization. */
|
||||
prev_mb_args = NULL;
|
||||
break;
|
||||
}
|
||||
} else if (opc == INDEX_op_mb) {
|
||||
prev_mb_args = args;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue