mirror of
https://github.com/danog/ir.git
synced 2025-01-22 05:31:32 +01:00
Cache deleted live ranges in ir_ctx.unused_ranges
This commit is contained in:
parent
1f447a538b
commit
0b78a322f8
2
ir.h
2
ir.h
@ -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 {
|
||||||
|
@ -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
88
ir_ra.c
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user