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.] Signed-off-by: Pranith Kumar <bobby.prani@gmail.com> Message-Id: <20160823134825.32578-1-bobby.prani@gmail.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
cc19e497a0
commit
34f939218c
@ -542,6 +542,7 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
|
||||
void tcg_optimize(TCGContext *s)
|
||||
{
|
||||
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.
|
||||
@ -1295,5 +1296,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 New Issue
Block a user