@@ -1643,6 +1643,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
const TCGArg *args,
+ const int *param_next_use,
unsigned int dead_iargs)
{
TCGTemp *ts, *ots;
@@ -1669,6 +1670,9 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
}
if (ts->reg != reg) {
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[ts->reg] = param_next_use[1];
+#endif
tcg_out_mov(s, ots->type, reg, ts->reg);
}
}
@@ -1694,6 +1698,9 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
} else {
tcg_abort();
}
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[reg] = param_next_use[0];
+#endif
s->reg_to_temp[reg] = args[0];
ots->reg = reg;
ots->val_type = TEMP_VAL_REG;
@@ -1703,6 +1710,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
static void tcg_reg_alloc_op(TCGContext *s,
const TCGOpDef *def, TCGOpcode opc,
const TCGArg *args,
+ const int *param_next_use,
unsigned int dead_iargs)
{
TCGRegSet allocated_regs;
@@ -1776,6 +1784,9 @@ static void tcg_reg_alloc_op(TCGContext *s,
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_mov(s, ts->type, reg, ts->reg);
}
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[reg] = param_next_use[i];
+#endif
new_args[i] = reg;
const_args[i] = 0;
tcg_regset_set_reg(allocated_regs, reg);
@@ -1845,6 +1856,9 @@ static void tcg_reg_alloc_op(TCGContext *s,
}
oarg_end:
new_args[i] = reg;
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[reg] = param_next_use[i];
+#endif
}
}
@@ -1869,6 +1883,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
TCGOpcode opc, const TCGArg *args,
+ const int *param_next_use,
unsigned int dead_iargs)
{
int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
@@ -1953,6 +1968,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
tcg_abort();
}
tcg_regset_set_reg(allocated_regs, reg);
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[reg] = param_next_use[nb_oargs + i];
+#endif
}
}
@@ -2039,6 +2057,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
ts->reg = reg;
ts->mem_coherent = 0;
s->reg_to_temp[reg] = arg;
+#ifdef USE_ADVANCED_REGALLOC
+ s->reg_next_use[reg] = param_next_use[i];
+#endif
}
}
@@ -2068,6 +2089,8 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
TCGOpcode opc;
int op_index;
const TCGOpDef *def;
+ const int *param_next_use_ptr;
+ int nb_args;
unsigned int dead_iargs;
const TCGArg *args;
@@ -2095,6 +2118,8 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
}
#endif
+ param_next_use_ptr = s->param_next_use;
+
tcg_reg_alloc_start(s);
s->code_buf = gen_code_buf;
@@ -2120,7 +2145,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
case INDEX_op_mov_i64:
#endif
dead_iargs = s->op_dead_iargs[op_index];
- tcg_reg_alloc_mov(s, def, args, dead_iargs);
+ tcg_reg_alloc_mov(s, def, args, param_next_use_ptr, dead_iargs);
break;
case INDEX_op_movi_i32:
#if TCG_TARGET_REG_BITS == 64
@@ -2137,6 +2162,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
case INDEX_op_nop3:
break;
case INDEX_op_nopn:
+ param_next_use_ptr += args[0];
args += args[0];
goto next;
case INDEX_op_discard:
@@ -2157,7 +2183,10 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
break;
case INDEX_op_call:
dead_iargs = s->op_dead_iargs[op_index];
- args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
+ nb_args = tcg_reg_alloc_call(s, def, opc, args,
+ param_next_use_ptr, dead_iargs);
+ args += nb_args;
+ param_next_use_ptr += nb_args;
goto next;
case INDEX_op_end:
goto the_end;
@@ -2166,10 +2195,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
faster to have specialized register allocator functions for
some common argument patterns */
dead_iargs = s->op_dead_iargs[op_index];
- tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
+ tcg_reg_alloc_op(s, def, opc, args, param_next_use_ptr, dead_iargs);
break;
}
args += def->nb_args;
+ param_next_use_ptr += def->nb_args;
next:
if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
return op_index;
Propagate next use of each register through process of register allocation. This would be needed to do a better spill choice. Signed-off-by: Kirill Batuzov <batuzovk@ispras.ru> --- tcg/tcg.c | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-)