Patchwork [v2,13/26] tcg: synchronize globals for ops with side effects

login
register
mail settings
Submitter Aurelien Jarno
Date Oct. 9, 2012, 7:56 p.m.
Message ID <1349812584-19551-14-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/190439/
State New
Headers show

Comments

Aurelien Jarno - Oct. 9, 2012, 7:56 p.m.
Operations with side effects (in practice qemu_ld/st ops), only need to
synchronize globals to make sure the CPU state is consistent in case of
exception.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 tcg/tcg.c |   33 ++++++++++++++++++++++++---------
 tcg/tcg.h |    4 ++--
 2 files changed, 26 insertions(+), 11 deletions(-)
Richard Henderson - Oct. 10, 2012, 5:01 p.m.
On 10/09/2012 12:56 PM, Aurelien Jarno wrote:
> Operations with side effects (in practice qemu_ld/st ops), only need to
> synchronize globals to make sure the CPU state is consistent in case of
> exception.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

Patch

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3983ec3..3f30fb1 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1360,9 +1360,8 @@  static void tcg_liveness_analysis(TCGContext *s)
                 /* if end of basic block, update */
                 if (def->flags & TCG_OPF_BB_END) {
                     tcg_la_bb_end(s, dead_temps, mem_temps);
-                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
-                    /* globals should go back to memory */
-                    memset(dead_temps, 1, s->nb_globals);
+                } else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
+                    /* globals should be synced to memory */
                     memset(mem_temps, 1, s->nb_globals);
                 }
 
@@ -1623,6 +1622,23 @@  static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
     }
 }
 
+/* sync globals to their canonical location and assume they can be
+   read by the following code. 'allocated_regs' is used in case a
+   temporary registers needs to be allocated to store a constant. */
+static void sync_globals(TCGContext *s, TCGRegSet allocated_regs)
+{
+    int i;
+
+    for (i = 0; i < s->nb_globals; i++) {
+#ifdef USE_LIVENESS_ANALYSIS
+        assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg ||
+               s->temps[i].mem_coherent);
+#else
+        temp_sync(s, i, allocated_regs);
+#endif
+    }
+}
+
 /* at the end of a basic block, we assume all temporaries are dead and
    all globals are stored at their canonical location. */
 static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
@@ -1860,12 +1876,11 @@  static void tcg_reg_alloc_op(TCGContext *s,
                     tcg_reg_free(s, reg);
                 }
             }
-            /* XXX: for load/store we could do that only for the slow path
-               (i.e. when a memory callback is called) */
-            
-            /* store globals and free associated registers (we assume the insn
-               can modify any global. */
-            save_globals(s, allocated_regs);
+        }
+        if (def->flags & TCG_OPF_SIDE_EFFECTS) {
+            /* sync globals if the op has side effects and might trigger
+               an exception. */
+            sync_globals(s, allocated_regs);
         }
         
         /* satisfy the output constraints */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 73d3769..fb6d9ea 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -530,8 +530,8 @@  enum {
     TCG_OPF_BB_END       = 0x01,
     /* Instruction clobbers call registers and potentially update globals.  */
     TCG_OPF_CALL_CLOBBER = 0x02,
-    /* Instruction has side effects: it cannot be removed
-       if its outputs are not used.  */
+    /* Instruction has side effects: it cannot be removed if its outputs
+       are not used, and might trigger exceptions.  */
     TCG_OPF_SIDE_EFFECTS = 0x04,
     /* Instruction operands are 64-bits (otherwise 32-bits).  */
     TCG_OPF_64BIT        = 0x08,