Avoid introducing a move for struct return (#6245)

* Move sret_reg handling to Lower:new, from gen_arg_setup

* Update exp files

* Review feedback

* Review feedback
This commit is contained in:
Trevor Elliott
2023-04-20 11:13:40 -07:00
committed by GitHub
parent 620ec03ca4
commit b667f5fa5b
3 changed files with 47 additions and 48 deletions

View File

@@ -377,12 +377,27 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
} }
} }
// Make a sret register, if one is needed. // Find the sret register, if it's used.
let mut sret_reg = None; let mut sret_reg = None;
for ret in &vcode.abi().signature().returns.clone() { for ret in vcode.abi().signature().returns.iter() {
if ret.purpose == ArgumentPurpose::StructReturn { if ret.purpose == ArgumentPurpose::StructReturn {
assert!(sret_reg.is_none()); let entry_bb = f.stencil.layout.entry_block().unwrap();
sret_reg = Some(vregs.alloc(ret.value_type)?); for (&param, sig_param) in f
.dfg
.block_params(entry_bb)
.iter()
.zip(vcode.abi().signature().params.iter())
{
if sig_param.purpose == ArgumentPurpose::StructReturn {
let regs = value_regs[param];
assert!(regs.len() == 1);
assert!(sret_reg.is_none());
sret_reg = Some(regs);
}
}
assert!(sret_reg.is_some());
} }
} }
@@ -576,24 +591,6 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
{ {
self.emit(insn); self.emit(insn);
} }
if self.abi().signature().params[i].purpose == ArgumentPurpose::StructReturn {
assert!(regs.len() == 1);
let ty = self.abi().signature().params[i].value_type;
// The ABI implementation must have ensured that a StructReturn
// arg is present in the return values.
assert!(self
.abi()
.signature()
.returns
.iter()
.position(|ret| ret.purpose == ArgumentPurpose::StructReturn)
.is_some());
self.emit(I::gen_move(
Writable::from_reg(self.sret_reg.unwrap().regs()[0]),
regs.regs()[0].to_reg(),
ty,
));
}
} }
if let Some(insn) = self if let Some(insn) = self
.vcode .vcode

View File

@@ -850,16 +850,14 @@ block0(v0: i64):
; VCode: ; VCode:
; block0: ; block0:
; mov x5, x8 ; movz x2, #42
; movz x4, #42 ; str x2, [x8]
; str x4, [x8]
; ret ; ret
; ;
; Disassembled: ; Disassembled:
; block0: ; offset 0x0 ; block0: ; offset 0x0
; mov x5, x8 ; mov x2, #0x2a
; mov x4, #0x2a ; str x2, [x8]
; str x4, [x8]
; ret ; ret
function %f18(i64) -> i64 { function %f18(i64) -> i64 {
@@ -905,13 +903,14 @@ block0(v0: i64):
; VCode: ; VCode:
; stp fp, lr, [sp, #-16]! ; stp fp, lr, [sp, #-16]!
; mov fp, sp ; mov fp, sp
; str x24, [sp, #-16]! ; str x23, [sp, #-16]!
; block0: ; block0:
; mov x24, x8 ; mov x23, x8
; load_ext_name x4, TestCase(%g)+0 ; load_ext_name x2, TestCase(%g)+0
; blr x4 ; mov x8, x23
; mov x8, x24 ; blr x2
; ldr x24, [sp], #16 ; mov x8, x23
; ldr x23, [sp], #16
; ldp fp, lr, [sp], #16 ; ldp fp, lr, [sp], #16
; ret ; ret
; ;
@@ -919,16 +918,17 @@ block0(v0: i64):
; block0: ; offset 0x0 ; block0: ; offset 0x0
; stp x29, x30, [sp, #-0x10]! ; stp x29, x30, [sp, #-0x10]!
; mov x29, sp ; mov x29, sp
; str x24, [sp, #-0x10]! ; str x23, [sp, #-0x10]!
; block1: ; offset 0xc ; block1: ; offset 0xc
; mov x24, x8 ; mov x23, x8
; ldr x4, #0x18 ; ldr x2, #0x18
; b #0x20 ; b #0x20
; .byte 0x00, 0x00, 0x00, 0x00 ; reloc_external Abs8 %g 0 ; .byte 0x00, 0x00, 0x00, 0x00 ; reloc_external Abs8 %g 0
; .byte 0x00, 0x00, 0x00, 0x00 ; .byte 0x00, 0x00, 0x00, 0x00
; blr x4 ; mov x8, x23
; mov x8, x24 ; blr x2
; ldr x24, [sp], #0x10 ; mov x8, x23
; ldr x23, [sp], #0x10
; ldp x29, x30, [sp], #0x10 ; ldp x29, x30, [sp], #0x10
; ret ; ret

View File

@@ -12,9 +12,9 @@ block0(v0: i64):
; pushq %rbp ; pushq %rbp
; movq %rsp, %rbp ; movq %rsp, %rbp
; block0: ; block0:
; movl $42, %eax
; movq %rax, 0(%rdi)
; movq %rdi, %rax ; movq %rdi, %rax
; movl $42, %edx
; movq %rdx, 0(%rdi)
; movq %rbp, %rsp ; movq %rbp, %rsp
; popq %rbp ; popq %rbp
; ret ; ret
@@ -24,9 +24,9 @@ block0(v0: i64):
; pushq %rbp ; pushq %rbp
; movq %rsp, %rbp ; movq %rsp, %rbp
; block1: ; offset 0x4 ; block1: ; offset 0x4
; movl $0x2a, %eax
; movq %rax, (%rdi) ; trap: heap_oob
; movq %rdi, %rax ; movq %rdi, %rax
; movl $0x2a, %edx
; movq %rdx, (%rdi) ; trap: heap_oob
; movq %rbp, %rsp ; movq %rbp, %rsp
; popq %rbp ; popq %rbp
; retq ; retq
@@ -79,8 +79,9 @@ block0(v0: i64):
; movq %r15, 0(%rsp) ; movq %r15, 0(%rsp)
; block0: ; block0:
; movq %rdi, %r15 ; movq %rdi, %r15
; load_ext_name %f4+0, %rdx ; load_ext_name %f4+0, %rax
; call *%rdx ; movq %r15, %rdi
; call *%rax
; movq %r15, %rax ; movq %r15, %rax
; movq 0(%rsp), %r15 ; movq 0(%rsp), %r15
; addq %rsp, $16, %rsp ; addq %rsp, $16, %rsp
@@ -96,8 +97,9 @@ block0(v0: i64):
; movq %r15, (%rsp) ; movq %r15, (%rsp)
; block1: ; offset 0xc ; block1: ; offset 0xc
; movq %rdi, %r15 ; movq %rdi, %r15
; movabsq $0, %rdx ; reloc_external Abs8 %f4 0 ; movabsq $0, %rax ; reloc_external Abs8 %f4 0
; callq *%rdx ; movq %r15, %rdi
; callq *%rax
; movq %r15, %rax ; movq %r15, %rax
; movq (%rsp), %r15 ; movq (%rsp), %r15
; addq $0x10, %rsp ; addq $0x10, %rsp