Avoid reservaton of temporary resiser for argument passing

We may use any scratch register that is not used for parameters
This commit is contained in:
Dmitry Stogov 2023-04-26 12:16:05 +03:00
parent 0de0c1d0fa
commit 9eb366698d
20 changed files with 38 additions and 132 deletions

View File

@ -252,36 +252,6 @@ enum _ir_rule {
};
/* register allocation */
static bool ir_call_needs_tmp_int_reg(const ir_ctx *ctx, const ir_insn *insn)
{
ir_ref arg;
ir_insn *arg_insn;
int j, n;
ir_type type;
int int_param = 0;
int int_reg_params_count = IR_REG_INT_ARGS;
n = insn->inputs_count;
for (j = 3; j <= n; j++) {
arg = ir_insn_op(insn, j);
arg_insn = &ctx->ir_base[arg];
type = arg_insn->type;
if (IR_IS_TYPE_INT(type)) {
if (IR_IS_CONST_REF(arg)) {
return 1;
} else if (int_param < int_reg_params_count) {
if (int_param > 0) {
return 1; /* for swap */
}
} else {
return 1; /* for mem -> stack copy */
}
int_param++;
}
}
return 0;
}
int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints)
{
uint32_t rule = ir_rule(ctx, ref);
@ -466,10 +436,6 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (ir_call_needs_tmp_int_reg(ctx, insn)) {
constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF);
n++;
}
}
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break;
@ -3505,7 +3471,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack;
}
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg)
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
@ -3524,6 +3490,8 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
int32_t used_stack, stack_offset = 0;
ir_copy *copies;
bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_IP0;
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn);
@ -3714,7 +3682,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -3783,7 +3751,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (used_stack != 0) {
ir_emit_call(ctx, def, insn);

View File

@ -515,50 +515,6 @@ enum _ir_rule {
};
/* register allocation */
static bool ir_call_needs_tmp_int_reg(const ir_ctx *ctx, const ir_insn *insn)
{
ir_ref arg;
ir_insn *arg_insn;
int j, n;
ir_type type;
int int_param = 0;
int int_reg_params_count = IR_REG_INT_ARGS;
#ifdef IR_HAVE_FASTCALL
if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) {
int_reg_params_count = IR_REG_INT_FCARGS;
}
#endif
n = insn->inputs_count;
for (j = 3; j <= n; j++) {
arg = ir_insn_op(insn, j);
arg_insn = &ctx->ir_base[arg];
type = arg_insn->type;
if (IR_IS_TYPE_INT(type)) {
if (IR_IS_CONST_REF(arg)) {
if (arg_insn->op == IR_STR || !IR_IS_SIGNED_32BIT(arg_insn->val.i64)) {
return 1;
}
} else {
if (int_param < int_reg_params_count) {
if (int_param > 0) {
return 1; /* for swap */
}
} else {
return 1; /* for mem -> stack copy */
}
}
int_param++;
} else if (type == IR_DOUBLE) {
if (IR_IS_CONST_REF(arg) && arg_insn->val.i64 != 0) {
return 1;
}
}
}
return 0;
}
int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints)
{
uint32_t rule = ir_rule(ctx, ref);
@ -783,10 +739,6 @@ op2_const:
if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (ir_call_needs_tmp_int_reg(ctx, insn)) {
constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF);
n++;
}
}
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break;
@ -5897,7 +5849,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack;
}
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg)
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
@ -5916,6 +5868,8 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
int32_t used_stack, stack_offset = IR_SHADOW_ARGS;
ir_copy *copies;
bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_RAX;
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn);
@ -6205,7 +6159,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -6308,7 +6262,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
(void) used_stack;
if (used_stack != 0) {

View File

@ -60,7 +60,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%rax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%eax]: [2.2-2.3)/1
[%rax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%edx), PHI_USE(12.2, phi=d_4/3)

View File

