qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 12/14] tcg: Store pointers to temporaries directly in


From: Richard Henderson
Subject: [Qemu-devel] [RFC 12/14] tcg: Store pointers to temporaries directly in TCGArg
Date: Wed, 16 Nov 2016 20:51:48 +0100

Signed-off-by: Richard Henderson <address@hidden>
---
 tcg/optimize.c | 103 +++++++++++++++++++++++++++++++--------------------------
 tcg/tcg.c      |  28 ++++++++++------
 tcg/tcg.h      |  20 +++++------
 3 files changed, 84 insertions(+), 67 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 0e5d9d8..06a8c13 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -33,19 +33,24 @@
         glue(glue(case INDEX_op_, x), _i64)
 
 struct tcg_temp_info {
-    bool is_const;
-    uint16_t prev_copy;
-    uint16_t next_copy;
+    TCGTemp *prev_copy;
+    TCGTemp *next_copy;
     tcg_target_ulong val;
     tcg_target_ulong mask;
+    bool is_const;
 };
 
 static struct tcg_temp_info temps[TCG_MAX_TEMPS];
 static TCGTempSet temps_used;
 
+static inline struct tcg_temp_info *ts_info(TCGTemp *ts)
+{
+    return ts->state_ptr;
+}
+
 static inline struct tcg_temp_info *temp_info(TCGArg arg)
 {
-    return &temps[arg];
+    return ts_info(arg_temp(arg));
 }
 
 static inline bool temp_is_const(TCGArg arg)
@@ -55,20 +60,20 @@ static inline bool temp_is_const(TCGArg arg)
 
 static inline bool temp_is_copy(TCGArg arg)
 {
-    return temp_info(arg)->next_copy != arg;
+    return temp_info(arg)->next_copy != arg_temp(arg);
 }
 
 /* Reset TEMP's state, possibly removing the temp for the list of copies.  */
-static void reset_temp(TCGArg temp)
+static void reset_temp(TCGTemp *ts)
 {
-    struct tcg_temp_info *ti = temp_info(temp);
-    struct tcg_temp_info *pi = temp_info(ti->prev_copy);
-    struct tcg_temp_info *ni = temp_info(ti->next_copy);
+    struct tcg_temp_info *ti = ts_info(ts);
+    struct tcg_temp_info *pi = ts_info(ti->prev_copy);
+    struct tcg_temp_info *ni = ts_info(ti->next_copy);
 
     ni->prev_copy = ti->prev_copy;
     pi->next_copy = ti->next_copy;
-    ti->next_copy = temp;
-    ti->prev_copy = temp;
+    ti->next_copy = ts;
+    ti->prev_copy = ts;
     ti->is_const = false;
     ti->mask = -1;
 }
