qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC][PATCH] tcg: allocate memory to spill registers on startup
Date: Fri, 10 Apr 2009 10:54:06 +0200	[thread overview]
Message-ID: <20090410085406.GA15094@volta.aurel32.net> (raw)

Currently the memory used to spill registers is allocated on demand from
a frame, and deallocated at the beginning of each TB.

This patch changes that so that the memory is allocated only once at
startup. As we don't know what will be the usage of the registers, this
increase the size of cpu_env by 1.5 kB of memory on 32-bit hosts and
3 kB of memory on 64-bit hosts. Those values can probably be reduced
later as I doubt any target is actually using 512 TCG registers (256
looks a saner value). On the other hand, this makes sure we always have
enough available memory to spill registers.

There is a small speed gain between 0.2 and 0.4%, but the most
important is that it makes the code simpler and more readable. This also
allow saving variables into memory from tcg-target.c (for the yet to
come slow path optimization).

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-defs.h |    2 +-
 tcg/tcg.c  |   36 +++++++++++-------------------------
 tcg/tcg.h  |    5 -----
 3 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index b462a9f..9c2fcec 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -158,7 +158,7 @@ typedef struct CPUWatchpoint {
     TAILQ_ENTRY(CPUWatchpoint) entry;
 } CPUWatchpoint;
 
-#define CPU_TEMP_BUF_NLONGS 128
+#define CPU_TEMP_BUF_NLONGS 512
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c64043f..d2e720f 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -245,9 +245,17 @@ void tcg_context_init(TCGContext *s)
 void tcg_set_frame(TCGContext *s, int reg,
                    tcg_target_long start, tcg_target_long size)
 {
-    s->frame_start = start;
-    s->frame_end = start + size;
-    s->frame_reg = reg;
+    int i;
+
+    assert(size != TCG_MAX_TEMPS * sizeof(tcg_target_long));
+
+    for (i = 0 ; i < TCG_MAX_TEMPS ; i++) {
+        TCGTemp *ts;
+        ts = &s->temps[i];
+        ts->mem_reg = reg;
+        ts->mem_offset = start;
+        start += sizeof(tcg_target_long);
+    }
 }
 
 void tcg_func_start(TCGContext *s)
@@ -259,7 +267,6 @@ void tcg_func_start(TCGContext *s)
         s->first_free_temp[i] = -1;
     s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
     s->nb_labels = 0;
-    s->current_frame_offset = s->frame_start;
 
     gen_opc_ptr = gen_opc_buf;
     gen_opparam_ptr = gen_opparam_buf;
@@ -330,7 +337,6 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
         ts->base_type = type;
         ts->type = TCG_TYPE_I32;
         ts->fixed_reg = 0;
-        ts->mem_allocated = 1;
         ts->mem_reg = reg;
 #ifdef TCG_TARGET_WORDS_BIGENDIAN
         ts->mem_offset = offset + 4;
@@ -345,7 +351,6 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
         ts->base_type = type;
         ts->type = TCG_TYPE_I32;
         ts->fixed_reg = 0;
-        ts->mem_allocated = 1;
         ts->mem_reg = reg;
 #ifdef TCG_TARGET_WORDS_BIGENDIAN
         ts->mem_offset = offset;
@@ -365,7 +370,6 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
         ts->base_type = type;
         ts->type = type;
         ts->fixed_reg = 0;
-        ts->mem_allocated = 1;
         ts->mem_reg = reg;
         ts->mem_offset = offset;
         ts->name = name;
@@ -679,7 +683,6 @@ static void tcg_reg_alloc_start(TCGContext *s)
     for(i = s->nb_globals; i < s->nb_temps; i++) {
         ts = &s->temps[i];
         ts->val_type = TEMP_VAL_DEAD;
-        ts->mem_allocated = 0;
         ts->fixed_reg = 0;
     }
     for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
@@ -1302,19 +1305,6 @@ static void check_regs(TCGContext *s)
 }
 #endif
 
-static void temp_allocate_frame(TCGContext *s, int temp)
-{
-    TCGTemp *ts;
-    ts = &s->temps[temp];
-    s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
-    if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
-        tcg_abort();
-    ts->mem_offset = s->current_frame_offset;
-    ts->mem_reg = s->frame_reg;
-    ts->mem_allocated = 1;
-    s->current_frame_offset += sizeof(tcg_target_long);
-}
-
 /* free register 'reg' by spilling the corresponding temporary if necessary */
 static void tcg_reg_free(TCGContext *s, int reg)
 {
@@ -1326,8 +1316,6 @@ static void tcg_reg_free(TCGContext *s, int reg)
         ts = &s->temps[temp];
         assert(ts->val_type == TEMP_VAL_REG);
         if (!ts->mem_coherent) {
-            if (!ts->mem_allocated) 
-                temp_allocate_frame(s, temp);
             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
         }
         ts->val_type = TEMP_VAL_MEM;
@@ -1381,8 +1369,6 @@ static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
         case TEMP_VAL_CONST:
             reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 
                                 allocated_regs);
-            if (!ts->mem_allocated) 
-                temp_allocate_frame(s, temp);
             tcg_out_movi(s, ts->type, reg, ts->val);
             tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
             ts->val_type = TEMP_VAL_MEM;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index bf95d7e..1fd3c25 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -217,7 +217,6 @@ typedef struct TCGTemp {
     tcg_target_long mem_offset;
     unsigned int fixed_reg:1;
     unsigned int mem_coherent:1;
-    unsigned int mem_allocated:1;
     unsigned int temp_local:1; /* If true, the temp is saved accross
                                   basic blocks. Otherwise, it is not
                                   preserved accross basic blocks. */
@@ -259,10 +258,6 @@ struct TCGContext {
        into account fixed registers */
     int reg_to_temp[TCG_TARGET_NB_REGS];
     TCGRegSet reserved_regs;
-    tcg_target_long current_frame_offset;
-    tcg_target_long frame_start;
-    tcg_target_long frame_end;
-    int frame_reg;
 
     uint8_t *code_ptr;
     TCGTemp static_temps[TCG_MAX_TEMPS];
-- 
1.6.1.3


-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

             reply	other threads:[~2009-04-10  8:54 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-10  8:54 Aurelien Jarno [this message]
2009-04-10 14:44 ` [Qemu-devel] [RFC][PATCH] tcg: allocate memory to spill registers on startup Paul Brook
2009-04-10 14:56   ` Aurelien Jarno
2009-04-10 15:20     ` Paul Brook
2009-04-10 15:31       ` Aurelien Jarno
2009-04-10 15:52         ` Paul Brook
2009-04-10 16:06           ` Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090410085406.GA15094@volta.aurel32.net \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).