@ -35,12 +35,12 @@ test:
movz x5, #0x1, lsl #32
movz x6, #0x6
movz w7, #0x7
movz w8, #0x8
str x8, [sp]
movz x8, #0x9
str x8, [sp, #8]
movz x8, #0x1, lsl #32
str x8, [sp, #0x10]
movz w16, #0x8
str x16, [sp]
movz x16, #0x9
str x16, [sp, #8]
movz x16, #0x1, lsl #32
str x16, [sp, #0x10]
bl _IO_printf
add sp, sp, #0x20
ldp x29, x30, [sp], #0x10

View File

@ -27,10 +27,10 @@ test:
mov x29, sp
str x19, [x29, #0x18]
mov w19, w0
mov w4, w1
mov w16, w1
mov w1, w2
mov w2, w3
mov w3, w4
mov w3, w16
adr x0, .L1
bl _IO_printf
add w0, w0, w19

View File

@ -25,10 +25,10 @@ test:
str x19, [x29, #0x18]
mov w19, w0
ldr x4, [x4]
mov w5, w1
mov w16, w1
mov w1, w2
mov w2, w3
mov w3, w5
mov w3, w16
adr x0, .L1
blr x4
add w0, w0, w19

View File

@ -37,10 +37,10 @@ test:
mov w2, w1
mov w1, w0
adr x0, .L1
ldr w9, [x29, #0x20]
str w9, [sp, #8]
ldr w9, [x29, #0x28]
str w9, [sp, #0x10]
ldr w16, [x29, #0x20]
str w16, [sp, #8]
ldr w16, [x29, #0x28]
str w16, [sp, #0x10]
bl _IO_printf
add sp, sp, #0x20
ldp x29, x30, [sp], #0x10

View File

@ -61,7 +61,6 @@ aarch64
TMP
[%d0]: [2.2-2.3)/3
[%d0]: [7.0-7.2)/6.2
[%x1]: [11.0-11.1)/1
R1 (d_4, d_10) [SPILL=0x0]
[%d0]: [3.0-7.0), DEF(4.2)
: [7.0-8.0)

View File

@ -61,8 +61,6 @@ aarch64
TMP
[%d0]: [2.2-2.3)/3
[%d0]: [7.0-7.2)/6.2
[%x1]: [11.0-11.1)/1
[%x1]: [13.0-13.1)/1
R1 (d_4, d_10) [SPILL=0x0]
[%d0]: [3.0-7.0), DEF(4.2)
: [7.0-8.0)

View File

@ -56,7 +56,6 @@ aarch64
TMP
[%w0]: [2.2-2.3)/1
[%w1]: [7.0-7.2)/6.2
[%x2]: [10.0-10.1)/1
[%w0]: [12.2-12.3)/1
R1 (d_4) [%w0]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%w18]: [3.0-13.0), DEF(5.2), USE(7.1/6.1)!, USE(9.1/1)!, USE(10.0/4, hint=%w1), PHI_USE(12.2, phi=d_4/3)

View File

@ -25,12 +25,12 @@ test:
movl 0x20(%esp), %ebx
movl 0x30(%esp), %eax
movl $.L1, (%esp)
movl 0x28(%esp), %ecx
movl %ecx, 4(%esp)
movl 0x2c(%esp), %ecx
movl %ecx, 8(%esp)
movl 0x24(%esp), %ecx
movl %ecx, 0xc(%esp)
movl 0x28(%esp), %eax
movl %eax, 4(%esp)
movl 0x2c(%esp), %eax
movl %eax, 8(%esp)
movl 0x24(%esp), %eax
movl %eax, 0xc(%esp)
calll *(%eax)
addl %ebx, %eax
movl 0x18(%esp), %ebx

View File

@ -60,7 +60,6 @@ x86
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%eax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ x86
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%eax]: [11.0-11.1)/1
[%eax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ x86
{ # LIVE-RANGES (vregs_count=3)
TMP
[%eax]: [2.2-2.3)/1
[%eax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.1/4), PHI_USE(12.2, phi=d_4/3)

View File

@ -33,14 +33,14 @@ test:
movl %esi, %edx
movl %edi, %esi
leaq .L1(%rip), %rdi
movl 0x30(%rsp), %r10d
movl %r10d, 8(%rsp)
movl 0x38(%rsp), %r10d
movl %r10d, 0x10(%rsp)
movl 0x40(%rsp), %r10d
movl %r10d, 0x18(%rsp)
movl 0x48(%rsp), %r10d
movl %r10d, 0x20(%rsp)
movl 0x30(%rsp), %eax
movl %eax, 8(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x10(%rsp)
movl 0x40(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x20(%rsp)
movabsq $_IO_printf, %rax
callq *%rax
addq $0x28, %rsp

View File

@ -60,7 +60,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%rax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3)
TMP
[%eax]: [2.2-2.3)/1
[%rax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%esi), PHI_USE(12.2, phi=d_4/3)