Revisión | 34f939218ce78163171addd63750e1e0300376ab (tree) |
---|---|
Tiempo | 2016-09-17 00:12:12 |
Autor | Pranith Kumar <bobby.prani@gmai...> |
Commiter | Richard Henderson |
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>
@@ -542,6 +542,7 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2) | ||
542 | 542 | void tcg_optimize(TCGContext *s) |
543 | 543 | { |
544 | 544 | int oi, oi_next, nb_temps, nb_globals; |
545 | + TCGArg *prev_mb_args = NULL; | |
545 | 546 | |
546 | 547 | /* Array VALS has an element for each temp. |
547 | 548 | If this temp holds a constant then its value is kept in VALS' element. |
@@ -1295,5 +1296,43 @@ void tcg_optimize(TCGContext *s) | ||
1295 | 1296 | } |
1296 | 1297 | break; |
1297 | 1298 | } |
1299 | + | |
1300 | + /* Eliminate duplicate and redundant fence instructions. */ | |
1301 | + if (prev_mb_args) { | |
1302 | + switch (opc) { | |
1303 | + case INDEX_op_mb: | |
1304 | + /* Merge two barriers of the same type into one, | |
1305 | + * or a weaker barrier into a stronger one, | |
1306 | + * or two weaker barriers into a stronger one. | |
1307 | + * mb X; mb Y => mb X|Y | |
1308 | + * mb; strl => mb; st | |
1309 | + * ldaq; mb => ld; mb | |
1310 | + * ldaq; strl => ld; mb; st | |
1311 | + * Other combinations are also merged into a strong | |
1312 | + * barrier. This is stricter than specified but for | |
1313 | + * the purposes of TCG is better than not optimizing. | |
1314 | + */ | |
1315 | + prev_mb_args[0] |= args[0]; | |
1316 | + tcg_op_remove(s, op); | |
1317 | + break; | |
1318 | + | |
1319 | + default: | |
1320 | + /* Opcodes that end the block stop the optimization. */ | |
1321 | + if ((def->flags & TCG_OPF_BB_END) == 0) { | |
1322 | + break; | |
1323 | + } | |
1324 | + /* fallthru */ | |
1325 | + case INDEX_op_qemu_ld_i32: | |
1326 | + case INDEX_op_qemu_ld_i64: | |
1327 | + case INDEX_op_qemu_st_i32: | |
1328 | + case INDEX_op_qemu_st_i64: | |
1329 | + case INDEX_op_call: | |
1330 | + /* Opcodes that touch guest memory stop the optimization. */ | |
1331 | + prev_mb_args = NULL; | |
1332 | + break; | |
1333 | + } | |
1334 | + } else if (opc == INDEX_op_mb) { | |
1335 | + prev_mb_args = args; | |
1336 | + } | |
1298 | 1337 | } |
1299 | 1338 | } |