tcg: Don't re-use TEMP_TB temporaries

Reusing TEMP_TB interferes with detecting whether the
temp can be adjusted to TEMP_EBB.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-01-29 14:02:59 -10:00
parent 4013884346
commit e1c08b002d
2 changed files with 53 additions and 50 deletions

View File

@ -612,7 +612,7 @@ struct TCGContext {
#endif #endif
GHashTable *const_table[TCG_TYPE_COUNT]; GHashTable *const_table[TCG_TYPE_COUNT];
TCGTempSet free_temps[TCG_TYPE_COUNT * 2]; TCGTempSet free_temps[TCG_TYPE_COUNT];
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
QTAILQ_HEAD(, TCGOp) ops, free_ops; QTAILQ_HEAD(, TCGOp) ops, free_ops;

101
tcg/tcg.c
View File

@ -1257,63 +1257,66 @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind) TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
{ {
TCGContext *s = tcg_ctx; TCGContext *s = tcg_ctx;
bool temp_local = kind == TEMP_TB;
TCGTemp *ts; TCGTemp *ts;
int idx, k; int n;
k = type + (temp_local ? TCG_TYPE_COUNT : 0); if (kind == TEMP_EBB) {
idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS); int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS);
if (idx < TCG_MAX_TEMPS) {
/* There is already an available temp with the right type. */
clear_bit(idx, s->free_temps[k].l);
ts = &s->temps[idx]; if (idx < TCG_MAX_TEMPS) {
ts->temp_allocated = 1; /* There is already an available temp with the right type. */
tcg_debug_assert(ts->base_type == type); clear_bit(idx, s->free_temps[type].l);
tcg_debug_assert(ts->kind == kind);
} else {
int i, n;
switch (type) { ts = &s->temps[idx];
case TCG_TYPE_I32: ts->temp_allocated = 1;
case TCG_TYPE_V64: tcg_debug_assert(ts->base_type == type);
case TCG_TYPE_V128: tcg_debug_assert(ts->kind == kind);
case TCG_TYPE_V256: goto done;
n = 1;
break;
case TCG_TYPE_I64:
n = 64 / TCG_TARGET_REG_BITS;
break;
case TCG_TYPE_I128:
n = 128 / TCG_TARGET_REG_BITS;
break;
default:
g_assert_not_reached();
} }
} else {
tcg_debug_assert(kind == TEMP_TB);
}
ts = tcg_temp_alloc(s); switch (type) {
ts->base_type = type; case TCG_TYPE_I32:
ts->temp_allocated = 1; case TCG_TYPE_V64:
ts->kind = kind; case TCG_TYPE_V128:
case TCG_TYPE_V256:
n = 1;
break;
case TCG_TYPE_I64:
n = 64 / TCG_TARGET_REG_BITS;
break;
case TCG_TYPE_I128:
n = 128 / TCG_TARGET_REG_BITS;
break;
default:
g_assert_not_reached();
}
if (n == 1) { ts = tcg_temp_alloc(s);
ts->type = type; ts->base_type = type;
} else { ts->temp_allocated = 1;
ts->type = TCG_TYPE_REG; ts->kind = kind;
for (i = 1; i < n; ++i) { if (n == 1) {
TCGTemp *ts2 = tcg_temp_alloc(s); ts->type = type;
} else {
ts->type = TCG_TYPE_REG;
tcg_debug_assert(ts2 == ts + i); for (int i = 1; i < n; ++i) {
ts2->base_type = type; TCGTemp *ts2 = tcg_temp_alloc(s);
ts2->type = TCG_TYPE_REG;
ts2->temp_allocated = 1; tcg_debug_assert(ts2 == ts + i);
ts2->temp_subindex = i; ts2->base_type = type;
ts2->kind = kind; ts2->type = TCG_TYPE_REG;
} ts2->temp_allocated = 1;
ts2->temp_subindex = i;
ts2->kind = kind;
} }
} }
done:
#if defined(CONFIG_DEBUG_TCG) #if defined(CONFIG_DEBUG_TCG)
s->temps_in_use++; s->temps_in_use++;
#endif #endif
@ -1358,7 +1361,6 @@ TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
void tcg_temp_free_internal(TCGTemp *ts) void tcg_temp_free_internal(TCGTemp *ts)
{ {
TCGContext *s = tcg_ctx; TCGContext *s = tcg_ctx;
int k, idx;
switch (ts->kind) { switch (ts->kind) {
case TEMP_CONST: case TEMP_CONST:
@ -1382,9 +1384,10 @@ void tcg_temp_free_internal(TCGTemp *ts)
s->temps_in_use--; s->temps_in_use--;
#endif #endif
idx = temp_idx(ts); if (ts->kind == TEMP_EBB) {
k = ts->base_type + (ts->kind == TEMP_EBB ? 0 : TCG_TYPE_COUNT); int idx = temp_idx(ts);
set_bit(idx, s->free_temps[k].l); set_bit(idx, s->free_temps[ts->base_type].l);
}
} }
TCGTemp *tcg_constant_internal(TCGType type, int64_t val) TCGTemp *tcg_constant_internal(TCGType type, int64_t val)