tcg: Allocate indirect_base temporaries in a different order

Since we've not got liveness analysis for indirect bases,
placing them at the end of the call-saved registers makes
it more likely that it'll stay live.

Backports commit 91478cefaaf2fa678e56df8635b34957f4d5d565 from qemu
This commit is contained in:
Richard Henderson 2018-02-20 19:24:31 -05:00 committed by Lioncash
parent bf385eba3c
commit 3653771265
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 33 additions and 11 deletions

View file

@ -352,6 +352,21 @@ void tcg_context_init(TCGContext *s)
}
tcg_target_init(s);
/* Reverse the order of the saved registers, assuming they're all at
the start of tcg_target_reg_alloc_order. */
for (n = 0; n < ARRAY_SIZE(tcg_target_reg_alloc_order); ++n) {
int r = tcg_target_reg_alloc_order[n];
if (tcg_regset_test_reg(s->tcg_target_call_clobber_regs, r)) {
break;
}
}
for (i = 0; i < n; ++i) {
s->indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[n - 1 - i];
}
for (; i < ARRAY_SIZE(tcg_target_reg_alloc_order); ++i) {
s->indirect_reg_alloc_order[i] = tcg_target_reg_alloc_order[i];
}
}
void tcg_prologue_init(TCGContext *s)
@ -1764,24 +1779,26 @@ static void tcg_reg_free(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)
/* Allocate a register belonging to reg1 & ~reg2 */
static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
TCGRegSet allocated_regs)
TCGRegSet allocated_regs, bool rev)
{
int i;
int i, n = ARRAY_SIZE(tcg_target_reg_alloc_order);
const int *order;
TCGReg reg;
TCGRegSet reg_ct;
tcg_regset_andnot(reg_ct, desired_regs, allocated_regs);
order = rev ? s->indirect_reg_alloc_order : tcg_target_reg_alloc_order;
/* first try free registers */
for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
reg = tcg_target_reg_alloc_order[i];
for(i = 0; i < n; i++) {
reg = order[i];
if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == NULL)
return reg;
}
/* XXX: do better spill choice */
for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
reg = tcg_target_reg_alloc_order[i];
for(i = 0; i < n; i++) {
reg = order[i];
if (tcg_regset_test_reg(reg_ct, reg)) {
tcg_reg_free(s, reg, allocated_regs);
return reg;
@ -1802,12 +1819,12 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
case TEMP_VAL_REG:
return;
case TEMP_VAL_CONST:
reg = tcg_reg_alloc(s, desired_regs, allocated_regs);
reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
tcg_out_movi(s, ts->type, reg, ts->val);
ts->mem_coherent = 0;
break;
case TEMP_VAL_MEM:
reg = tcg_reg_alloc(s, desired_regs, allocated_regs);
reg = tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirect_base);
if (ts->indirect_reg) {
tcg_regset_set_reg(allocated_regs, reg);
temp_load(s, ts->mem_base,
@ -2042,7 +2059,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
input one. */
tcg_regset_set_reg(allocated_regs, ts->reg);
ots->reg = tcg_reg_alloc(s, (TCGRegSet)s->tcg_target_available_regs[otype],
allocated_regs);
allocated_regs, ots->indirect_base);
}
tcg_out_mov(s, otype, ots->reg, ts->reg);
}
@ -2118,7 +2135,8 @@ static void tcg_reg_alloc_op(TCGContext *s,
allocate_in_reg:
/* allocate a new register matching the constraint
and move the temporary register into it */
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs,
ts->indirect_base);
tcg_out_mov(s, ts->type, reg, ts->reg);
}
new_args[i] = reg;
@ -2167,7 +2185,8 @@ static void tcg_reg_alloc_op(TCGContext *s,
tcg_regset_test_reg(arg_ct->u.regs, reg)) {
goto oarg_end;
}
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs,
ts->indirect_base);
}
tcg_regset_set_reg(allocated_regs, reg);
/* if a fixed register is used, then a move will be done afterwards */

View file

@ -751,6 +751,9 @@ struct TCGContext {
/* qemu/tcg/tcg.c */
uint64_t tcg_target_call_clobber_regs;
uint64_t tcg_target_available_regs[2];
// Unicorn: Use a large array size to get around needing a file static
// Initially was using: ARRAY_SIZE(tcg_target_reg_alloc_order) as the size
int indirect_reg_alloc_order[50];
TCGOpDef *tcg_op_defs;
/* qemu/tcg/optimize.c */