Skip to content

Commit

Permalink
tcg: Lower indirect registers in a separate pass
Browse files Browse the repository at this point in the history
Rather than rely on recursion during the middle of register allocation,
lower indirect registers to loads and stores off the indirect base into
plain temps.

For an x86_64 host, with sufficient registers, this results in identical
code, modulo the actual register assignments.

For an i686 host, with insufficient registers, this means that temps can
be (temporarily) spilled to the stack in order to satisfy an allocation.
This as opposed to the possibility of not being able to spill, to allocate
a register for the indirect base, in order to perform a spill.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
rth7680 committed Aug 5, 2016
1 parent c0ef05b commit 5a18407
Show file tree
Hide file tree
Showing 5 changed files with 263 additions and 84 deletions.
1 change: 1 addition & 0 deletions include/qemu/log.h
Expand Up @@ -42,6 +42,7 @@ static inline bool qemu_log_separate(void)
#define CPU_LOG_TB_NOCHAIN (1 << 13)
#define CPU_LOG_PAGE (1 << 14)
#define LOG_TRACE (1 << 15)
#define CPU_LOG_TB_OP_IND (1 << 16)

/* Returns true if a bit is set in the current loglevel mask
*/
Expand Down
31 changes: 2 additions & 29 deletions tcg/optimize.c
Expand Up @@ -82,33 +82,6 @@ static void init_temp_info(TCGArg temp)
}
}

static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
TCGOpcode opc, int nargs)
{
int oi = s->gen_next_op_idx;
int pi = s->gen_next_parm_idx;
int prev = old_op->prev;
int next = old_op - s->gen_op_buf;
TCGOp *new_op;

tcg_debug_assert(oi < OPC_BUF_SIZE);
tcg_debug_assert(pi + nargs <= OPPARAM_BUF_SIZE);
s->gen_next_op_idx = oi + 1;
s->gen_next_parm_idx = pi + nargs;

new_op = &s->gen_op_buf[oi];
*new_op = (TCGOp){
.opc = opc,
.args = pi,
.prev = prev,
.next = next
};
s->gen_op_buf[prev].next = oi;
old_op->prev = oi;

return new_op;
}

static int op_bits(TCGOpcode op)
{
const TCGOpDef *def = &tcg_op_defs[op];
Expand Down Expand Up @@ -1116,7 +1089,7 @@ void tcg_optimize(TCGContext *s)
uint64_t a = ((uint64_t)ah << 32) | al;
uint64_t b = ((uint64_t)bh << 32) | bl;
TCGArg rl, rh;
TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);
TCGOp *op2 = tcg_op_insert_before(s, op, INDEX_op_movi_i32, 2);
TCGArg *args2 = &s->gen_opparam_buf[op2->args];

if (opc == INDEX_op_add2_i32) {
Expand All @@ -1142,7 +1115,7 @@ void tcg_optimize(TCGContext *s)
uint32_t b = temps[args[3]].val;
uint64_t r = (uint64_t)a * b;
TCGArg rl, rh;
TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);
TCGOp *op2 = tcg_op_insert_before(s, op, INDEX_op_movi_i32, 2);
TCGArg *args2 = &s->gen_opparam_buf[op2->args];

rl = args[0];
Expand Down

0 comments on commit 5a18407

Please sign in to comment.