tcg: rework TCG helper flags

The current helper flags, TCG_CALL_CONST and TCG_CALL_PURE might be
confusing and doesn't provide enough granularity for some helpers (FP
helpers for example).

This patch changes them into the following helpers flags:
- TCG_CALL_NO_READ_GLOBALS means that the helper does not read globals,
  either directly or via an exception. They will not be saved to their
  canonical location before calling the helper.
- TCG_CALL_NO_WRITE_GLOBALS means that the helper does not modify any
  globals. They will only be saved to their canonical locations before
  calling helpers, but they won't be reloaded afterwise.
- TCG_CALL_NO_SIDE_EFFECTS means that the call to the function is
  removed if the return value is not used.

It provides convenience flags, to avoid helper definitions longer than
80 characters. It also provides compatibility flags, and updates the
documentation.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2012-10-09 21:53:08 +02:00
parent 3d5c5f876d
commit 7850527966
5 changed files with 60 additions and 30 deletions

View file

@ -1251,7 +1251,7 @@ static void tcg_liveness_analysis(TCGContext *s)
/* pure functions can be removed if their result is not
used */
if (call_flags & TCG_CALL_PURE) {
if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
for(i = 0; i < nb_oargs; i++) {
arg = args[i];
if (!dead_temps[arg] || mem_temps[arg]) {
@ -1277,11 +1277,15 @@ static void tcg_liveness_analysis(TCGContext *s)
dead_temps[arg] = 1;
mem_temps[arg] = 0;
}
if (!(call_flags & TCG_CALL_CONST)) {
if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) {
/* globals should be synced to memory */
memset(mem_temps, 1, s->nb_globals);
}
if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS |
TCG_CALL_NO_READ_GLOBALS))) {
/* globals should go back to memory */
memset(dead_temps, 1, s->nb_globals);
memset(mem_temps, 1, s->nb_globals);
}
/* input args are live */
@ -2128,10 +2132,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
tcg_reg_free(s, reg);
}
}
/* store globals and free associated registers (we assume the call
can modify any global. */
if (!(flags & TCG_CALL_CONST)) {
/* Save globals if they might be written by the helper, sync them if
they might be read. */
if (flags & TCG_CALL_NO_READ_GLOBALS) {
/* Nothing to do */
} else if (flags & TCG_CALL_NO_WRITE_GLOBALS) {
sync_globals(s, allocated_regs);
} else {
save_globals(s, allocated_regs);
}