Improve spill code fusion

This commit is contained in:
Dmitry Stogov 2022-09-15 17:52:28 +03:00
parent 367e47ac30
commit e6f6e92d66
2 changed files with 25 additions and 3 deletions

View File

@ -294,7 +294,12 @@ void ir_dump_live_ranges(ir_ctx *ctx, FILE *f)
}
fprintf(f, ")");
if (ival->stack_spill_pos != -1) {
fprintf(f, " [SPILL=0x%x]", ival->stack_spill_pos);
if (ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) {
IR_ASSERT(ctx->spill_base >= 0);
fprintf(f, " [SPILL=0x%x(%%%s)]", ival->stack_spill_pos, ir_reg_name(ctx->spill_base, IR_ADDR));
} else {
fprintf(f, " [SPILL=0x%x]", ival->stack_spill_pos);
}
}
}
if (ival->next) {

21
ir_ra.c
View File

@ -2399,14 +2399,32 @@ static void assign_regs(ir_ctx *ctx)
if (ival->reg >= 0) {
use_pos = ival->use_pos;
while (use_pos) {
ref = IR_LIVE_POS_TO_REF(use_pos->pos);
reg = ival->reg;
if (use_pos->op_num == 0
&& (use_pos->flags & IR_DEF_REUSES_OP1_REG)
&& ctx->regs[ref][1] != IR_REG_NONE
&& (ctx->regs[ref][1] & IR_REG_SPILL_LOAD)) {
/* load op1 directly into result (valid only when op1 register is not reused) */
ctx->regs[ref][1] = reg | IR_REG_SPILL_LOAD;
}
if (ival->top->stack_spill_pos != -1) {
// TODO: Insert spill loads and stotres in optimal positons (resolution)
if (use_pos->op_num == 0) {
reg |= IR_REG_SPILL_STORE;
} else {
reg |= IR_REG_SPILL_LOAD;
if ((use_pos->flags & IR_USE_MUST_BE_IN_REG)
|| ctx->ir_base[ref].op == IR_CALL
|| ctx->ir_base[ref].op == IR_TAILCALL
|| (use_pos->op_num == 2
&& ctx->ir_base[ref].op1 == ctx->ir_base[ref].op2
&& IR_REG_NUM(ctx->regs[ref][1]) == reg)) {
reg |= IR_REG_SPILL_LOAD;
} else {
/* fuse spill load (valid only when register is not reused) */
reg = IR_REG_NONE;
}
}
}
if (use_pos->flags & IR_PHI_USE) {
@ -2415,7 +2433,6 @@ static void assign_regs(ir_ctx *ctx)
IR_ASSERT(use_pos->op_num <= IR_MAX(3, ir_input_edges_count(ctx, &ctx->ir_base[ref])));
ctx->regs[ref][use_pos->op_num] = reg;
} else {
ref = IR_LIVE_POS_TO_REF(use_pos->pos);
IR_ASSERT(use_pos->op_num <= IR_MAX(3, ir_input_edges_count(ctx, &ctx->ir_base[ref])));
ctx->regs[ref][use_pos->op_num] = reg;
}