From 23bd7fb272a589db608036df205511037b8a290e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 7 Apr 2022 14:18:59 +0300 Subject: [PATCH] Add hints and fixed intrvals for parameters --- ir_ra.c | 39 +++++++++++++++-------- ir_x86.dasc | 89 +++++++++++++++++++++++++++++++++++++++++++---------- ir_x86.h | 8 ++--- 3 files changed, 103 insertions(+), 33 deletions(-) diff --git a/ir_ra.c b/ir_ra.c index 31156fa..357208c 100644 --- a/ir_ra.c +++ b/ir_ra.c @@ -309,7 +309,12 @@ int ir_compute_live_ranges(ir_ctx *ctx) } reg = ctx->rules ? ir_uses_fixed_reg(ctx, i, 0) : IR_REG_NONE; if (reg != IR_REG_NONE) { - ir_add_fixed_live_range(ctx, reg, i * 2, i * 2); + if (insn->op == IR_PARAM) { + /* parameter register must be kept before it's copied */ + ir_add_fixed_live_range(ctx, reg, 2, i * 2); + } else { + ir_add_fixed_live_range(ctx, reg, i * 2, i * 2); + } } ir_add_use(ctx, ctx->vregs[i], 0, i * 2, reg); /* live.remove(opd) */ @@ -790,13 +795,29 @@ static bool ir_live_range_covers(ir_live_interval *ival, ir_ref position) return 0; } +static ir_ref ir_try_allocate_preferred_reg(ir_live_interval *ival, ir_ref *freeUntilPos) +{ + ir_use_pos *use_pos; + + use_pos = ival->use_pos; + while (use_pos) { + if (use_pos->hint >= 0) { + if (ir_live_range_end(ival) <= freeUntilPos[use_pos->hint]) { + /* register available for the whole interval */ + return use_pos->hint; + } + } + use_pos = use_pos->next; + } + return IR_REG_NONE; +} + static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, int current, uint32_t len, ir_bitset active, ir_bitset inactive) { ir_ref freeUntilPos[IR_REG_NUM]; int i, reg; ir_ref pos, next; ir_live_interval *ival = ctx->live_intervals[current]; - ir_use_pos *use_pos; ir_regset available; if (IR_IS_TYPE_FP(ival->type)) { @@ -845,16 +866,10 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, int current, uint32_t len, i } IR_BITSET_FOREACH_END(); /* Try to use hint */ - use_pos = ival->use_pos; - while (use_pos) { - if (use_pos->hint >= 0) { - if (ir_live_range_end(ival) <= freeUntilPos[use_pos->hint]) { - /* register available for the whole interval */ - ival->reg = use_pos->hint; - return reg; - } - } - use_pos = use_pos->next; + reg = ir_try_allocate_preferred_reg(ival, freeUntilPos); + if (reg != IR_REG_NONE) { + ival->reg = reg; + return reg; } reg = IR_REGSET_FIRST(available); diff --git a/ir_x86.dasc b/ir_x86.dasc index 46f6737..e9eddfd 100644 --- a/ir_x86.dasc +++ b/ir_x86.dasc @@ -809,6 +809,49 @@ ir_regset ir_get_fixed_regset(ir_ctx *ctx, ir_ref ref) return IR_REGSET_EMPTY; } +static ir_reg ir_get_param_reg(ir_ctx *ctx, ir_ref ref) +{ + ir_use_list *use_list = &ctx->use_lists[1]; + int i; + ir_ref use, *p; + ir_insn *insn; + int int_param = 0; + int fp_param = 0; + int int_reg_params_count = IR_REG_INT_ARGS; + int fp_reg_params_count = IR_REG_FP_ARGS; + const int8_t *int_reg_params = _ir_int_reg_params; + const int8_t *fp_reg_params = _ir_fp_reg_params; + + for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + use = *p; + insn = &ctx->ir_base[use]; + if (insn->op == IR_PARAM) { + if (IR_IS_TYPE_INT(insn->type)) { + if (use == ref) { + if (int_param < int_reg_params_count) { + return int_reg_params[int_param]; + } else { + return IR_REG_NONE; + } + } + int_param++; + } else if (IR_IS_TYPE_FP(insn->type)) { + if (use == ref) { + if (fp_param < fp_reg_params_count) { + return fp_reg_params[fp_param]; + } else { + return IR_REG_NONE; + } + } + fp_param++; + } else { + IR_ASSERT(0); + } + } + } + return IR_REG_NONE; +} + ir_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num) { ir_ref rule; @@ -836,6 +879,10 @@ ir_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num) if (op_num == 2) { return IR_REG_XMM0; } + } else if (rule == IR_SKIP_REG) { + if (ctx->ir_base[ref].op == IR_PARAM && op_num == 0) { + return ir_get_param_reg(ctx, ref); + } } return IR_REG_NONE; } @@ -3038,28 +3085,36 @@ static void ir_emit_load_params(ir_ctx *ctx) for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { use = *p; insn = &ctx->ir_base[use]; - if (insn->op == IR_PARAM && ctx->vregs[use]) { - if (IR_IS_TYPE_INT(insn->type)) { - if (int_param_num < int_reg_params_count) { - src_reg = int_reg_params[int_param_num]; + if (insn->op == IR_PARAM) { + if (ctx->vregs[use]) { + if (IR_IS_TYPE_INT(insn->type)) { + if (int_param_num < int_reg_params_count) { + src_reg = int_reg_params[int_param_num]; + } else { + // TODO: replace IR_REG_NONE by stack slot + src_reg = IR_REG_NONE; + } + int_param_num++; } else { - // TODO: replace IR_REG_NONE by stack slot - src_reg = IR_REG_NONE; + if (fp_param_num < fp_reg_params_count) { + src_reg = fp_reg_params[fp_param_num]; + } else { + // TODO: replace IR_REG_NONE by stack slot + src_reg = IR_REG_NONE; + } + fp_param_num++; + } + dst_reg = ctx->live_intervals[ctx->vregs[use]]->reg; + if (src_reg != dst_reg) { + // TODO: DO parallel move + ir_emit_param_move(ctx, insn->type, src_reg, ctx->vregs[use], insn->op2); } - int_param_num++; } else { - if (fp_param_num < fp_reg_params_count) { - src_reg = fp_reg_params[fp_param_num]; + if (IR_IS_TYPE_INT(insn->type)) { + int_param_num++; } else { - // TODO: replace IR_REG_NONE by stack slot - src_reg = IR_REG_NONE; + fp_param_num++; } - fp_param_num++; - } - dst_reg = ctx->live_intervals[ctx->vregs[use]]->reg; - if (src_reg != dst_reg) { - // TODO: DO parallel move - ir_emit_param_move(ctx, insn->type, src_reg, ctx->vregs[use], insn->op2); } } } diff --git a/ir_x86.h b/ir_x86.h index bdd0646..a667e16 100644 --- a/ir_x86.h +++ b/ir_x86.h @@ -228,10 +228,10 @@ uint32_t __inline __ir_clz(uint32_t value) { # define IR_REG_FP_RET1 IR_REG_XMM0 # define IR_REG_INT_ARGS 6 # define IR_REG_FP_ARGS 8 -# define IR_REG_INT_ARG1 IR_REG_RSI -# define IR_REG_INT_ARG2 IR_REG_RDI -# define IR_REG_INT_ARG3 IR_REG_RCX -# define IR_REG_INT_ARG4 IR_REG_RDX +# define IR_REG_INT_ARG1 IR_REG_RDI +# define IR_REG_INT_ARG2 IR_REG_RSI +# define IR_REG_INT_ARG3 IR_REG_RDX +# define IR_REG_INT_ARG4 IR_REG_RCX # define IR_REG_INT_ARG5 IR_REG_R8 # define IR_REG_INT_ARG6 IR_REG_R9 # define IR_REG_FP_ARG1 IR_REG_XMM0