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
|
||||
given input arguments is dead. Instructions updating dead
|
||||
temporaries are removed. */
|
||||
@ -4872,6 +4941,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
|
||||
#endif
|
||||
|
||||
reachable_code_pass(s);
|
||||
liveness_pass_0(s);
|
||||
liveness_pass_1(s);
|
||||
|
||||
if (s->nb_indirects > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user