I found that passing [Mutable][Raw]Span as inout produces more instructions in caller function (initialization of span) and additional instruction in callee side for getting pointer ( If I understand it correctly). Is this a missed optimization?
Example with MutableSpan
@inline(never)
func borrowingCaller() -> Int {
var arr: [3 of Int] = [1,2,3]
var span = arr.mutableSpan
return borrowingCallee(span)
}
@inline(never)
func borrowingCallee(_ span: borrowing MutableSpan<Int>) -> Int {
return span[1]
}
@inline(never)
func inoutCaller() -> Int {
var arr: [3 of Int] = [1,2,3]
var span = arr.mutableSpan
return inoutCallee(&span)
}
@inline(never)
func inoutCallee(_ span: inout MutableSpan<Int>) -> Int {
return span[1]
}
Swift 6.2 -Ounchecked -disable-stack-protector
output.borrowingCaller() -> Swift.Int:
sub rsp, 24
mov qword ptr [rsp], 1
mov qword ptr [rsp + 8], 2
mov qword ptr [rsp + 16], 3
mov rdi, rsp
call (output.borrowingCallee(Swift.MutableSpan<Swift.Int>) -> Swift.Int)
add rsp, 24
ret
output.borrowingCallee(Swift.MutableSpan<Swift.Int>) -> Swift.Int:
mov rax, qword ptr [rdi + 8]
ret
output.inoutCaller() -> Swift.Int:
sub rsp, 40
mov qword ptr [rsp + 16], 1
mov qword ptr [rsp + 24], 2
mov qword ptr [rsp + 32], 3
lea rax, [rsp + 16]
mov qword ptr [rsp], rax
mov qword ptr [rsp + 8], 3
mov rdi, rsp
call (output.inoutCallee(inout Swift.MutableSpan<Swift.Int>) -> Swift.Int)
add rsp, 40
ret
output.inoutCallee(inout Swift.MutableSpan<Swift.Int>) -> Swift.Int:
mov rax, qword ptr [rdi]
mov rax, qword ptr [rax + 8]
ret