|
@@ -1027,9 +1027,18 @@ void tcg_temp_free_internal(TCGTemp *ts)
|
|
|
TCGContext *s = tcg_ctx;
|
|
|
int k, idx;
|
|
|
|
|
|
- /* In order to simplify users of tcg_constant_*, silently ignore free. */
|
|
|
- if (ts->kind == TEMP_CONST) {
|
|
|
+ switch (ts->kind) {
|
|
|
+ case TEMP_CONST:
|
|
|
+ /*
|
|
|
+ * In order to simplify users of tcg_constant_*,
|
|
|
+ * silently ignore free.
|
|
|
+ */
|
|
|
return;
|
|
|
+ case TEMP_NORMAL:
|
|
|
+ case TEMP_LOCAL:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ g_assert_not_reached();
|
|
|
}
|
|
|
|
|
|
#if defined(CONFIG_DEBUG_TCG)
|
|
@@ -1039,7 +1048,6 @@ void tcg_temp_free_internal(TCGTemp *ts)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- tcg_debug_assert(ts->kind < TEMP_GLOBAL);
|
|
|
tcg_debug_assert(ts->temp_allocated != 0);
|
|
|
ts->temp_allocated = 0;
|
|
|
|
|
@@ -1677,6 +1685,7 @@ static void tcg_reg_alloc_start(TCGContext *s)
|
|
|
case TEMP_GLOBAL:
|
|
|
break;
|
|
|
case TEMP_NORMAL:
|
|
|
+ case TEMP_EBB:
|
|
|
val = TEMP_VAL_DEAD;
|
|
|
/* fall through */
|
|
|
case TEMP_LOCAL:
|
|
@@ -1704,6 +1713,9 @@ static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
|
|
|
case TEMP_LOCAL:
|
|
|
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
|
|
|
break;
|
|
|
+ case TEMP_EBB:
|
|
|
+ snprintf(buf, buf_size, "ebb%d", idx - s->nb_globals);
|
|
|
+ break;
|
|
|
case TEMP_NORMAL:
|
|
|
snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
|
|
|
break;
|
|
@@ -2376,6 +2388,7 @@ static void la_bb_end(TCGContext *s, int ng, int nt)
|
|
|
state = TS_DEAD | TS_MEM;
|
|
|
break;
|
|
|
case TEMP_NORMAL:
|
|
|
+ case TEMP_EBB:
|
|
|
case TEMP_CONST:
|
|
|
state = TS_DEAD;
|
|
|
break;
|
|
@@ -2403,8 +2416,9 @@ static void la_global_sync(TCGContext *s, int ng)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * liveness analysis: conditional branch: all temps are dead,
|
|
|
- * globals and local temps should be synced.
|
|
|
+ * liveness analysis: conditional branch: all temps are dead unless
|
|
|
+ * explicitly live-across-conditional-branch, globals and local temps
|
|
|
+ * should be synced.
|
|
|
*/
|
|
|
static void la_bb_sync(TCGContext *s, int ng, int nt)
|
|
|
{
|
|
@@ -2425,6 +2439,7 @@ static void la_bb_sync(TCGContext *s, int ng, int nt)
|
|
|
case TEMP_NORMAL:
|
|
|
s->temps[i].state = TS_DEAD;
|
|
|
break;
|
|
|
+ case TEMP_EBB:
|
|
|
case TEMP_CONST:
|
|
|
continue;
|
|
|
default:
|
|
@@ -2795,6 +2810,7 @@ static bool liveness_pass_2(TCGContext *s)
|
|
|
TCGTemp *dts = tcg_temp_alloc(s);
|
|
|
dts->type = its->type;
|
|
|
dts->base_type = its->base_type;
|
|
|
+ dts->kind = TEMP_EBB;
|
|
|
its->state_ptr = dts;
|
|
|
} else {
|
|
|
its->state_ptr = NULL;
|
|
@@ -3105,6 +3121,7 @@ static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
|
|
|
new_type = TEMP_VAL_MEM;
|
|
|
break;
|
|
|
case TEMP_NORMAL:
|
|
|
+ case TEMP_EBB:
|
|
|
new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
|
|
|
break;
|
|
|
case TEMP_CONST:
|
|
@@ -3351,6 +3368,7 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
|
|
|
temp_save(s, ts, allocated_regs);
|
|
|
break;
|
|
|
case TEMP_NORMAL:
|
|
|
+ case TEMP_EBB:
|
|
|
/* The liveness analysis already ensures that temps are dead.
|
|
|
Keep an tcg_debug_assert for safety. */
|
|
|
tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
|
|
@@ -3368,8 +3386,9 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * At a conditional branch, we assume all temporaries are dead and
|
|
|
- * all globals and local temps are synced to their location.
|
|
|
+ * At a conditional branch, we assume all temporaries are dead unless
|
|
|
+ * explicitly live-across-conditional-branch; all globals and local
|
|
|
+ * temps are synced to their location.
|
|
|
*/
|
|
|
static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
|
|
|
{
|
|
@@ -3388,6 +3407,7 @@ static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
|
|
|
case TEMP_NORMAL:
|
|
|
tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
|
|
|
break;
|
|
|
+ case TEMP_EBB:
|
|
|
case TEMP_CONST:
|
|
|
break;
|
|
|
default:
|