mirror of https://github.com/xemu-project/xemu.git
tcg: Add liveness_pass_0
Attempt to reduce the lifetime of TEMP_TB. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
9bbee4c01c
commit
874b857461
70
tcg/tcg.c
70
tcg/tcg.c
|
@ -2857,6 +2857,75 @@ static void la_cross_call(TCGContext *s, int nt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Liveness analysis: Verify the lifetime of TEMP_TB, and reduce
|
||||||
|
* to TEMP_EBB, if possible.
|
||||||
|
*/
|
||||||
|
static void __attribute__((noinline))
|
||||||
|
liveness_pass_0(TCGContext *s)
|
||||||
|
{
|
||||||
|
void * const multiple_ebb = (void *)(uintptr_t)-1;
|
||||||
|
int nb_temps = s->nb_temps;
|
||||||
|
TCGOp *op, *ebb;
|
||||||
|
|
||||||
|
for (int i = s->nb_globals; i < nb_temps; ++i) {
|
||||||
|
s->temps[i].state_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Represent each EBB by the op at which it begins. In the case of
|
||||||
|
* the first EBB, this is the first op, otherwise it is a label.
|
||||||
|
* Collect the uses of each TEMP_TB: NULL for unused, EBB for use
|
||||||
|
* within a single EBB, else MULTIPLE_EBB.
|
||||||
|
*/
|
||||||
|
ebb = QTAILQ_FIRST(&s->ops);
|
||||||
|
QTAILQ_FOREACH(op, &s->ops, link) {
|
||||||
|
const TCGOpDef *def;
|
||||||
|
int nb_oargs, nb_iargs;
|
||||||
|
|
||||||
|
switch (op->opc) {
|
||||||
|
case INDEX_op_set_label:
|
||||||
|
ebb = op;
|
||||||
|
continue;
|
||||||
|
case INDEX_op_discard:
|
||||||
|
continue;
|
||||||
|
case INDEX_op_call:
|
||||||
|
nb_oargs = TCGOP_CALLO(op);
|
||||||
|
nb_iargs = TCGOP_CALLI(op);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
def = &tcg_op_defs[op->opc];
|
||||||
|
nb_oargs = def->nb_oargs;
|
||||||
|
nb_iargs = def->nb_iargs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nb_oargs + nb_iargs; ++i) {
|
||||||
|
TCGTemp *ts = arg_temp(op->args[i]);
|
||||||
|
|
||||||
|
if (ts->kind != TEMP_TB) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ts->state_ptr == NULL) {
|
||||||
|
ts->state_ptr = ebb;
|
||||||
|
} else if (ts->state_ptr != ebb) {
|
||||||
|
ts->state_ptr = multiple_ebb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For TEMP_TB that turned out not to be used beyond one EBB,
|
||||||
|
* reduce the liveness to TEMP_EBB.
|
||||||
|
*/
|
||||||
|
for (int i = s->nb_globals; i < nb_temps; ++i) {
|
||||||
|
TCGTemp *ts = &s->temps[i];
|
||||||
|
if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) {
|
||||||
|
ts->kind = TEMP_EBB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Liveness analysis : update the opc_arg_life array to tell if a
|
/* Liveness analysis : update the opc_arg_life array to tell if a
|
||||||
given input arguments is dead. Instructions updating dead
|
given input arguments is dead. Instructions updating dead
|
||||||
temporaries are removed. */
|
temporaries are removed. */
|
||||||
|
@ -4872,6 +4941,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
reachable_code_pass(s);
|
reachable_code_pass(s);
|
||||||
|
liveness_pass_0(s);
|
||||||
liveness_pass_1(s);
|
liveness_pass_1(s);
|
||||||
|
|
||||||
if (s->nb_indirects > 0) {
|
if (s->nb_indirects > 0) {
|
||||||
|
|
Loading…
Reference in New Issue