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:
@@ -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 (¶m, 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user