TwoWordPair::Return and Calling Conventions on x64 Windows

I've been working on getting Swift running properly on 64-bit Windows and wanted to get some feedback/ideas on a specific issue.

In swift/Runtime/HeapObject.h, there is a TwoWordPair::Return type intended to return two word-sized values in registers. On Windows, structs are returned indirectly. For some platforms (ARM, i386, 32-bit Windows) this is worked around by packing the results into a 64-bit int.

We can apply a similar solution on Win64 by packing the results into an __m128 and adopting the __vectorcall calling convention to ensure that the value is passed in a register. However, adopting a new calling convention for methods that interact with TwoWordPair::Return has a fairly major fallout; I've started work in a branch (see the most recent three commits on https://github.com/troughton/swift/tree/x64-vectorcall), but it feels very messy. The main issue is that __vectorcall using a different mangling scheme, which means we need to special-case in quite a few different places.

Another alternative would be to adopt the Swift calling convention for swift_allocBox. If this doesn't cause other issues, it seems cleaner and would have a much smaller impact on the code-base. However, there's currently an issue blocking using the Swift calling convention on Windows; it gets sent to MicrosoftMangle in Clang, which doesn't know how to mangle the Swift calling convention (https://reviews.llvm.org/D31372). I'd like to resolve this, and it seems like there are two possible implementations:

Pick an arbitrary prefix to use for SwiftCC and then mangle the rest of the string following the Microsoft convention, knowing that tools won't know how to deal with it.
Alternatively, for functions that use SwiftCC, use the Itanium mangling. This would require a more major refactoring in Clang but might be easier to demangle.
What are people's thoughts on these two issues?

- Thomas

Since all of the functions that use TwoWordPair::Return are part of the Swift runtime and not intended to be overloaded, we could also just make them all `extern "C"`, or give them explicit mangled names, either everywhere or just on x64 Windows.

Jordan

···

On Dec 5, 2017, at 17:30, Thomas Roughton via swift-dev <swift-dev@swift.org> wrote:

I've been working on getting Swift running properly on 64-bit Windows and wanted to get some feedback/ideas on a specific issue.

In swift/Runtime/HeapObject.h, there is a TwoWordPair::Return type intended to return two word-sized values in registers. On Windows, structs are returned indirectly. For some platforms (ARM, i386, 32-bit Windows) this is worked around by packing the results into a 64-bit int.

We can apply a similar solution on Win64 by packing the results into an __m128 and adopting the __vectorcall calling convention to ensure that the value is passed in a register. However, adopting a new calling convention for methods that interact with TwoWordPair::Return has a fairly major fallout; I've started work in a branch (see the most recent three commits on https://github.com/troughton/swift/tree/x64-vectorcall), but it feels very messy. The main issue is that __vectorcall using a different mangling scheme, which means we need to special-case in quite a few different places.

Another alternative would be to adopt the Swift calling convention for swift_allocBox. If this doesn't cause other issues, it seems cleaner and would have a much smaller impact on the code-base. However, there's currently an issue blocking using the Swift calling convention on Windows; it gets sent to MicrosoftMangle in Clang, which doesn't know how to mangle the Swift calling convention (https://reviews.llvm.org/D31372). I'd like to resolve this, and it seems like there are two possible implementations:

Pick an arbitrary prefix to use for SwiftCC and then mangle the rest of the string following the Microsoft convention, knowing that tools won't know how to deal with it.
Alternatively, for functions that use SwiftCC, use the Itanium mangling. This would require a more major refactoring in Clang but might be easier to demangle.
What are people's thoughts on these two issues?

- Thomas
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

I think it wouldn't be the worst thing to just ignore SwiftCC when mangling for the MSVC ABI for now, at least when mangling a top-level function type.

John.

···

On Dec 5, 2017, at 8:30 PM, Thomas Roughton via swift-dev <swift-dev@swift.org> wrote:

I've been working on getting Swift running properly on 64-bit Windows and wanted to get some feedback/ideas on a specific issue.

In swift/Runtime/HeapObject.h, there is a TwoWordPair::Return type intended to return two word-sized values in registers. On Windows, structs are returned indirectly. For some platforms (ARM, i386, 32-bit Windows) this is worked around by packing the results into a 64-bit int.

We can apply a similar solution on Win64 by packing the results into an __m128 and adopting the __vectorcall calling convention to ensure that the value is passed in a register. However, adopting a new calling convention for methods that interact with TwoWordPair::Return has a fairly major fallout; I've started work in a branch (see the most recent three commits on https://github.com/troughton/swift/tree/x64-vectorcall), but it feels very messy. The main issue is that __vectorcall using a different mangling scheme, which means we need to special-case in quite a few different places.

Another alternative would be to adopt the Swift calling convention for swift_allocBox. If this doesn't cause other issues, it seems cleaner and would have a much smaller impact on the code-base. However, there's currently an issue blocking using the Swift calling convention on Windows; it gets sent to MicrosoftMangle in Clang, which doesn't know how to mangle the Swift calling convention (https://reviews.llvm.org/D31372). I'd like to resolve this, and it seems like there are two possible implementations:

Pick an arbitrary prefix to use for SwiftCC and then mangle the rest of the string following the Microsoft convention, knowing that tools won't know how to deal with it.
Alternatively, for functions that use SwiftCC, use the Itanium mangling. This would require a more major refactoring in Clang but might be easier to demangle.
What are people's thoughts on these two issues?