mirror of
https://github.com/danog/ir.git
synced 2024-11-30 04:39:43 +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;
|
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);
|
||||||
|
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;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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_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
|
||||||
|
Loading…
Reference in New Issue
Block a user