From 477dbf7d762051c672b1a963fe98886948458002 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 18 May 2023 13:37:12 +0300 Subject: [PATCH] Avoid live range constrction for RLOAD with fixed registers --- ir_aarch64.dasc | 5 +++++ ir_ra.c | 42 ++++++++++++++++++++++++++++-------------- ir_x86.dasc | 5 +++++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/ir_aarch64.dasc b/ir_aarch64.dasc index 4730e08..836e814 100644 --- a/ir_aarch64.dasc +++ b/ir_aarch64.dasc @@ -739,6 +739,11 @@ binop_fp: return IR_STORE_FP; } break; + case IR_RLOAD: + if (IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)) { + return IR_SKIPPED | IR_RLOAD; + } + return IR_RLOAD; case IR_RSTORE: if (IR_IS_TYPE_INT(ctx->ir_base[insn->op2].type)) { if ((ctx->flags & IR_OPT_CODEGEN) && ir_in_same_block(ctx, insn->op2) && ctx->use_lists[insn->op2].count == 1) { diff --git a/ir_ra.c b/ir_ra.c index 5891d09..3db6e9d 100644 --- a/ir_ra.c +++ b/ir_ra.c @@ -541,6 +541,8 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block } else if (ctx->rules[child] & IR_FUSED) { IR_ASSERT(stack_pos < (int)(sizeof(stack)/sizeof(stack_pos))); stack[stack_pos++] = child; + } else if (ctx->rules[child] == (IR_SKIPPED|IR_RLOAD)) { + ir_set_alocated_reg(ctx, input, j, ctx->ir_base[child].op2); } } } @@ -570,6 +572,11 @@ int ir_compute_live_ranges(ir_ctx *ctx) return 0; } + if (ctx->rules) { + ctx->regs = ir_mem_malloc(sizeof(ir_regs) * ctx->insns_count); + memset(ctx->regs, IR_REG_NONE, sizeof(ir_regs) * ctx->insns_count); + } + /* Compute Live Ranges */ ctx->flags &= ~(IR_LR_HAVE_VARS|IR_LR_HAVE_DESSA_MOVES); len = ir_bitset_len(ctx->vregs_count + 1); @@ -715,12 +722,9 @@ int ir_compute_live_ranges(ir_ctx *ctx) ival = ir_fix_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), IR_DEF_LIVE_POS_FROM_REF(ref)); ival->type = insn->type; - if (IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)) { - ival->flags = IR_LIVE_INTERVAL_REG_LOAD; - ival->reg = insn->op2; - } else { - ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), insn->op2, IR_USE_SHOULD_BE_IN_REG, 0); - } + /* Fixed RLOADs are handled without live-ranges */ + IR_ASSERT(!IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)); + ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), insn->op2, IR_USE_SHOULD_BE_IN_REG, 0); continue; } else if (insn->op != IR_PHI) { ir_live_pos def_pos; @@ -851,6 +855,8 @@ int ir_compute_live_ranges(ir_ctx *ctx) IR_ASSERT(ctx->rules); if (ctx->rules[input] & IR_FUSED) { ir_add_fusion_ranges(ctx, ref, input, bb, live); + } else if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { + ir_set_alocated_reg(ctx, ref, j, ctx->ir_base[input].op2); } } else { if (reg != IR_REG_NONE) { @@ -1219,6 +1225,8 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block } else if (ctx->rules[child] & IR_FUSED) { IR_ASSERT(stack_pos < (int)(sizeof(stack)/sizeof(stack_pos))); stack[stack_pos++] = child; + } else if (ctx->rules[child] == (IR_SKIPPED|IR_RLOAD)) { + ir_set_alocated_reg(ctx, input, j, ctx->ir_base[child].op2); } } } @@ -1244,6 +1252,11 @@ int ir_compute_live_ranges(ir_ctx *ctx) return 0; } + if (ctx->rules) { + ctx->regs = ir_mem_malloc(sizeof(ir_regs) * ctx->insns_count); + memset(ctx->regs, IR_REG_NONE, sizeof(ir_regs) * ctx->insns_count); + } + /* Compute Live Ranges */ ctx->flags &= ~(IR_LR_HAVE_VARS|IR_LR_HAVE_DESSA_MOVES); @@ -1349,12 +1362,9 @@ int ir_compute_live_ranges(ir_ctx *ctx) ival = ir_fix_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), IR_DEF_LIVE_POS_FROM_REF(ref)); ival->type = insn->type; - if (IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)) { - ival->flags = IR_LIVE_INTERVAL_REG_LOAD; - ival->reg = insn->op2; - } else { - ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), insn->op2, IR_USE_SHOULD_BE_IN_REG, 0); - } + /* Fixed RLOADs are handled without live-ranges */ + IR_ASSERT(!IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)); + ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), insn->op2, IR_USE_SHOULD_BE_IN_REG, 0); continue; } else if (insn->op != IR_PHI) { ir_live_pos def_pos; @@ -1483,6 +1493,8 @@ int ir_compute_live_ranges(ir_ctx *ctx) IR_ASSERT(ctx->rules); if (ctx->rules[input] & IR_FUSED) { ir_add_fusion_ranges(ctx, ref, input, bb, live_in_block, b); + } else if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { + ir_set_alocated_reg(ctx, ref, j, ctx->ir_base[input].op2); } } else { if (reg != IR_REG_NONE) { @@ -3512,8 +3524,10 @@ static void assign_regs(ir_ctx *ctx) int8_t reg; ir_ref ref; - ctx->regs = ir_mem_malloc(sizeof(ir_regs) * ctx->insns_count); - memset(ctx->regs, IR_REG_NONE, sizeof(ir_regs) * ctx->insns_count); + if (!ctx->regs) { + ctx->regs = ir_mem_malloc(sizeof(ir_regs) * ctx->insns_count); + memset(ctx->regs, IR_REG_NONE, sizeof(ir_regs) * ctx->insns_count); + } for (i = 1; i <= ctx->vregs_count; i++) { top_ival = ival = ctx->live_intervals[i]; diff --git a/ir_x86.dasc b/ir_x86.dasc index 35b712f..64bda56 100644 --- a/ir_x86.dasc +++ b/ir_x86.dasc @@ -1523,6 +1523,11 @@ store_int: return IR_STORE_FP; } break; + case IR_RLOAD: + if (IR_REGSET_IN(IR_REGSET_UNION(ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)) { + return IR_SKIPPED | IR_RLOAD; + } + return IR_RLOAD; case IR_RSTORE: if (IR_IS_TYPE_INT(ctx->ir_base[insn->op2].type)) { if ((ctx->flags & IR_OPT_CODEGEN)