Skip to content

Commit

Permalink
Revise description of return type handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored Jan 19, 2024
1 parent bc35ee7 commit 922900c
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion proposed/swift-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ When calling a function that returns an opaque struct, the Swift ABI always requ

At the lowest level of the calling convention, we do not consider Library Evolution to be a different calling convention than the Swift calling convention. Library Evolution requires that some types are passed by a pointer/reference, but it does not fundamentally change the calling convention. Effectively, Library Evolution forces the least optimizable choice to be taken at every possible point. As a result, we should not handle Library Evolution as a separate calling convention and instead we can manually handle it at the projection layer.

For frozen structs and enums, Swift has a complicated lowering process where the struct or enum type's layout are recursively flattened to a sequence of primitives. If this sequence is length 4 or less, the values of this type are split into the elements of this sequence for parameter passing instead of passing the struct as a whole. Structs and enums that cannot be broken down in this way are passed by-reference to their specified frozen layout. Due to high implementation cost in the RyuJIT, in particular in the `UnmanagedCallersOnly` scenario, we should implement this first pass of lowering in the projection layer; the only types allowed for `CallConvSwift` calling convention in method or function pointer signatures are primitives, our special Swift register types, and pointer types. We will allow struct types as the return type in a signature to support scenarios where a return value is passed in multiple registers instead of passed indirectly; this occurs in some scenarios such as some larger-than-register SIMD types. For reference, this lowering pass is done in the Swift compiler when lowering from Swift IL to LLVM IR. This design decision reinforces our direction of having the Runtime layer of Swift interop support similar features as the LLVM IR representation of Swift.
For frozen structs and enums, Swift has a complicated lowering process where the struct or enum type's layout are recursively flattened to a sequence of primitives. If this sequence is length 4 or less, the values of this type are split into the elements of this sequence for parameter passing instead of passing the struct as a whole. Structs and enums that cannot be broken down in this way are passed by-reference to their specified frozen layout. When a frozen struct or enum with a valid primitive sequence of 4 elements or less is returned from a function, it is returned if it were a structure of the elements of the primitive sequence. Due to high implementation cost in the RyuJIT, in particular in the `UnmanagedCallersOnly` scenario, we should implement this first pass of lowering in the projection layer. The only types allowed for `CallConvSwift` calling convention in method or function pointer parameters are primitives, our special Swift register types, and pointer types. In return types, we will also allow structure types to support returning the primitive type sequences correctly. For reference, this lowering pass is done in the Swift compiler when lowering from Swift IL to LLVM IR. This design decision reinforces our direction of having the Runtime layer of Swift interop support similar features as the LLVM IR representation of Swift.

##### SIMD Types

Expand Down

0 comments on commit 922900c

Please sign in to comment.