diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2012-10-09 21:53:08 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2012-10-28 14:54:23 +0100 |
commit | 78505279665e64d28e4a308818b69e6f77ecc5d2 (patch) | |
tree | 92a449ff75f77f4dcc04b5705a50beaa851c0a76 /tcg/tcg.c | |
parent | 3d5c5f876d171983d614925eebe4f0edccbb75be (diff) | |
download | qemu-78505279665e64d28e4a308818b69e6f77ecc5d2.zip qemu-78505279665e64d28e4a308818b69e6f77ecc5d2.tar.gz qemu-78505279665e64d28e4a308818b69e6f77ecc5d2.tar.bz2 |
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>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r-- | tcg/tcg.c | 24 |
1 files changed, 16 insertions, 8 deletions
@@ -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); } |