Inline fast path

This commit is contained in:
Dmitry Stogov 2023-05-05 18:37:14 +03:00
parent c3fca224ff
commit d859591943

58
ir_ra.c
View File

@ -138,33 +138,36 @@ 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 ir_live_interval *ir_new_live_range(ir_ctx *ctx, int v, ir_live_pos start, ir_live_pos end)
{
ir_live_interval *ival = ir_arena_alloc(&ctx->arena, sizeof(ir_live_interval));
ival->type = IR_VOID;
ival->reg = IR_REG_NONE;
ival->flags = 0;
ival->vreg = v;
ival->stack_spill_pos = -1; // not allocated
ival->range.start = start;
ival->range.end = ival->end = end;
ival->range.next = NULL;
ival->use_pos = NULL;
ival->next = NULL;
ctx->live_intervals[v] = ival;
return ival;
}
static ir_live_interval *ir_add_live_range(ir_ctx *ctx, int v, ir_live_pos start, ir_live_pos end) static ir_live_interval *ir_add_live_range(ir_ctx *ctx, int v, 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; ir_live_range *p, *q;
if (!ival) { if (!ival) {
ival = ir_arena_alloc(&ctx->arena, sizeof(ir_live_interval)); return ir_new_live_range(ctx, v, start, end);
ival->type = IR_VOID;
ival->reg = IR_REG_NONE;
ival->flags = 0;
ival->vreg = v;
ival->stack_spill_pos = -1; // not allocated
ival->range.start = start;
ival->range.end = ival->end = end;
ival->range.next = NULL;
ival->use_pos = NULL;
ival->next = NULL;
ctx->live_intervals[v] = ival;
return ival;
} }
p = &ival->range; p = &ival->range;
if (end == p->start) { if (end >= p->start) {
p->start = start;
return ival;
} else if (end > p->start) {
ir_live_range *prev = NULL; ir_live_range *prev = NULL;
do { do {
@ -231,6 +234,17 @@ static ir_live_interval *ir_add_live_range(ir_ctx *ctx, int v, ir_live_pos start
return ival; return ival;
} }
IR_ALWAYS_INLINE ir_live_interval *ir_add_prev_live_range(ir_ctx *ctx, int v, ir_live_pos start, ir_live_pos end)
{
ir_live_interval *ival = ctx->live_intervals[v];
if (ival && ival->range.start == end) {
ival->range.start = start;
return ival;
}
return ir_add_live_range(ctx, v, start, end);
}
static void ir_add_fixed_live_range(ir_ctx *ctx, 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;
@ -612,7 +626,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, i, ir_add_prev_live_range(ctx, i,
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();
@ -639,7 +653,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
IR_ASSERT(v); IR_ASSERT(v);
ir_bitset_incl(live, v); ir_bitset_incl(live, v);
/* intervals[phi.inputOf(b)].addRange(b.from, b.to) */ /* intervals[phi.inputOf(b)].addRange(b.from, b.to) */
ival = ir_add_live_range(ctx, v, ival = ir_add_prev_live_range(ctx, v,
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, ival, k, IR_DEF_LIVE_POS_FROM_REF(bb->end), use); ir_add_phi_use(ctx, ival, k, IR_DEF_LIVE_POS_FROM_REF(bb->end), use);
@ -940,7 +954,7 @@ IR_ALWAYS_INLINE void ir_live_out_push(ir_ctx *ctx, uint32_t *live_outs, ir_list
#if 0 #if 0
ir_block *bb = &ctx->cfg_blocks[b]; ir_block *bb = &ctx->cfg_blocks[b];
live_outs[b] = v; live_outs[b] = v;
ir_add_live_range(ctx, v, ir_add_prev_live_range(ctx, v,
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));
#else #else
@ -1251,7 +1265,7 @@ int ir_compute_live_ranges(ir_ctx *ctx)
while (n != 0) { while (n != 0) {
i = ir_list_at(&live_lists, n); i = ir_list_at(&live_lists, n);
SET_LIVE_IN_BLOCK(i, b); SET_LIVE_IN_BLOCK(i, b);
ir_add_live_range(ctx, i, ir_add_prev_live_range(ctx, i,
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));
n = ir_list_at(&live_lists, n - 1); n = ir_list_at(&live_lists, n - 1);