mirror of
https://github.com/danog/ir.git
synced 2024-11-26 20:34:53 +01:00
Add hints and fixed intrvals for parameters
This commit is contained in:
parent
5b34386f62
commit
23bd7fb272
39
ir_ra.c
39
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);
|
||||
|
89
ir_x86.dasc
89
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
ir_x86.h
8
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
|
||||
|
Loading…
Reference in New Issue
Block a user