From 9eb366698da30f4e88e1ddc050dedbbd3b4aa95e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 26 Apr 2023 12:16:05 +0300 Subject: [PATCH] Avoid reservaton of temporary resiser for argument passing We may use any scratch register that is not used for parameters --- ir_aarch64.dasc | 42 ++-------------- ir_x86.dasc | 56 ++-------------------- tests/debug.Windows-x86_64/regset-fib.irt | 1 - tests/debug.Windows-x86_64/regset-fib2.irt | 2 - tests/debug.Windows-x86_64/regset-fibi.irt | 1 - tests/debug.aarch64/args_001.irt | 12 ++--- tests/debug.aarch64/call2.irt | 4 +- tests/debug.aarch64/call3.irt | 4 +- tests/debug.aarch64/params_003.irt | 8 ++-- tests/debug.aarch64/regset-fib.irt | 1 - tests/debug.aarch64/regset-fib2.irt | 2 - tests/debug.aarch64/regset-fibi.irt | 1 - tests/debug.x86/call3.irt | 12 ++--- tests/debug.x86/regset-fib.irt | 1 - tests/debug.x86/regset-fib2.irt | 2 - tests/debug.x86/regset-fibi.irt | 1 - tests/debug/params_003.irt | 16 +++---- tests/debug/regset-fib.irt | 1 - tests/debug/regset-fib2.irt | 2 - tests/debug/regset-fibi.irt | 1 - 20 files changed, 38 insertions(+), 132 deletions(-) diff --git a/ir_aarch64.dasc b/ir_aarch64.dasc index 7995f2b..402ac1c 100644 --- a/ir_aarch64.dasc +++ b/ir_aarch64.dasc @@ -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); diff --git a/ir_x86.dasc b/ir_x86.dasc index 3a770c0..a9886dd 100644 --- a/ir_x86.dasc +++ b/ir_x86.dasc @@ -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) { diff --git a/tests/debug.Windows-x86_64/regset-fib.irt b/tests/debug.Windows-x86_64/regset-fib.irt index 3078765..e9d2855 100755 --- a/tests/debug.Windows-x86_64/regset-fib.irt +++ b/tests/debug.Windows-x86_64/regset-fib.irt @@ -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] diff --git a/tests/debug.Windows-x86_64/regset-fib2.irt b/tests/debug.Windows-x86_64/regset-fib2.irt index 2daaa35..d86eb22 100755 --- a/tests/debug.Windows-x86_64/regset-fib2.irt +++ b/tests/debug.Windows-x86_64/regset-fib2.irt @@ -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] diff --git a/tests/debug.Windows-x86_64/regset-fibi.irt b/tests/debug.Windows-x86_64/regset-fibi.irt index d4dbf7f..188cc74 100755 --- a/tests/debug.Windows-x86_64/regset-fibi.irt +++ b/tests/debug.Windows-x86_64/regset-fibi.irt @@ -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) diff --git a/tests/debug.aarch64/args_001.irt b/tests/debug.aarch64/args_001.irt index d6f6222..81383a7 100644 --- a/tests/debug.aarch64/args_001.irt +++ b/tests/debug.aarch64/args_001.irt @@ -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 diff --git a/tests/debug.aarch64/call2.irt b/tests/debug.aarch64/call2.irt index 12500ed..48c2301 100644 --- a/tests/debug.aarch64/call2.irt +++ b/tests/debug.aarch64/call2.irt @@ -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 diff --git a/tests/debug.aarch64/call3.irt b/tests/debug.aarch64/call3.irt index 6923104..0e52d86 100644 --- a/tests/debug.aarch64/call3.irt +++ b/tests/debug.aarch64/call3.irt @@ -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 diff --git a/tests/debug.aarch64/params_003.irt b/tests/debug.aarch64/params_003.irt index 7971bd8..12b8902 100644 --- a/tests/debug.aarch64/params_003.irt +++ b/tests/debug.aarch64/params_003.irt @@ -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 diff --git a/tests/debug.aarch64/regset-fib.irt b/tests/debug.aarch64/regset-fib.irt index 42b1e27..2823cc7 100644 --- a/tests/debug.aarch64/regset-fib.irt +++ b/tests/debug.aarch64/regset-fib.irt @@ -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) diff --git a/tests/debug.aarch64/regset-fib2.irt b/tests/debug.aarch64/regset-fib2.irt index 1233b2d..6cb465a 100644 --- a/tests/debug.aarch64/regset-fib2.irt +++ b/tests/debug.aarch64/regset-fib2.irt @@ -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) diff --git a/tests/debug.aarch64/regset-fibi.irt b/tests/debug.aarch64/regset-fibi.irt index 67f4ab4..3917e45 100644 --- a/tests/debug.aarch64/regset-fibi.irt +++ b/tests/debug.aarch64/regset-fibi.irt @@ -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) diff --git a/tests/debug.x86/call3.irt b/tests/debug.x86/call3.irt index 106c76f..61efcf6 100644 --- a/tests/debug.x86/call3.irt +++ b/tests/debug.x86/call3.irt @@ -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 diff --git a/tests/debug.x86/regset-fib.irt b/tests/debug.x86/regset-fib.irt index 933323d..c5d13ab 100644 --- a/tests/debug.x86/regset-fib.irt +++ b/tests/debug.x86/regset-fib.irt @@ -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] diff --git a/tests/debug.x86/regset-fib2.irt b/tests/debug.x86/regset-fib2.irt index 10c4715..c579dc7 100644 --- a/tests/debug.x86/regset-fib2.irt +++ b/tests/debug.x86/regset-fib2.irt @@ -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] diff --git a/tests/debug.x86/regset-fibi.irt b/tests/debug.x86/regset-fibi.irt index 812fc3f..abb8d66 100644 --- a/tests/debug.x86/regset-fibi.irt +++ b/tests/debug.x86/regset-fibi.irt @@ -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) diff --git a/tests/debug/params_003.irt b/tests/debug/params_003.irt index 34ec74e..a343602 100644 --- a/tests/debug/params_003.irt +++ b/tests/debug/params_003.irt @@ -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 diff --git a/tests/debug/regset-fib.irt b/tests/debug/regset-fib.irt index e7f7ba7..b99b95f 100644 --- a/tests/debug/regset-fib.irt +++ b/tests/debug/regset-fib.irt @@ -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] diff --git a/tests/debug/regset-fib2.irt b/tests/debug/regset-fib2.irt index 0410536..07e09ba 100644 --- a/tests/debug/regset-fib2.irt +++ b/tests/debug/regset-fib2.irt @@ -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] diff --git a/tests/debug/regset-fibi.irt b/tests/debug/regset-fibi.irt index d82b499..3d3005d 100644 --- a/tests/debug/regset-fibi.irt +++ b/tests/debug/regset-fibi.irt @@ -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)