Cache deleted live ranges in ir_ctx.unused_ranges

This commit is contained in:
Dmitry Stogov 2023-04-13 11:42:47 +03:00
parent 1f447a538b
commit 0b78a322f8
3 changed files with 47 additions and 45 deletions

2
ir.h
View File

@ -505,6 +505,7 @@ typedef struct _ir_ctx ir_ctx;
typedef struct _ir_use_list ir_use_list; typedef struct _ir_use_list ir_use_list;
typedef struct _ir_block ir_block; typedef struct _ir_block ir_block;
typedef struct _ir_live_interval ir_live_interval; typedef struct _ir_live_interval ir_live_interval;
typedef struct _ir_live_range ir_live_range;
typedef int8_t ir_regs[4]; typedef int8_t ir_regs[4];
typedef void (*ir_snapshot_create_t)(ir_ctx *ctx, ir_ref addr); typedef void (*ir_snapshot_create_t)(ir_ctx *ctx, ir_ref addr);
@ -537,6 +538,7 @@ struct _ir_ctx {
int32_t fixed_call_stack_size; /* fixed preallocated stack for parameter passing (default 0) */ int32_t fixed_call_stack_size; /* fixed preallocated stack for parameter passing (default 0) */
uint64_t fixed_save_regset; /* registers that always saved/restored in prologue/epilugue */ uint64_t fixed_save_regset; /* registers that always saved/restored in prologue/epilugue */
ir_live_interval **live_intervals; ir_live_interval **live_intervals;
ir_live_range *unused_ranges;
ir_regs *regs; ir_regs *regs;
ir_ref *prev_ref; ir_ref *prev_ref;
union { union {

View File

@ -878,8 +878,6 @@ ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3,
/*** IR Live Info ***/ /*** IR Live Info ***/
typedef ir_ref ir_live_pos; typedef ir_ref ir_live_pos;
typedef struct _ir_use_pos ir_use_pos; typedef struct _ir_use_pos ir_use_pos;
typedef struct _ir_live_range ir_live_range;
typedef struct _ir_live_interval ir_live_interval;
#define IR_SUB_REFS_COUNT 4 #define IR_SUB_REFS_COUNT 4

88
ir_ra.c
View File

@ -142,7 +142,7 @@ static void ir_add_local_var(ir_ctx *ctx, int v, uint8_t type)
ctx->flags |= IR_LR_HAVE_VARS; ctx->flags |= IR_LR_HAVE_VARS;
} }
static void ir_add_live_range(ir_ctx *ctx, ir_live_range **unused, int v, uint8_t type, ir_live_pos start, ir_live_pos end) static void ir_add_live_range(ir_ctx *ctx, int v, uint8_t type, ir_live_pos start, ir_live_pos end)
{ {
ir_live_interval *ival = ctx->live_intervals[v]; ir_live_interval *ival = ctx->live_intervals[v];
ir_live_range *p, *q, *next, *prev; ir_live_range *p, *q, *next, *prev;
@ -184,9 +184,9 @@ static void ir_add_live_range(ir_ctx *ctx, ir_live_range **unused, int v, uint8_
p->end = next->end; p->end = next->end;
} }
p->next = next->next; p->next = next->next;
/* list of deleted structures is keapt in "unused" list */ /* remember in the "unused_ranges" list */
next->next = *unused; next->next = ctx->unused_ranges;
*unused = next; ctx->unused_ranges = next;
next = p->next; next = p->next;
} }
if (!p->next) { if (!p->next) {
@ -198,10 +198,10 @@ static void ir_add_live_range(ir_ctx *ctx, ir_live_range **unused, int v, uint8_
prev = p; prev = p;
p = prev->next; p = prev->next;
} }
if (*unused) { if (ctx->unused_ranges) {
/* reuse */ /* reuse */
q = *unused; q = ctx->unused_ranges;
*unused = q->next; ctx->unused_ranges = q->next;
} else { } else {
q = ir_mem_malloc(sizeof(ir_live_range)); q = ir_mem_malloc(sizeof(ir_live_range));
} }
@ -222,7 +222,7 @@ static void ir_add_live_range(ir_ctx *ctx, ir_live_range **unused, int v, uint8_
} }
} }
static void ir_add_fixed_live_range(ir_ctx *ctx, ir_live_range **unused, ir_reg reg, ir_live_pos start, ir_live_pos end) static void ir_add_fixed_live_range(ir_ctx *ctx, ir_reg reg, ir_live_pos start, ir_live_pos end)
{ {
int v = ctx->vregs_count + 1 + reg; int v = ctx->vregs_count + 1 + reg;
ir_live_interval *ival = ctx->live_intervals[v]; ir_live_interval *ival = ctx->live_intervals[v];
@ -244,7 +244,7 @@ static void ir_add_fixed_live_range(ir_ctx *ctx, ir_live_range **unused, ir_reg
ctx->live_intervals[v] = ival; ctx->live_intervals[v] = ival;
return; return;
} }
ir_add_live_range(ctx, unused, v, IR_VOID, start, end); ir_add_live_range(ctx, v, IR_VOID, start, end);
} }
static void ir_add_tmp(ir_ctx *ctx, ir_ref ref, ir_ref tmp_ref, int32_t tmp_op_num, ir_tmp_reg tmp_reg) static void ir_add_tmp(ir_ctx *ctx, ir_ref ref, ir_ref tmp_ref, int32_t tmp_op_num, ir_tmp_reg tmp_reg)
@ -417,14 +417,14 @@ static void ir_add_osr_entry_loads(ir_ctx *ctx, ir_block *bb, ir_bitset live, ui
#if 0 #if 0
/* ENTRY "clobbers" all registers */ /* ENTRY "clobbers" all registers */
ir_ref ref = ctx->ir_base[bb->start].op1; ir_ref ref = ctx->ir_base[bb->start].op1;
ir_add_fixed_live_range(ctx, &unused, IR_REG_ALL, ir_add_fixed_live_range(ctx, IR_REG_ALL,
IR_DEF_LIVE_POS_FROM_REF(ref), IR_DEF_LIVE_POS_FROM_REF(ref),
IR_SAVE_LIVE_POS_FROM_REF(ref)); IR_SAVE_LIVE_POS_FROM_REF(ref));
#endif #endif
} }
} }
static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block *bb, ir_bitset live, ir_live_range **unused) static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block *bb, ir_bitset live)
{ {
ir_ref stack[4]; ir_ref stack[4];
int stack_pos = 0; int stack_pos = 0;
@ -448,7 +448,7 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block
ir_add_tmp(ctx, ref, input, constraints.tmp_regs[n].num, constraints.tmp_regs[n]); ir_add_tmp(ctx, ref, input, constraints.tmp_regs[n].num, constraints.tmp_regs[n]);
} else { } else {
/* CPU specific constraints */ /* CPU specific constraints */
ir_add_fixed_live_range(ctx, unused, constraints.tmp_regs[n].reg, ir_add_fixed_live_range(ctx, constraints.tmp_regs[n].reg,
IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].start, IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].start,
IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].end); IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].end);
} }
@ -484,7 +484,7 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block
/* live.add(opd) */ /* live.add(opd) */
ir_bitset_incl(live, ctx->vregs[child]); ir_bitset_incl(live, ctx->vregs[child]);
/* intervals[opd].addRange(b.from, op.id) */ /* intervals[opd].addRange(b.from, op.id) */
ir_add_live_range(ctx, unused, ctx->vregs[child], ctx->ir_base[child].type, ir_add_live_range(ctx, ctx->vregs[child], ctx->ir_base[child].type,
IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); IR_START_LIVE_POS_FROM_REF(bb->start), use_pos);
} }
ir_add_use(ctx, ctx->vregs[child], j, use_pos, reg, use_flags, -input); ir_add_use(ctx, ctx->vregs[child], j, use_pos, reg, use_flags, -input);
@ -528,7 +528,7 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block
uint8_t use_flags = IR_USE_MUST_BE_IN_REG; uint8_t use_flags = IR_USE_MUST_BE_IN_REG;
/* intervals[opd].addRange(b.from, op.id) */ /* intervals[opd].addRange(b.from, op.id) */
ir_add_live_range(ctx, unused, ctx->vregs[input], ctx->ir_base[input].type, ir_add_live_range(ctx, ctx->vregs[input], ctx->ir_base[input].type,
IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); IR_START_LIVE_POS_FROM_REF(bb->start), use_pos);
ir_add_use(ctx, ctx->vregs[input], op_num, use_pos, IR_REG_NONE, use_flags, IR_UNUSED); ir_add_use(ctx, ctx->vregs[input], op_num, use_pos, IR_REG_NONE, use_flags, IR_UNUSED);
/* live.add(opd) */ /* live.add(opd) */
@ -549,7 +549,6 @@ int ir_compute_live_ranges(ir_ctx *ctx)
ir_bitset live, bb_live; ir_bitset live, bb_live;
ir_bitset loops = NULL; ir_bitset loops = NULL;
ir_bitqueue queue; ir_bitqueue queue;
ir_live_range *unused = NULL;
if (!(ctx->flags & IR_LINEAR) || !ctx->vregs) { if (!(ctx->flags & IR_LINEAR) || !ctx->vregs) {
return 0; return 0;
@ -562,6 +561,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
/* vregs + tmp + fixed + SRATCH + ALL */ /* vregs + tmp + fixed + SRATCH + ALL */
ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_NUM + 2, sizeof(ir_live_interval*)); ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_NUM + 2, sizeof(ir_live_interval*));
ctx->unused_ranges = NULL;
#ifdef IR_DEBUG #ifdef IR_DEBUG
visited = ir_bitset_malloc(ctx->cfg_blocks_count + 1); visited = ir_bitset_malloc(ctx->cfg_blocks_count + 1);
@ -611,7 +611,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
/* for each opd in live */ /* for each opd in live */
IR_BITSET_FOREACH(live, len, i) { IR_BITSET_FOREACH(live, len, i) {
/* intervals[opd].addRange(b.from, b.to) */ /* intervals[opd].addRange(b.from, b.to) */
ir_add_live_range(ctx, &unused, i, IR_VOID, ir_add_live_range(ctx, i, IR_VOID,
IR_START_LIVE_POS_FROM_REF(bb->start), IR_START_LIVE_POS_FROM_REF(bb->start),
IR_END_LIVE_POS_FROM_REF(bb->end)); IR_END_LIVE_POS_FROM_REF(bb->end));
} IR_BITSET_FOREACH_END(); } IR_BITSET_FOREACH_END();
@ -636,7 +636,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
IR_ASSERT(ctx->vregs[input]); IR_ASSERT(ctx->vregs[input]);
ir_bitset_incl(live, ctx->vregs[input]); ir_bitset_incl(live, ctx->vregs[input]);
/* intervals[phi.inputOf(b)].addRange(b.from, b.to) */ /* intervals[phi.inputOf(b)].addRange(b.from, b.to) */
ir_add_live_range(ctx, &unused, ctx->vregs[input], insn->type, ir_add_live_range(ctx, ctx->vregs[input], insn->type,
IR_START_LIVE_POS_FROM_REF(bb->start), IR_START_LIVE_POS_FROM_REF(bb->start),
IR_END_LIVE_POS_FROM_REF(bb->end)); IR_END_LIVE_POS_FROM_REF(bb->end));
ir_add_phi_use(ctx, ctx->vregs[input], k, IR_DEF_LIVE_POS_FROM_REF(bb->end), use); ir_add_phi_use(ctx, ctx->vregs[input], k, IR_DEF_LIVE_POS_FROM_REF(bb->end), use);
@ -674,7 +674,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
ir_add_tmp(ctx, ref, ref, constraints.tmp_regs[n].num, constraints.tmp_regs[n]); ir_add_tmp(ctx, ref, ref, constraints.tmp_regs[n].num, constraints.tmp_regs[n]);
} else { } else {
/* CPU specific constraints */ /* CPU specific constraints */
ir_add_fixed_live_range(ctx, &unused, constraints.tmp_regs[n].reg, ir_add_fixed_live_range(ctx, constraints.tmp_regs[n].reg,
IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].start, IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].start,
IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].end); IR_START_LIVE_POS_FROM_REF(ref) + constraints.tmp_regs[n].end);
} }
@ -709,10 +709,10 @@ int ir_compute_live_ranges(ir_ctx *ctx)
def_pos = IR_SAVE_LIVE_POS_FROM_REF(ref); def_pos = IR_SAVE_LIVE_POS_FROM_REF(ref);
if (insn->op == IR_PARAM) { if (insn->op == IR_PARAM) {
/* parameter register must be kept before it's copied */ /* parameter register must be kept before it's copied */
ir_add_fixed_live_range(ctx, &unused, reg, ir_add_fixed_live_range(ctx, reg,
IR_START_LIVE_POS_FROM_REF(bb->start), def_pos); IR_START_LIVE_POS_FROM_REF(bb->start), def_pos);
} else { } else {
ir_add_fixed_live_range(ctx, &unused, reg, ir_add_fixed_live_range(ctx, reg,
IR_DEF_LIVE_POS_FROM_REF(ref), def_pos); IR_DEF_LIVE_POS_FROM_REF(ref), def_pos);
} }
} else if (def_flags & IR_DEF_REUSES_OP1_REG) { } else if (def_flags & IR_DEF_REUSES_OP1_REG) {
@ -761,7 +761,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
ir_live_pos use_pos = IR_USE_LIVE_POS_FROM_REF(ref); ir_live_pos use_pos = IR_USE_LIVE_POS_FROM_REF(ref);
ir_add_live_range(ctx, &unused, ctx->vregs[insn->op2], ctx->ir_base[insn->op2].type, ir_add_live_range(ctx, ctx->vregs[insn->op2], ctx->ir_base[insn->op2].type,
IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); IR_START_LIVE_POS_FROM_REF(bb->start), use_pos);
ir_add_use(ctx, ctx->vregs[insn->op2], 2, use_pos, IR_REG_NONE, 0, IR_UNUSED); ir_add_use(ctx, ctx->vregs[insn->op2], 2, use_pos, IR_REG_NONE, 0, IR_UNUSED);
ir_bitset_incl(live, ctx->vregs[insn->op2]); ir_bitset_incl(live, ctx->vregs[insn->op2]);
@ -790,13 +790,13 @@ int ir_compute_live_ranges(ir_ctx *ctx)
IR_ASSERT(ctx->vregs[ref]); IR_ASSERT(ctx->vregs[ref]);
hint_ref = ref; hint_ref = ref;
if (reg != IR_REG_NONE) { if (reg != IR_REG_NONE) {
ir_add_fixed_live_range(ctx, &unused, reg, ir_add_fixed_live_range(ctx, reg,
use_pos, IR_USE_LIVE_POS_FROM_REF(ref)); use_pos, IR_USE_LIVE_POS_FROM_REF(ref));
} }
} else { } else {
if (reg != IR_REG_NONE) { if (reg != IR_REG_NONE) {
use_pos = IR_LOAD_LIVE_POS_FROM_REF(ref); use_pos = IR_LOAD_LIVE_POS_FROM_REF(ref);
ir_add_fixed_live_range(ctx, &unused, reg, ir_add_fixed_live_range(ctx, reg,
use_pos, IR_USE_LIVE_POS_FROM_REF(ref)); use_pos, IR_USE_LIVE_POS_FROM_REF(ref));
} else if ((def_flags & IR_DEF_REUSES_OP1_REG) && input == insn->op1) { } else if ((def_flags & IR_DEF_REUSES_OP1_REG) && input == insn->op1) {
/* Input is the same as "op1" */ /* Input is the same as "op1" */
@ -809,18 +809,18 @@ int ir_compute_live_ranges(ir_ctx *ctx)
/* live.add(opd) */ /* live.add(opd) */
ir_bitset_incl(live, ctx->vregs[input]); ir_bitset_incl(live, ctx->vregs[input]);
/* intervals[opd].addRange(b.from, op.id) */ /* intervals[opd].addRange(b.from, op.id) */
ir_add_live_range(ctx, &unused, ctx->vregs[input], ctx->ir_base[input].type, ir_add_live_range(ctx, ctx->vregs[input], ctx->ir_base[input].type,
IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); IR_START_LIVE_POS_FROM_REF(bb->start), use_pos);
} }
ir_add_use(ctx, ctx->vregs[input], j, use_pos, reg, use_flags, hint_ref); ir_add_use(ctx, ctx->vregs[input], j, use_pos, reg, use_flags, hint_ref);
} else if (input > 0) { } else if (input > 0) {
IR_ASSERT(ctx->rules); IR_ASSERT(ctx->rules);
if (ctx->rules[input] & IR_FUSED) { if (ctx->rules[input] & IR_FUSED) {
ir_add_fusion_ranges(ctx, ref, input, bb, live, &unused); ir_add_fusion_ranges(ctx, ref, input, bb, live);
} }
} else { } else {
if (reg != IR_REG_NONE) { if (reg != IR_REG_NONE) {
ir_add_fixed_live_range(ctx, &unused, reg, ir_add_fixed_live_range(ctx, reg,
IR_LOAD_LIVE_POS_FROM_REF(ref), IR_USE_LIVE_POS_FROM_REF(ref)); IR_LOAD_LIVE_POS_FROM_REF(ref), IR_USE_LIVE_POS_FROM_REF(ref));
} }
} }
@ -852,7 +852,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
IR_BITSET_FOREACH(live, len, i) { IR_BITSET_FOREACH(live, len, i) {
ir_bitset_incl(child_live_in, i); ir_bitset_incl(child_live_in, i);
ir_add_live_range(ctx, &unused, i, IR_VOID, ir_add_live_range(ctx, i, IR_VOID,
IR_START_LIVE_POS_FROM_REF(child_bb->start), IR_START_LIVE_POS_FROM_REF(child_bb->start),
IR_END_LIVE_POS_FROM_REF(child_bb->end)); IR_END_LIVE_POS_FROM_REF(child_bb->end));
} IR_BITSET_FOREACH_END(); } IR_BITSET_FOREACH_END();
@ -884,8 +884,9 @@ int ir_compute_live_ranges(ir_ctx *ctx)
} }
} }
if (unused) { if (ctx->unused_ranges) {
ir_free_live_ranges(unused); ir_free_live_ranges(ctx->unused_ranges);
ctx->unused_ranges = NULL;
} }
if (loops) { if (loops) {
@ -978,7 +979,7 @@ static ir_live_pos ir_vregs_overlap(ir_ctx *ctx, uint32_t r1, uint32_t r2)
return ir_ivals_overlap(&ival1->range, &ival2->range); return ir_ivals_overlap(&ival1->range, &ival2->range);
} }
static void ir_vregs_join(ir_ctx *ctx, ir_live_range **unused, uint32_t r1, uint32_t r2) static void ir_vregs_join(ir_ctx *ctx, uint32_t r1, uint32_t r2)
{ {
ir_live_interval *ival = ctx->live_intervals[r2]; ir_live_interval *ival = ctx->live_intervals[r2];
ir_live_range *live_range = &ival->range; ir_live_range *live_range = &ival->range;
@ -989,13 +990,13 @@ static void ir_vregs_join(ir_ctx *ctx, ir_live_range **unused, uint32_t r1, uint
fprintf(stderr, "COALESCE %d -> %d\n", r2, r1); fprintf(stderr, "COALESCE %d -> %d\n", r2, r1);
#endif #endif
ir_add_live_range(ctx, unused, r1, ival->type, live_range->start, live_range->end); ir_add_live_range(ctx, r1, ival->type, live_range->start, live_range->end);
live_range = live_range->next; live_range = live_range->next;
while (live_range) { while (live_range) {
next = live_range->next; next = live_range->next;
live_range->next = *unused; live_range->next = ctx->unused_ranges;
*unused = live_range; ctx->unused_ranges = live_range;
ir_add_live_range(ctx, unused, r1, ival->type, live_range->start, live_range->end); ir_add_live_range(ctx, r1, ival->type, live_range->start, live_range->end);
live_range = next; live_range = next;
} }
@ -1037,7 +1038,7 @@ static void ir_vregs_join(ir_ctx *ctx, ir_live_range **unused, uint32_t r1, uint
ir_mem_free(ival); ir_mem_free(ival);
} }
static bool ir_try_coalesce(ir_ctx *ctx, ir_live_range **unused, ir_ref from, ir_ref to) static bool ir_try_coalesce(ir_ctx *ctx, ir_ref from, ir_ref to)
{ {
ir_ref i; ir_ref i;
uint32_t v1 = ctx->vregs[from]; uint32_t v1 = ctx->vregs[from];
@ -1048,13 +1049,13 @@ static bool ir_try_coalesce(ir_ctx *ctx, ir_live_range **unused, ir_ref from, ir
uint16_t f2 = ctx->live_intervals[v2]->flags; uint16_t f2 = ctx->live_intervals[v2]->flags;
if ((f1 & IR_LIVE_INTERVAL_COALESCED) && !(f2 & IR_LIVE_INTERVAL_COALESCED)) { if ((f1 & IR_LIVE_INTERVAL_COALESCED) && !(f2 & IR_LIVE_INTERVAL_COALESCED)) {
ir_vregs_join(ctx, unused, v1, v2); ir_vregs_join(ctx, v1, v2);
ctx->vregs[to] = v1; ctx->vregs[to] = v1;
} else if ((f2 & IR_LIVE_INTERVAL_COALESCED) && !(f1 & IR_LIVE_INTERVAL_COALESCED)) { } else if ((f2 & IR_LIVE_INTERVAL_COALESCED) && !(f1 & IR_LIVE_INTERVAL_COALESCED)) {
ir_vregs_join(ctx, unused, v2, v1); ir_vregs_join(ctx, v2, v1);
ctx->vregs[from] = v2; ctx->vregs[from] = v2;
} else if (from < to) { } else if (from < to) {
ir_vregs_join(ctx, unused, v1, v2); ir_vregs_join(ctx, v1, v2);
if (f2 & IR_LIVE_INTERVAL_COALESCED) { if (f2 & IR_LIVE_INTERVAL_COALESCED) {
for (i = 0; i < ctx->insns_count; i++) { for (i = 0; i < ctx->insns_count; i++) {
if (ctx->vregs[i] == v2) { if (ctx->vregs[i] == v2) {
@ -1065,7 +1066,7 @@ static bool ir_try_coalesce(ir_ctx *ctx, ir_live_range **unused, ir_ref from, ir
ctx->vregs[to] = v1; ctx->vregs[to] = v1;
} }
} else { } else {
ir_vregs_join(ctx,unused, v2, v1); ir_vregs_join(ctx, v2, v1);
if (f1 & IR_LIVE_INTERVAL_COALESCED) { if (f1 & IR_LIVE_INTERVAL_COALESCED) {
for (i = 0; i < ctx->insns_count; i++) { for (i = 0; i < ctx->insns_count; i++) {
if (ctx->vregs[i] == v1) { if (ctx->vregs[i] == v1) {
@ -1260,8 +1261,8 @@ int ir_coalesce(ir_ctx *ctx)
ir_insn *insn; ir_insn *insn;
ir_worklist blocks; ir_worklist blocks;
bool compact = 0; bool compact = 0;
ir_live_range *unused = NULL;
ctx->unused_ranges = NULL;
/* Collect a list of blocks which are predecossors to block with phi finctions */ /* Collect a list of blocks which are predecossors to block with phi finctions */
ir_worklist_init(&blocks, ctx->cfg_blocks_count + 1); ir_worklist_init(&blocks, ctx->cfg_blocks_count + 1);
for (b = 1, bb = &ctx->cfg_blocks[1]; b <= ctx->cfg_blocks_count; b++, bb++) { for (b = 1, bb = &ctx->cfg_blocks[1]; b <= ctx->cfg_blocks_count; b++, bb++) {
@ -1311,7 +1312,7 @@ int ir_coalesce(ir_ctx *ctx)
if (insn->op == IR_PHI) { if (insn->op == IR_PHI) {
input = ir_insn_op(insn, k); input = ir_insn_op(insn, k);
if (input > 0) { if (input > 0) {
if (!ir_try_coalesce(ctx, &unused, input, use)) { if (!ir_try_coalesce(ctx, input, use)) {
ir_add_phi_move(ctx, b, input, use); ir_add_phi_move(ctx, b, input, use);
} else { } else {
compact = 1; compact = 1;
@ -1323,8 +1324,9 @@ int ir_coalesce(ir_ctx *ctx)
} }
} }
} }
if (unused) { if (ctx->unused_ranges) {
ir_free_live_ranges(unused); ir_free_live_ranges(ctx->unused_ranges);
ctx->unused_ranges = NULL;
} }
ir_worklist_free(&blocks); ir_worklist_free(&blocks);