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:
parent
4013884346
commit
e1c08b002d
@ -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
101
tcg/tcg.c
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user