summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-05-17 18:25:45 +0200
committerAurelien Jarno <aurelien@aurel32.net>2011-05-23 22:38:26 +0200
commit8c11ad25f40ee443000d2dbc0ef296ee210d86b4 (patch)
treec988cb3f41bb0c610e044a7dd115f9faef42b09e
parent6b64b624cde336f3df1146483e7858f5fa814f95 (diff)
downloadfocaccia-qemu-8c11ad25f40ee443000d2dbc0ef296ee210d86b4.tar.gz
focaccia-qemu-8c11ad25f40ee443000d2dbc0ef296ee210d86b4.zip
tcg: don't keep dead outputs in registers
If an op with dead outputs is not removed, because it has side effects
or has multiple output and only one dead, mark the registers as dead
instead of saving them. This avoid a few register spills on TCG targets
with low register count, especially with div2 and mul2 ops, or when a
qemu_ld* result is not used (prefetch emulation for example).

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--tcg/tcg.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 82d3e1db77..fad92f97c3 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1782,12 +1782,16 @@ static void tcg_reg_alloc_op(TCGContext *s,
             if (!ts->fixed_reg) {
                 if (ts->val_type == TEMP_VAL_REG)
                     s->reg_to_temp[ts->reg] = -1;
-                ts->val_type = TEMP_VAL_REG;
-                ts->reg = reg;
-                /* temp value is modified, so the value kept in memory is
-                   potentially not the same */
-                ts->mem_coherent = 0; 
-                s->reg_to_temp[reg] = arg;
+                if (IS_DEAD_ARG(i)) {
+                    ts->val_type = TEMP_VAL_DEAD;
+                } else {
+                    ts->val_type = TEMP_VAL_REG;
+                    ts->reg = reg;
+                    /* temp value is modified, so the value kept in memory is
+                       potentially not the same */
+                    ts->mem_coherent = 0;
+                    s->reg_to_temp[reg] = arg;
+               }
             }
         oarg_end:
             new_args[i] = reg;
@@ -1981,10 +1985,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
         } else {
             if (ts->val_type == TEMP_VAL_REG)
                 s->reg_to_temp[ts->reg] = -1;
-            ts->val_type = TEMP_VAL_REG;
-            ts->reg = reg;
-            ts->mem_coherent = 0; 
-            s->reg_to_temp[reg] = arg;
+            if (IS_DEAD_ARG(i)) {
+                ts->val_type = TEMP_VAL_DEAD;
+            } else {
+                ts->val_type = TEMP_VAL_REG;
+                ts->reg = reg;
+                ts->mem_coherent = 0;
+                s->reg_to_temp[reg] = arg;
+            }
         }
     }