tcg: Add output_pref to TCGOp

Allocate storage for, but do not yet fill in, per-opcode
preferences for the output operands.  Pass it in to the
register allocation routines for output operands.

Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2018-11-27 07:44:51 -08:00
parent ba87719cd2
commit 69e3706d2b
2 changed files with 14 additions and 7 deletions

View File

@ -2591,6 +2591,8 @@ static void liveness_pass_1(TCGContext *s)
break; break;
} }
op->life = arg_life; op->life = arg_life;
op->output_pref[0] = 0;
op->output_pref[1] = 0;
} }
} }
@ -3105,17 +3107,18 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
TCGTemp *ots = arg_temp(op->args[0]); TCGTemp *ots = arg_temp(op->args[0]);
tcg_target_ulong val = op->args[1]; tcg_target_ulong val = op->args[1];
tcg_reg_alloc_do_movi(s, ots, val, op->life, 0); tcg_reg_alloc_do_movi(s, ots, val, op->life, op->output_pref[0]);
} }
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op) static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
{ {
const TCGLifeData arg_life = op->life; const TCGLifeData arg_life = op->life;
TCGRegSet allocated_regs; TCGRegSet allocated_regs, preferred_regs;
TCGTemp *ts, *ots; TCGTemp *ts, *ots;
TCGType otype, itype; TCGType otype, itype;
allocated_regs = s->reserved_regs; allocated_regs = s->reserved_regs;
preferred_regs = op->output_pref[0];
ots = arg_temp(op->args[0]); ots = arg_temp(op->args[0]);
ts = arg_temp(op->args[1]); ts = arg_temp(op->args[1]);
@ -3129,7 +3132,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
if (IS_DEAD_ARG(1)) { if (IS_DEAD_ARG(1)) {
temp_dead(s, ts); temp_dead(s, ts);
} }
tcg_reg_alloc_do_movi(s, ots, val, arg_life, 0); tcg_reg_alloc_do_movi(s, ots, val, arg_life, preferred_regs);
return; return;
} }
@ -3138,7 +3141,8 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
the SOURCE value into its own register first, that way we the SOURCE value into its own register first, that way we
don't have to reload SOURCE the next time it is used. */ don't have to reload SOURCE the next time it is used. */
if (ts->val_type == TEMP_VAL_MEM) { if (ts->val_type == TEMP_VAL_MEM) {
temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs, 0); temp_load(s, ts, tcg_target_available_regs[itype],
allocated_regs, preferred_regs);
} }
tcg_debug_assert(ts->val_type == TEMP_VAL_REG); tcg_debug_assert(ts->val_type == TEMP_VAL_REG);
@ -3168,7 +3172,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
input one. */ input one. */
tcg_regset_set_reg(allocated_regs, ts->reg); tcg_regset_set_reg(allocated_regs, ts->reg);
ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype], ots->reg = tcg_reg_alloc(s, tcg_target_available_regs[otype],
allocated_regs, 0, allocated_regs, preferred_regs,
ots->indirect_base); ots->indirect_base);
} }
tcg_out_mov(s, otype, ots->reg, ts->reg); tcg_out_mov(s, otype, ots->reg, ts->reg);
@ -3302,7 +3306,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
} else if (arg_ct->ct & TCG_CT_NEWREG) { } else if (arg_ct->ct & TCG_CT_NEWREG) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, reg = tcg_reg_alloc(s, arg_ct->u.regs,
i_allocated_regs | o_allocated_regs, i_allocated_regs | o_allocated_regs,
0, ts->indirect_base); op->output_pref[k], ts->indirect_base);
} else { } else {
/* if fixed register, we try to use it */ /* if fixed register, we try to use it */
reg = ts->reg; reg = ts->reg;
@ -3311,7 +3315,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
goto oarg_end; goto oarg_end;
} }
reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs, reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
0, ts->indirect_base); op->output_pref[k], ts->indirect_base);
} }
tcg_regset_set_reg(o_allocated_regs, reg); tcg_regset_set_reg(o_allocated_regs, reg);
/* if a fixed register is used, then a move will be done afterwards */ /* if a fixed register is used, then a move will be done afterwards */

View File

@ -619,6 +619,9 @@ typedef struct TCGOp {
/* Arguments for the opcode. */ /* Arguments for the opcode. */
TCGArg args[MAX_OPC_PARAM]; TCGArg args[MAX_OPC_PARAM];
/* Register preferences for the output(s). */
TCGRegSet output_pref[2];
} TCGOp; } TCGOp;
#define TCGOP_CALLI(X) (X)->param1 #define TCGOP_CALLI(X) (X)->param1