Add hints and fixed intrvals for parameters

This commit is contained in:
Dmitry Stogov 2022-04-07 14:18:59 +03:00
parent 5b34386f62
commit 23bd7fb272
3 changed files with 103 additions and 33 deletions

39
ir_ra.c
View File

@ -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; reg = ctx->rules ? ir_uses_fixed_reg(ctx, i, 0) : IR_REG_NONE;
if (reg != 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); ir_add_use(ctx, ctx->vregs[i], 0, i * 2, reg);
/* live.remove(opd) */ /* live.remove(opd) */
@ -790,13 +795,29 @@ static bool ir_live_range_covers(ir_live_interval *ival, ir_ref position)
return 0; 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) 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]; ir_ref freeUntilPos[IR_REG_NUM];
int i, reg; int i, reg;
ir_ref pos, next; ir_ref pos, next;
ir_live_interval *ival = ctx->live_intervals[current]; ir_live_interval *ival = ctx->live_intervals[current];
ir_use_pos *use_pos;
ir_regset available; ir_regset available;
if (IR_IS_TYPE_FP(ival->type)) { 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(); } IR_BITSET_FOREACH_END();
/* Try to use hint */ /* Try to use hint */
use_pos = ival->use_pos; reg = ir_try_allocate_preferred_reg(ival, freeUntilPos);
while (use_pos) { if (reg != IR_REG_NONE) {
if (use_pos->hint >= 0) { ival->reg = reg;
if (ir_live_range_end(ival) <= freeUntilPos[use_pos->hint]) { return reg;
/* register available for the whole interval */
ival->reg = use_pos->hint;
return reg;
}
}
use_pos = use_pos->next;
} }
reg = IR_REGSET_FIRST(available); reg = IR_REGSET_FIRST(available);

View File

@ -809,6 +809,49 @@ ir_regset ir_get_fixed_regset(ir_ctx *ctx, ir_ref ref)
return IR_REGSET_EMPTY; 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_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num)
{ {
ir_ref rule; 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) { if (op_num == 2) {
return IR_REG_XMM0; 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; 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++) { for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
use = *p; use = *p;
insn = &ctx->ir_base[use]; insn = &ctx->ir_base[use];
if (insn->op == IR_PARAM && ctx->vregs[use]) { if (insn->op == IR_PARAM) {
if (IR_IS_TYPE_INT(insn->type)) { if (ctx->vregs[use]) {
if (int_param_num < int_reg_params_count) { if (IR_IS_TYPE_INT(insn->type)) {
src_reg = int_reg_params[int_param_num]; 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 { } else {
// TODO: replace IR_REG_NONE by stack slot if (fp_param_num < fp_reg_params_count) {
src_reg = IR_REG_NONE; 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 { } else {
if (fp_param_num < fp_reg_params_count) { if (IR_IS_TYPE_INT(insn->type)) {
src_reg = fp_reg_params[fp_param_num]; int_param_num++;
} else { } else {
// TODO: replace IR_REG_NONE by stack slot fp_param_num++;
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);
} }
} }
} }

View File

@ -228,10 +228,10 @@ uint32_t __inline __ir_clz(uint32_t value) {
# define IR_REG_FP_RET1 IR_REG_XMM0 # define IR_REG_FP_RET1 IR_REG_XMM0
# define IR_REG_INT_ARGS 6 # define IR_REG_INT_ARGS 6
# define IR_REG_FP_ARGS 8 # define IR_REG_FP_ARGS 8
# define IR_REG_INT_ARG1 IR_REG_RSI # define IR_REG_INT_ARG1 IR_REG_RDI
# define IR_REG_INT_ARG2 IR_REG_RDI # define IR_REG_INT_ARG2 IR_REG_RSI
# define IR_REG_INT_ARG3 IR_REG_RCX # define IR_REG_INT_ARG3 IR_REG_RDX
# define IR_REG_INT_ARG4 IR_REG_RDX # define IR_REG_INT_ARG4 IR_REG_RCX
# define IR_REG_INT_ARG5 IR_REG_R8 # define IR_REG_INT_ARG5 IR_REG_R8
# define IR_REG_INT_ARG6 IR_REG_R9 # define IR_REG_INT_ARG6 IR_REG_R9
# define IR_REG_FP_ARG1 IR_REG_XMM0 # define IR_REG_FP_ARG1 IR_REG_XMM0