mirror of
https://github.com/danog/ir.git
synced 2024-12-03 10:08:29 +01:00
More accurate reslution of a register allocation conflict
This commit is contained in:
parent
1b88d998c8
commit
b1e6ae66e3
34
ir_ra.c
34
ir_ra.c
@ -2187,6 +2187,16 @@ static ir_live_pos ir_first_use_pos_after(ir_live_interval *ival, ir_live_pos po
|
||||
return p ? p->pos : 0x7fffffff;
|
||||
}
|
||||
|
||||
static ir_live_pos ir_first_use_pos(ir_live_interval *ival, uint8_t flags)
|
||||
{
|
||||
ir_use_pos *p = ival->use_pos;
|
||||
|
||||
while (p && !(p->flags & flags)) {
|
||||
p = p->next;
|
||||
}
|
||||
return p ? p->pos : 0x7fffffff;
|
||||
}
|
||||
|
||||
static ir_block *ir_block_from_live_pos(ir_ctx *ctx, ir_live_pos pos)
|
||||
{
|
||||
ir_ref ref = IR_LIVE_POS_TO_REF(pos);
|
||||
@ -3012,6 +3022,7 @@ spill_current:
|
||||
return IR_REG_NONE;
|
||||
}
|
||||
if (split_pos >= blockPos[reg]) {
|
||||
try_next_available_register:
|
||||
IR_REGSET_EXCL(available, reg);
|
||||
if (IR_REGSET_IS_EMPTY(available)) {
|
||||
fprintf(stderr, "LSRA Internal Error: Unsolvable conflict. Allocation is not possible\n");
|
||||
@ -3052,13 +3063,22 @@ spill_current:
|
||||
child = ir_split_interval_at(ctx, other, split_pos);
|
||||
IR_LOG_LSRA(" ---- Finish", other, "");
|
||||
} else {
|
||||
if (ir_first_use_pos_after(other, other->range.start, IR_USE_MUST_BE_IN_REG) < other->end) {
|
||||
if (next_use_pos > ival->range.start && !(ival->flags & IR_LIVE_INTERVAL_TEMP)) {
|
||||
goto spill_current;
|
||||
}
|
||||
fprintf(stderr, "LSRA Internal Error: Unsolvable conflict. Allocation is not possible\n");
|
||||
IR_ASSERT(0);
|
||||
exit(-1);
|
||||
if (ir_first_use_pos(other, IR_USE_MUST_BE_IN_REG) <= other->end) {
|
||||
if (!(ival->flags & IR_LIVE_INTERVAL_TEMP)) {
|
||||
next_use_pos = ir_first_use_pos(ival, IR_USE_MUST_BE_IN_REG);
|
||||
if (next_use_pos == ival->range.start) {
|
||||
IR_ASSERT(ival->use_pos && ival->use_pos->op_num == 0);
|
||||
/* split right after definition */
|
||||
split_pos = next_use_pos + 1;
|
||||
} else {
|
||||
split_pos = ir_find_optimal_split_position(ctx, ival, ival->range.start, next_use_pos - 1, 1);
|
||||
}
|
||||
|
||||
if (split_pos > ival->range.start) {
|
||||
goto spill_current;
|
||||
}
|
||||
}
|
||||
goto try_next_available_register;
|
||||
}
|
||||
child = other;
|
||||
other->reg = IR_REG_NONE;
|
||||
|
Loading…
Reference in New Issue
Block a user