@@ -82,13 +87,16 @@ static void reset_all_temps(int nb_temps)
 /* Initialize and activate a temporary.  */
 static void init_temp_info(TCGArg temp)
 {
-    if (!test_bit(temp, temps_used.l)) {
-        struct tcg_temp_info *ti = temp_info(temp);
-        ti->next_copy = temp;
-        ti->prev_copy = temp;
+    size_t idx = arg_index(temp);
+    if (!test_bit(idx, temps_used.l)) {
+        TCGTemp *ts = arg_temp(temp);
+        struct tcg_temp_info *ti = &temps[idx];
+        ts->state_ptr = ti;
+        ti->next_copy = ts;
+        ti->prev_copy = ts;
         ti->is_const = false;
         ti->mask = -1;
-        set_bit(temp, temps_used.l);
+        set_bit(idx, temps_used.l);
     }
 }
 
@@ -128,27 +136,26 @@ static TCGOpcode op_to_movi(TCGOpcode op)
 
 static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
 {
-    TCGArg i;
+    TCGTemp *ts = arg_temp(temp);
+    TCGTemp *i;
 
     /* If this is already a global, we can't do better. */
-    if (temp < s->nb_globals) {
+    if (ts->temp_global) {
         return temp;
     }
 
     /* Search for a global first. */
-    for (i = temp_info(temp)->next_copy; i != temp;
-         i = temp_info(i)->next_copy) {
-        if (i < s->nb_globals) {
-            return i;
+    for (i = ts_info(ts)->next_copy; i != ts; i = ts_info(i)->next_copy) {
+        if (i->temp_global) {
+            return (uintptr_t)i;
         }
     }
 
     /* If it is a temp, search for a temp local. */
-    if (!s->temps[temp].temp_local) {
-        for (i = temp_info(temp)->next_copy; i != temp;
-             i = temp_info(i)->next_copy) {
-            if (s->temps[i].temp_local) {
-                return i;
+    if (!ts->temp_local) {
+        for (i = ts_info(ts)->next_copy; i != ts; i = ts_info(i)->next_copy) {
+            if (i->temp_local) {
+                return (uintptr_t)i;
             }
         }
     }
@@ -159,7 +166,9 @@ static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
 
 static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
 {
-    TCGArg i;
+    TCGTemp *t1 = arg_temp(arg1);
+    TCGTemp *t2 = arg_temp(arg2);
+    TCGTemp *i;
 
     if (arg1 == arg2) {
         return true;
@@ -169,9 +178,8 @@ static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
         return false;
     }
 
-    for (i = temp_info(arg1)->next_copy; i != arg1;
-         i = temp_info(i)->next_copy) {
-        if (i == arg2) {
+    for (i = ts_info(t1)->next_copy; i != t1; i = ts_info(i)->next_copy) {
+        if (i == t2) {
             return true;
         }
     }
@@ -184,11 +192,12 @@ static void tcg_opt_gen_movi(TCGContext *s, TCGOp *op, 
TCGArg *args,
 {
     TCGOpcode new_op = op_to_movi(op->opc);
     tcg_target_ulong mask;
-    struct tcg_temp_info *di = temp_info(dst);
+    TCGTemp *ds = arg_temp(dst);
+    struct tcg_temp_info *di = ts_info(ds);
 
     op->opc = new_op;
 
-    reset_temp(dst);
+    reset_temp(ds);
     di->is_const = true;
     di->val = val;
     mask = val;
@@ -210,14 +219,16 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
         return;
     }
 
-    struct tcg_temp_info *di = temp_info(dst);
-    struct tcg_temp_info *si = temp_info(src);
+    TCGTemp *ds = arg_temp(dst);
+    TCGTemp *ss = arg_temp(src);
+    struct tcg_temp_info *di = ts_info(ds);
+    struct tcg_temp_info *si = ts_info(ss);
     TCGOpcode new_op = op_to_mov(op->opc);
     tcg_target_ulong mask;
 
     op->opc = new_op;
 
-    reset_temp(dst);
+    reset_temp(ds);
     mask = si->mask;
     if (TCG_TARGET_REG_BITS > 32 && new_op == INDEX_op_mov_i32) {
         /* High bits of the destination are now garbage.  */
@@ -225,11 +236,11 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, 
TCGArg *args,
     }
     di->mask = mask;
 
-    if (s->temps[src].type == s->temps[dst].type) {
+    if (ss->type == ds->type) {
         di->next_copy = si->next_copy;
-        di->prev_copy = src;
-        temp_info(di->next_copy)->prev_copy = dst;
-        si->next_copy = dst;
+        di->prev_copy = ss;
+        ts_info(di->next_copy)->prev_copy = ds;
+        si->next_copy = ds;
         di->is_const = si->is_const;
         di->val = si->val;
     }
@@ -702,7 +713,7 @@ void tcg_optimize(TCGContext *s)
                 }
                 if (temp_is_const(args[1]) && temp_info(args[1])->val == 0) {
                     op->opc = neg_op;
-                    reset_temp(args[0]);
+                    reset_temp(arg_temp(args[0]));
                     args[1] = args[2];
                     continue;
                 }
@@ -758,7 +769,7 @@ void tcg_optimize(TCGContext *s)
                     break;
                 }
                 op->opc = not_op;
-                reset_temp(args[0]);
+                reset_temp(arg_temp(args[0]));
                 args[1] = args[i];
                 continue;
             }
@@ -1270,7 +1281,7 @@ void tcg_optimize(TCGContext *s)
                 /* Simplify LT/GE comparisons vs zero to a single compare
                    vs the high word of the input.  */
             do_setcond_high:
-                reset_temp(args[0]);
+                reset_temp(arg_temp(args[0]));
                 temp_info(args[0])->mask = 1;
                 op->opc = INDEX_op_setcond_i32;
                 args[1] = args[2];
@@ -1294,7 +1305,7 @@ void tcg_optimize(TCGContext *s)
                     goto do_default;
                 }
             do_setcond_low:
-                reset_temp(args[0]);
+                reset_temp(arg_temp(args[0]));
                 temp_info(args[0])->mask = 1;
                 op->opc = INDEX_op_setcond_i32;
                 args[2] = args[3];
@@ -1327,7 +1338,7 @@ void tcg_optimize(TCGContext *s)
                   & (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
                 for (i = 0; i < nb_globals; i++) {
                     if (test_bit(i, temps_used.l)) {
-                        reset_temp(i);
+                        reset_temp(&s->temps[i]);
                     }
                 }
             }
@@ -1345,7 +1356,7 @@ void tcg_optimize(TCGContext *s)
             } else {
         do_reset_output:
                 for (i = 0; i < nb_oargs; i++) {
-                    reset_temp(args[i]);
+                    reset_temp(arg_temp(args[i]));
                     /* Save the corresponding known-zero bits mask for the
                        first output argument (only one supported so far). */
                     if (i == 0) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c62f161..a2a0b90 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -773,11 +773,11 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
 #else
         if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
 #ifdef HOST_WORDS_BIGENDIAN
-            s->gen_opparam_buf[pi++] = ret + 1;
+            s->gen_opparam_buf[pi++] = ret + sizeof(TCGTemp);
             s->gen_opparam_buf[pi++] = ret;
 #else
             s->gen_opparam_buf[pi++] = ret;
-            s->gen_opparam_buf[pi++] = ret + 1;
+            s->gen_opparam_buf[pi++] = ret + sizeof(TCGTemp);
 #endif
             nb_rets = 2;
         } else {
@@ -810,11 +810,11 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
               have to get more complicated to differentiate between
               stack arguments and register arguments.  */
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
-            s->gen_opparam_buf[pi++] = args[i] + 1;
+            s->gen_opparam_buf[pi++] = args[i] + sizeof(TCGTemp);
             s->gen_opparam_buf[pi++] = args[i];
 #else
             s->gen_opparam_buf[pi++] = args[i];
-            s->gen_opparam_buf[pi++] = args[i] + 1;
+            s->gen_opparam_buf[pi++] = args[i] + sizeof(TCGTemp);
 #endif
             real_args += 2;
             continue;
@@ -1633,7 +1633,7 @@ static void liveness_pass_1(TCGContext *s)
 static bool liveness_pass_2(TCGContext *s)
 {
     int nb_globals = s->nb_globals;
-    int i, oi, oi_next;
+    int i, oi, oi_next, n;
     bool changes = false;
 
     /* Create a temporary for each indirect global.  */
@@ -1644,10 +1644,16 @@ static bool liveness_pass_2(TCGContext *s)
             dts->type = its->type;
             dts->base_type = its->base_type;
             its->state_ptr = dts;
+        } else {
+            its->state_ptr = NULL;
         }
         /* All globals begin dead.  */
         its->state = TS_DEAD;
     }
+    for (n = s->nb_temps; i < n; ++i) {
+        TCGTemp *its = &s->temps[i];
+        its->state_ptr = NULL;
+    }
 
     for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
         TCGOp *op = &s->gen_op_buf[oi];
@@ -1695,8 +1701,8 @@ static bool liveness_pass_2(TCGContext *s)
                     TCGOp *lop = tcg_op_insert_before(s, op, lopc, 3);
                     TCGArg *largs = &s->gen_opparam_buf[lop->args];
 
-                    largs[0] = temp_idx(dir_ts);
-                    largs[1] = temp_idx(arg_ts->mem_base);
+                    largs[0] = (uintptr_t)dir_ts;
+                    largs[1] = (uintptr_t)arg_ts->mem_base;
                     largs[2] = arg_ts->mem_offset;
 
                     /* Loaded, but synced with memory.  */
@@ -1713,7 +1719,7 @@ static bool liveness_pass_2(TCGContext *s)
             if (arg_ts) {
                 dir_ts = arg_ts->state_ptr;
                 if (dir_ts) {
-                    args[i] = temp_idx(dir_ts);
+                    args[i] = (uintptr_t)dir_ts;
                     changes = true;
                     if (IS_DEAD_ARG(i)) {
                         arg_ts->state = TS_DEAD;
@@ -1755,7 +1761,7 @@ static bool liveness_pass_2(TCGContext *s)
             if (dir_ts == 0) {
                 continue;
             }
-            args[i] = temp_idx(dir_ts);
+            args[i] = (uintptr_t)dir_ts;
             changes = true;
 
             /* The output is now live and modified.  */
@@ -1769,8 +1775,8 @@ static bool liveness_pass_2(TCGContext *s)
                 TCGOp *sop = tcg_op_insert_after(s, op, sopc, 3);
                 TCGArg *sargs = &s->gen_opparam_buf[sop->args];
 
-                sargs[0] = temp_idx(dir_ts);
-                sargs[1] = temp_idx(arg_ts->mem_base);
+                sargs[0] = (uintptr_t)dir_ts;
+                sargs[1] = (uintptr_t)arg_ts->mem_base;
                 sargs[2] = arg_ts->mem_offset;
 
                 arg_ts->state = TS_MEM;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 2670cab..730c2d5 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -705,44 +705,44 @@ static inline uintptr_t temp_idx(TCGTemp *ts)
     return n;
 }
 
-static inline size_t arg_index(TCGArg a)
+static inline TCGTemp *arg_temp(TCGArg a)
 {
-    return a;
+    return (TCGTemp *)(uintptr_t)a;
 }
 
-static inline TCGTemp *arg_temp(TCGArg a)
+static inline size_t arg_index(TCGArg a)
 {
-    return &tcg_ctx.temps[a];
+    return temp_idx(arg_temp(a));
 }
 
 static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(uintptr_t i)
 {
-    return (TCGv_i32)&tcg_ctx.temps[i];
+    return (TCGv_i32)i;
 }
 
 static inline TCGv_i64 QEMU_ARTIFICIAL MAKE_TCGV_I64(uintptr_t i)
 {
-    return (TCGv_i64)&tcg_ctx.temps[i];
+    return (TCGv_i64)i;
 }
 
 static inline TCGv_ptr QEMU_ARTIFICIAL MAKE_TCGV_PTR(uintptr_t i)
 {
-    return (TCGv_ptr)&tcg_ctx.temps[i];
+    return (TCGv_ptr)i;
 }
 
 static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_I32(TCGv_i32 t)
 {
-    return temp_idx((TCGTemp *)t);
+    return (uintptr_t)t;
 }
 
 static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_I64(TCGv_i64 t)
 {
-    return temp_idx((TCGTemp *)t);
+    return (uintptr_t)t;
 }
 
 static inline uintptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t)
 {
-    return temp_idx((TCGTemp *)t);
+    return (uintptr_t)t;
 }
 
 static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]