tcg: try sti when moving a constant into a dead memory temp

This comes from free from unifying tcg_reg_alloc_mov and
tcg_reg_alloc_movi's handling of TEMP_VAL_CONST. It triggers
often on moves to cc_dst, such as the following translation
of "sub $0x3c,%esp":

before: after:
subl $0x3c,%ebp subl $0x3c,%ebp
movl %ebp,0x10(%r14) movl %ebp,0x10(%r14)
movl $0x3c,%ebx movl $0x3c,0x2c(%r14)
movl %ebx,0x2c(%r14)

Backports commit 0fe4fca4e1a5e06a270127dd80bb753d4dda61c6 from qemu
This commit is contained in:
Paolo Bonzini 2018-02-26 10:08:44 -05:00 committed by Lioncash
parent be00a3e100
commit 8734e13a73
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -2166,15 +2166,9 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
save_globals(s, allocated_regs);
}
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
TCGLifeData arg_life)
static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
tcg_target_ulong val, TCGLifeData arg_life)
{
TCGTemp *ots;
tcg_target_ulong val;
ots = &s->temps[args[0]];
val = args[1];
if (ots->fixed_reg) {
/* For fixed registers, we do not do any constant propagation. */
tcg_out_movi(s, ots->type, ots->reg, val);
@ -2194,6 +2188,15 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
}
}
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
TCGLifeData arg_life)
{
TCGTemp *ots = &s->temps[args[0]];
tcg_target_ulong val = args[1];
tcg_reg_alloc_do_movi(s, ots, val, arg_life);
}
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
const TCGArg *args, TCGLifeData arg_life)
{
@ -2209,21 +2212,29 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
otype = ots->type;
itype = ts->type;
/* If the source value is not in a register, and we're going to be
forced to have it in a register in order to perform the copy,
then copy the SOURCE value into its own register first. That way
we don't have to reload SOURCE the next time it is used. */
if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG)
|| ts->val_type == TEMP_VAL_MEM) {
if (ts->val_type == TEMP_VAL_CONST) {
/* propagate constant or generate sti */
tcg_target_ulong val = ts->val;
if (IS_DEAD_ARG(1)) {
temp_dead(s, ts);
}
tcg_reg_alloc_do_movi(s, ots, val, arg_life);
return;
}
/* If the source value is in memory we're going to be forced
to have it in a register in order to perform the copy. Copy
the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */
if (ts->val_type == TEMP_VAL_MEM) {
temp_load(s, ts, s->tcg_target_available_regs[itype], allocated_regs);
}
tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
if (IS_DEAD_ARG(0) && !ots->fixed_reg) {
/* mov to a non-saved dead register makes no sense (even with
liveness analysis disabled). */
tcg_debug_assert(NEED_SYNC_ARG(0));
/* The code above should have moved the temp to a register. */
tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
if (!ots->mem_allocated) {
temp_allocate_frame(s, args[0]);
}
@ -2232,17 +2243,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
temp_dead(s, ts);
}
temp_dead(s, ots);
} else if (ts->val_type == TEMP_VAL_CONST) {
/* propagate constant */
if (ots->val_type == TEMP_VAL_REG) {
s->reg_to_temp[ots->reg] = NULL;
}
ots->val_type = TEMP_VAL_CONST;
ots->val = ts->val;
} else {
/* The code in the first if block should have moved the
temp to a register. */
tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
/* the mov can be suppressed */
if (ots->val_type == TEMP_VAL_REG) {