Skip to content

Commit

Permalink
Allow reuse of spill slots for objecs of smaller size
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Aug 2, 2023
1 parent 283f1a3 commit dd2ecad
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
1 change: 1 addition & 0 deletions ir_aarch64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -4754,6 +4754,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
data.ra_data.unused_slot_4 = 0;
data.ra_data.unused_slot_2 = 0;
data.ra_data.unused_slot_1 = 0;
data.ra_data.handled = NULL;
data.rodata_label = 0;
data.jmp_table_label = 0;
ctx->data = &data;
Expand Down
1 change: 1 addition & 0 deletions ir_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,7 @@ typedef struct _ir_reg_alloc_data {
int32_t unused_slot_4;
int32_t unused_slot_2;
int32_t unused_slot_1;
ir_live_interval **handled;
} ir_reg_alloc_data;

int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *data);
Expand Down
73 changes: 60 additions & 13 deletions ir_ra.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,13 +2377,21 @@ int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *dat
int32_t ret;
uint8_t size = ir_type_size[type];

if (size == 8) {
IR_ASSERT(size == 1 || size == 2 || size == 4 || size == 8);
if (data->handled && data->handled[size]) {
ret = data->handled[size]->stack_spill_pos;
data->handled[size] = data->handled[size]->list_next;
} else if (size == 8) {
ret = ctx->stack_frame_size;
ctx->stack_frame_size += 8;
} else if (size == 4) {
if (data->unused_slot_4) {
ret = data->unused_slot_4;
data->unused_slot_4 = 0;
} else if (data->handled && data->handled[8]) {
ret = data->handled[8]->stack_spill_pos;
data->handled[8] = data->handled[8]->list_next;
data->unused_slot_4 = ret + 4;
} else {
ret = ctx->stack_frame_size;
if (sizeof(void*) == 8) {
Expand All @@ -2401,6 +2409,15 @@ int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *dat
ret = data->unused_slot_4;
data->unused_slot_2 = data->unused_slot_4 + 2;
data->unused_slot_4 = 0;
} else if (data->handled && data->handled[4]) {
ret = data->handled[4]->stack_spill_pos;
data->handled[4] = data->handled[4]->list_next;
data->unused_slot_2 = ret + 2;
} else if (data->handled && data->handled[8]) {
ret = data->handled[8]->stack_spill_pos;
data->handled[8] = data->handled[8]->list_next;
data->unused_slot_2 = ret + 2;
data->unused_slot_4 = ret + 4;
} else {
ret = ctx->stack_frame_size;
data->unused_slot_2 = ctx->stack_frame_size + 2;
Expand All @@ -2425,6 +2442,21 @@ int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *dat
data->unused_slot_1 = data->unused_slot_4 + 1;
data->unused_slot_2 = data->unused_slot_4 + 2;
data->unused_slot_4 = 0;
} else if (data->handled && data->handled[2]) {
ret = data->handled[2]->stack_spill_pos;
data->handled[2] = data->handled[2]->list_next;
data->unused_slot_1 = ret + 1;
} else if (data->handled && data->handled[4]) {
ret = data->handled[4]->stack_spill_pos;
data->handled[4] = data->handled[4]->list_next;
data->unused_slot_1 = ret + 1;
data->unused_slot_2 = ret + 2;
} else if (data->handled && data->handled[8]) {
ret = data->handled[8]->stack_spill_pos;
data->handled[8] = data->handled[8]->list_next;
data->unused_slot_1 = ret + 1;
data->unused_slot_2 = ret + 2;
data->unused_slot_4 = ret + 4;
} else {
ret = ctx->stack_frame_size;
data->unused_slot_1 = ctx->stack_frame_size + 1;
Expand Down Expand Up @@ -3301,6 +3333,7 @@ static int ir_linear_scan(ir_ctx *ctx)
data.unused_slot_4 = 0;
data.unused_slot_2 = 0;
data.unused_slot_1 = 0;
data.handled = NULL;

while (vars) {
ir_insn *insn = &ctx->ir_base[vars];
Expand Down Expand Up @@ -3484,7 +3517,9 @@ static int ir_linear_scan(ir_ctx *ctx)
if (unhandled) {
uint8_t size;
ir_live_interval *handled[9] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
ir_live_interval *old;

data.handled = handled;
active = NULL;
while (unhandled) {
ival = unhandled;
Expand All @@ -3505,32 +3540,44 @@ static int ir_linear_scan(ir_ctx *ctx)
}
size = ir_type_size[other->type];
IR_ASSERT(size == 1 || size == 2 || size == 4 || size == 8);
other->list_next = handled[size];
handled[size] = other;
old = handled[size];
while (old) {
if (old->stack_spill_pos == other->stack_spill_pos) {
break;
}
old = old->list_next;
}
if (!old) {
other->list_next = handled[size];
handled[size] = other;
}
} else {
prev = other;
}
other = prev ? prev->list_next : active;
}

size = ir_type_size[ival->type];
IR_ASSERT(size == 1 || size == 2 || size == 4 || size == 8);
if (handled[size] != NULL) {
ival->stack_spill_pos = handled[size]->stack_spill_pos;
handled[size] = handled[size]->list_next;
} else {
ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type, &data);
}
ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type, &data);
if (unhandled && ival->end > unhandled->range.start) {
ival->list_next = active;
active = ival;
} else {
size = ir_type_size[ival->type];
IR_ASSERT(size == 1 || size == 2 || size == 4 || size == 8);
ival->list_next = handled[size];
handled[size] = ival;
old = handled[size];
while (old) {
if (old->stack_spill_pos == ival->stack_spill_pos) {
break;
}
old = old->list_next;
}
if (!old) {
ival->list_next = handled[size];
handled[size] = ival;
}
}
}
data.handled = NULL;
}
}

Expand Down
1 change: 1 addition & 0 deletions ir_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -7815,6 +7815,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
data.ra_data.unused_slot_4 = 0;
data.ra_data.unused_slot_2 = 0;
data.ra_data.unused_slot_1 = 0;
data.ra_data.handled = NULL;
data.rodata_label = 0;
data.jmp_table_label = 0;
data.double_neg_const = 0;
Expand Down

0 comments on commit dd2ecad

Please sign in to comment.