tcg: Propagate TCGOp down to allocators

Backports commit dd186292017641d5b31fc13225a420677e1d20d3 from qemu
This commit is contained in:
Richard Henderson 2018-03-05 07:12:09 -05:00 committed by Lioncash
parent f1e2ea6847
commit c8f0f6901e
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -2412,25 +2412,24 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
} }
} }
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args, static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
TCGLifeData arg_life)
{ {
TCGTemp *ots = &s->temps[args[0]]; TCGTemp *ots = &s->temps[op->args[0]];
tcg_target_ulong val = args[1]; tcg_target_ulong val = op->args[1];
tcg_reg_alloc_do_movi(s, ots, val, arg_life); tcg_reg_alloc_do_movi(s, ots, val, op->life);
} }
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
const TCGArg *args, TCGLifeData arg_life)
{ {
const TCGLifeData arg_life = op->life;
TCGRegSet allocated_regs; TCGRegSet allocated_regs;
TCGTemp *ts, *ots; TCGTemp *ts, *ots;
TCGType otype, itype; TCGType otype, itype;
allocated_regs = s->reserved_regs; allocated_regs = s->reserved_regs;
ots = &s->temps[args[0]]; ots = &s->temps[op->args[0]];
ts = &s->temps[args[1]]; ts = &s->temps[op->args[1]];
/* Note that otype != itype for no-op truncation. */ /* Note that otype != itype for no-op truncation. */
otype = ots->type; otype = ots->type;
@ -2460,7 +2459,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
liveness analysis disabled). */ liveness analysis disabled). */
tcg_debug_assert(NEED_SYNC_ARG(0)); tcg_debug_assert(NEED_SYNC_ARG(0));
if (!ots->mem_allocated) { if (!ots->mem_allocated) {
temp_allocate_frame(s, args[0]); temp_allocate_frame(s, op->args[0]);
} }
tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset); tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
if (IS_DEAD_ARG(1)) { if (IS_DEAD_ARG(1)) {
@ -2494,10 +2493,10 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
} }
} }
static void tcg_reg_alloc_op(TCGContext *s, static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
const TCGOpDef *def, TCGOpcode opc,
const TCGArg *args, TCGLifeData arg_life)
{ {
const TCGLifeData arg_life = op->life;
const TCGOpDef * const def = &s->tcg_op_defs[op->opc];
TCGRegSet i_allocated_regs; TCGRegSet i_allocated_regs;
TCGRegSet o_allocated_regs; TCGRegSet o_allocated_regs;
int i, k, nb_iargs, nb_oargs; int i, k, nb_iargs, nb_oargs;
@ -2513,7 +2512,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* copy constants */ /* copy constants */
memcpy(new_args + nb_oargs + nb_iargs, memcpy(new_args + nb_oargs + nb_iargs,
args + nb_oargs + nb_iargs, op->args + nb_oargs + nb_iargs,
sizeof(TCGArg) * def->nb_cargs); sizeof(TCGArg) * def->nb_cargs);
i_allocated_regs = s->reserved_regs; i_allocated_regs = s->reserved_regs;
@ -2522,7 +2521,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* satisfy input constraints */ /* satisfy input constraints */
for (k = 0; k < nb_iargs; k++) { for (k = 0; k < nb_iargs; k++) {
i = def->sorted_args[nb_oargs + k]; i = def->sorted_args[nb_oargs + k];
arg = args[i]; arg = op->args[i];
arg_ct = &def->args_ct[i]; arg_ct = &def->args_ct[i];
ts = &s->temps[arg]; ts = &s->temps[arg];
@ -2540,7 +2539,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
if (ts->fixed_reg) { if (ts->fixed_reg) {
/* if fixed register, we must allocate a new register /* if fixed register, we must allocate a new register
if the alias is not the same register */ if the alias is not the same register */
if (arg != args[arg_ct->alias_index]) if (arg != op->args[arg_ct->alias_index])
goto allocate_in_reg; goto allocate_in_reg;
} else { } else {
/* if the input is aliased to an output and if it is /* if the input is aliased to an output and if it is
@ -2581,7 +2580,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* mark dead temporaries and free the associated registers */ /* mark dead temporaries and free the associated registers */
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
if (IS_DEAD_ARG(i)) { if (IS_DEAD_ARG(i)) {
temp_dead(s, &s->temps[args[i]]); temp_dead(s, &s->temps[op->args[i]]);
} }
} }
@ -2605,7 +2604,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
/* satisfy the output constraints */ /* satisfy the output constraints */
for(k = 0; k < nb_oargs; k++) { for(k = 0; k < nb_oargs; k++) {
i = def->sorted_args[k]; i = def->sorted_args[k];
arg = args[i]; arg = op->args[i];
arg_ct = &def->args_ct[i]; arg_ct = &def->args_ct[i];
ts = &s->temps[arg]; ts = &s->temps[arg];
if ((arg_ct->ct & TCG_CT_ALIAS) if ((arg_ct->ct & TCG_CT_ALIAS)
@ -2644,11 +2643,11 @@ static void tcg_reg_alloc_op(TCGContext *s,
} }
/* emit instruction */ /* emit instruction */
tcg_out_op(s, opc, new_args, const_args); tcg_out_op(s, op->opc, new_args, const_args);
/* move the outputs in the correct register if needed */ /* move the outputs in the correct register if needed */
for(i = 0; i < nb_oargs; i++) { for(i = 0; i < nb_oargs; i++) {
ts = &s->temps[args[i]]; ts = &s->temps[op->args[i]];
reg = new_args[i]; reg = new_args[i];
if (ts->fixed_reg && ts->reg != reg) { if (ts->fixed_reg && ts->reg != reg) {
tcg_out_mov(s, ts->type, ts->reg, reg); tcg_out_mov(s, ts->type, ts->reg, reg);
@ -2667,9 +2666,11 @@ static void tcg_reg_alloc_op(TCGContext *s,
#define STACK_DIR(x) (x) #define STACK_DIR(x) (x)
#endif #endif
static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
const TCGArg * const args, TCGLifeData arg_life)
{ {
const int nb_oargs = op->callo;
const int nb_iargs = op->calli;
const TCGLifeData arg_life = op->life;
int flags, nb_regs, i; int flags, nb_regs, i;
TCGReg reg; TCGReg reg;
TCGArg arg; TCGArg arg;
@ -2680,8 +2681,8 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
int allocate_args; int allocate_args;
TCGRegSet allocated_regs; TCGRegSet allocated_regs;
func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs]; func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
flags = args[nb_oargs + nb_iargs + 1]; flags = op->args[nb_oargs + nb_iargs + 1];
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs); nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
#if TCG_TARGET_REG_BITS == 32 #if TCG_TARGET_REG_BITS == 32
@ -2705,7 +2706,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
stack_offset = TCG_TARGET_CALL_STACK_OFFSET; stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
for (i = nb_regs; i < nb_iargs; i++) { for (i = nb_regs; i < nb_iargs; i++) {
arg = args[nb_oargs + i]; arg = op->args[nb_oargs + i];
#ifdef TCG_TARGET_STACK_GROWSUP #ifdef TCG_TARGET_STACK_GROWSUP
stack_offset -= sizeof(tcg_target_long); stack_offset -= sizeof(tcg_target_long);
#endif #endif
@ -2723,7 +2724,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
/* assign input registers */ /* assign input registers */
allocated_regs = s->reserved_regs; allocated_regs = s->reserved_regs;
for (i = 0; i < nb_regs; i++) { for (i = 0; i < nb_regs; i++) {
arg = args[nb_oargs + i]; arg = op->args[nb_oargs + i];
if (arg != TCG_CALL_DUMMY_ARG) { if (arg != TCG_CALL_DUMMY_ARG) {
ts = &s->temps[arg]; ts = &s->temps[arg];
reg = tcg_target_call_iarg_regs[i]; reg = tcg_target_call_iarg_regs[i];
@ -2747,7 +2748,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
/* mark dead temporaries and free the associated registers */ /* mark dead temporaries and free the associated registers */
for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) { for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
if (IS_DEAD_ARG(i)) { if (IS_DEAD_ARG(i)) {
temp_dead(s, &s->temps[args[i]]); temp_dead(s, &s->temps[op->args[i]]);
} }
} }
@ -2772,7 +2773,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
/* assign output registers and emit moves if needed */ /* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) { for(i = 0; i < nb_oargs; i++) {
arg = args[i]; arg = op->args[i];
ts = &s->temps[arg]; ts = &s->temps[arg];
reg = tcg_target_call_oarg_regs[i]; reg = tcg_target_call_oarg_regs[i];
tcg_debug_assert(s->reg_to_temp[reg] == NULL); tcg_debug_assert(s->reg_to_temp[reg] == NULL);
@ -2906,8 +2907,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) { for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
TCGOp * const op = &s->gen_op_buf[oi]; TCGOp * const op = &s->gen_op_buf[oi];
TCGOpcode opc = op->opc; TCGOpcode opc = op->opc;
const TCGOpDef *def = &s->tcg_op_defs[opc];
TCGLifeData arg_life = op->life;
oi_next = op->next; oi_next = op->next;
#ifdef CONFIG_PROFILER #ifdef CONFIG_PROFILER
@ -2916,11 +2915,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
switch (opc) { switch (opc) {
case INDEX_op_mov_i32: case INDEX_op_mov_i32:
case INDEX_op_mov_i64: case INDEX_op_mov_i64:
tcg_reg_alloc_mov(s, def, op->args, arg_life); tcg_reg_alloc_mov(s, op);
break; break;
case INDEX_op_movi_i32: case INDEX_op_movi_i32:
case INDEX_op_movi_i64: case INDEX_op_movi_i64:
tcg_reg_alloc_movi(s, op->args, arg_life); tcg_reg_alloc_movi(s, op);
break; break;
case INDEX_op_insn_start: case INDEX_op_insn_start:
if (num_insns >= 0) { if (num_insns >= 0) {
@ -2945,7 +2944,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
tcg_out_label(s, arg_label(s, op->args[0]), s->code_ptr); tcg_out_label(s, arg_label(s, op->args[0]), s->code_ptr);
break; break;
case INDEX_op_call: case INDEX_op_call:
tcg_reg_alloc_call(s, op->callo, op->calli, op->args, arg_life); tcg_reg_alloc_call(s, op);
break; break;
default: default:
/* Sanity check that we've not introduced any unhandled opcodes. */ /* Sanity check that we've not introduced any unhandled opcodes. */
@ -2953,7 +2952,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
/* Note: in order to speed up the code, it would be much /* Note: in order to speed up the code, it would be much
faster to have specialized register allocator functions for faster to have specialized register allocator functions for
some common argument patterns */ some common argument patterns */
tcg_reg_alloc_op(s, def, opc, op->args, arg_life); tcg_reg_alloc_op(s, op);
break; break;
} }
#ifdef CONFIG_DEBUG_TCG #ifdef CONFIG_DEBUG_TCG