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 <batuz...@ispras.ru> --- tcg/tcg.c | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 821ffa7..c6e920e 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -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; -- 1.7.4.1