-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[runtime] Remove TwoWordPair and use the Swift calling convention instead. #13299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@jrose-apple I went with this solution rather than what was suggested on swift-dev since the functions were already marked |
@@ -131,6 +131,8 @@ | |||
#define SWIFT_CC_DefaultCC_IMPL SWIFT_CC_c | |||
#define SWIFT_LLVM_CC_DefaultCC llvm::CallingConv::C | |||
|
|||
#define SWIFT_CC_SwiftCC SWIFT_CC_swift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Swift calling convention is called SWIFT_CC_swift
directly and SWIFT_LLVM_CC_SwiftCC
to refer to the LLVM name. These need to match (either swift
or SwiftCC
) for the purposes of the macros in RuntimeFunctions.def, so I chose to alias SwiftCC
to swift
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this is necessary. RuntimeFunctions.def already uses SwiftCC
for two functions. Why is this only now a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, both SwiftCC
functions in RuntimeFunctions.def used the FUNCTION
macro. However, swift_allocBox
uses FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL
.
In RuntimeEntrySymbols.cpp
, that FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL
expands into DEFINE_SYMBOL
, whereas FUNCTION
, as defined in that same file, expands to nothing for any calling convention other than RegisterPreservingCC
.
DEFINE_SYMBOL
uses the SWIFT_CC
macro, which expands to SWIFT_CC_##CC
. Since SWIFT_CC_SwiftCC was undefined, I defined it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. That's fine.
include/swift/Runtime/HeapObject.h
Outdated
#endif | ||
struct BoxPair { | ||
HeapObject *first; | ||
OpaqueValue *second; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure for the best name for these variables (they're never actually referred to by name), so I kept with the precedent from TwoWordPair
. object
and value
don't seem ideal as they remind me of e.g. a key-value pair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
object
and buffer
would be appropriate.
@@ -610,6 +610,10 @@ llvm::Constant *swift::getWrapperFn(llvm::Module &Module, | |||
RETURNS, ARGS, ATTRS) \ | |||
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS)) | |||
|
|||
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_SwiftCC(ID, NAME, SYMBOL, CC, \ | |||
RETURNS, ARGS, ATTRS) \ | |||
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it a problem to drop the SYMBOL part here? I thought that's what you were trying to fix on Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not actually unused. Like for the other calling conventions in this file, the SYMBOL
arg is dropped here but used in RuntimeEntrySymbols.cpp. I only had to add this macro here because SwiftCC wasn't previously being used on a global symbol.
This 'fix' for Windows is really a unification across all platforms by making sure the calling convention for these functions is guaranteed to be compatible with Swift.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, didn't think to check for that. Thanks for the explanation.
Forcing SwiftCC has a drawback: it means the function can't currently be imported into Swift using the usual import machinery. None of these functions are imported that way, though, and I don't think the risk of wanting to add a new one is too large. SwiftCC functions also are implied to use a different retain-count convention, but again I don't think that affects any of these functions. |
include/swift/Runtime/Config.h
Outdated
@@ -122,7 +122,7 @@ | |||
#define SWIFT_LLVM_CC(CC) SWIFT_LLVM_CC_##CC | |||
|
|||
// Currently, RuntimeFunction.def uses the following calling conventions: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're here, can you correct this misspelling? The file name is RuntimeFunctions.def
.
TwoWordPair() = default; | ||
TwoWordPair(A first, B second); | ||
|
||
// FIXME: rdar://16257592 arm codegen doesn't call swift_allocBox correctly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rdar://16257592 was closed long ago, so we're good here.
// in registers, so cram the result into an unsigned long long. | ||
// Use an enum class with implicit conversions so we don't dirty C callers | ||
// too much. | ||
#if __arm__ || __i386__ || defined(__CYGWIN__) || defined(_MSC_VER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One consideration is that this could cause any of these platforms that tries to build without SWIFT_USE_SWIFTCALL
(e.g. with an unsupported Clang) to silently break. Is there any reason that SWIFT_USE_SWIFTCALL
can't be required now, so not supporting it is an error? Otherwise it might be worth adding back an #if
block for only these platforms with an #error
that the Swift calling convention must be enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. If we start requiring SWIFT_USE_SWIFTCALL
then we ought to remove its other uses in Config.h
and add the #error
check there.
I see at least one reference to the C compiler being MSVC (swift/Basic/Compiler.h
). I assume it has no swiftcall support. Do we actually support MSVC? Is anyone using it?
Formally requiring recent clang would be worth a heads-up notice or a discussion on swift-evolution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I see that the default definition of SWIFT_USE_SWIFTCALL
in Config.h
still disables it. Are you building locally with it enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; I've submitted a PR for Clang that means we can enable it on Windows.
As for MSVC: I know @hughbe was doing a lot of work around getting the compiler building under MSVC. However, if I'm not mistaken, SWIFT_USE_SWIFTCALL
and its descendants are only used in the stdlib/runtime, which is normally built using the just-built Clang anyway. The requirement then is a little less strict: the stdlib/runtime must be built with a recent Clang - and I think that was already a requirement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that distinction will work. Probably looks something like this:
- Remove
SWIFT_USE_SWIFTCALL
from Config.h. (In the interim add some#if !SWIFT_USE_SWIFTCALL #error "SWIFT_USE_SWIFTCALL=0 is not supported"
to catch anyone switching it externally.) - Use
__has_attribute(swiftcall)
to define the macros formerly controlled bySWIFT_USE_SWIFTCALL
. Or possibly define them unconditionally, if they are never used in code that is included in the compiler's build. - Add
__has_attribute(swiftcall)
enforcement somewhere in runtime-only code. I don't know of any established place for such a thing.
I should note that apparently I missed the relevant tests before, and will need to update them to include the |
After updating the SIL tests to account for the added The change to always use SwiftCC is in #13311; this PR and that can be merged in any order and then I'll rebase the other. |
@swift-ci please test |
Build failed |
Build failed |
Oops, sorry, that build failure's my mistake; I forgot to cherry pick a commit across to this branch. |
@swift-ci please test |
Build failed |
Build failed |
Tests seem to have passed despite the "Build failed" messages. |
Right. It's a CI glitch. If you look at those failure messages they say that it's automatically retrying. |
clang is miscompiling some swiftcall functions on armv7s. Stop using swiftcall in some places until it is fixed. Reverts c5bf2ec (swiftlang#13299). rdar://35973477
Reverted in #14079. clang is miscompiling the swiftcall version of |
…g#14079) clang is miscompiling some swiftcall functions on armv7s. Stop using swiftcall in some places until it is fixed. Reverts c5bf2ec (swiftlang#13299). rdar://35973477
We should be ready to put this back now. Thomas, do you want to take it? |
Sure. I'll take a look at it in the next few days. |
Historically,
TwoWordPair
seems to be a >4 year old hack that worked around the lack of a dedicated calling convention to interoperate with Swift. On some platforms, it packed two word-sized values into a larger integer to ensure it would be passed in registers.However, this approach doesn't work on platforms such as 64-bit Windows, where a calling convention such as
__vectorcall
would need to be used instead (which would pollute the codebase quite significantly).Now that SwiftCC exists (and works on Windows, once apple/swift-clang#142 is merged) we don't need that hack anymore and can instead mark all functions that used
TwoWordPair::Return
as using the Swift calling convention.Note that I split up
TwoWordPair
into different struct types. Using the templatedTwoWordPair
gives compile-time warnings that the functions have C-linkage but use an incomplete type that's potentially incompatible with C.This has passed the long test suite locally, but I wouldn't be surprised if there's some subtle breakage somewhere I've missed. It does also require that every platform which previously needed a workaround supports SwiftCC, which I believe to be the case.
This fixes Swift functionality on 64-bit Windows; previously we would crash in an assertion on
ManagedBufferPointer
when trying to do anything more than aprint
statement sinceClassExtents
wasn't correctly being returned from_getSwiftClassInstanceExtents
.