-
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
Changes from all commits
0a123c7
14e4930
7c7ac6a
18b8588
ca38f02
215592c
01ef8b2
d33a0cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,66 +97,10 @@ HeapObject *swift_initStaticObject(HeapMetadata const *metadata, | |
SWIFT_RUNTIME_EXPORT | ||
void swift_verifyEndOfLifetime(HeapObject *object); | ||
|
||
/// A structure that's two pointers in size. | ||
/// | ||
/// C functions can use the TwoWordPair::Return type to return a value in | ||
/// two registers, compatible with Swift's calling convention for tuples | ||
/// and structs of two word-sized elements. | ||
template<typename A, typename B> | ||
struct TwoWordPair { | ||
A first; | ||
B second; | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more. rdar://16257592 was closed long ago, so we're good here. |
||
// Structs are returned indirectly on these platforms, but we want to return | ||
// 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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. If we start requiring I see at least one reference to the C compiler being MSVC ( 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 commentThe reason will be displayed to describe this comment to others. Learn more. Also, I see that the default definition of There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that distinction will work. Probably looks something like this:
|
||
#if defined(__CYGWIN__) | ||
enum class Return : unsigned __int128 {}; | ||
#else | ||
enum class Return : unsigned long long {}; | ||
#endif | ||
|
||
operator Return() const { | ||
union { | ||
TwoWordPair value; | ||
Return mangled; | ||
} reinterpret = {*this}; | ||
|
||
return reinterpret.mangled; | ||
} | ||
|
||
/*implicit*/ TwoWordPair(Return r) { | ||
union { | ||
Return mangled; | ||
TwoWordPair value; | ||
} reinterpret = {r}; | ||
|
||
*this = reinterpret.value; | ||
} | ||
#else | ||
using Return = TwoWordPair; | ||
#endif | ||
struct BoxPair { | ||
HeapObject *object; | ||
OpaqueValue *buffer; | ||
}; | ||
|
||
template<typename A, typename B> | ||
inline TwoWordPair<A,B>::TwoWordPair(A first, B second) | ||
: first(first), second(second) | ||
{ | ||
static_assert(sizeof(A) == sizeof(void*), | ||
"first type must be word-sized"); | ||
static_assert(sizeof(B) == sizeof(void*), | ||
"second type must be word-sized"); | ||
static_assert(alignof(TwoWordPair) == alignof(void*), | ||
"pair must be word-aligned"); | ||
} | ||
|
||
using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>; | ||
|
||
/// Allocates a heap object that can contain a value of the given type. | ||
/// Returns a Box structure containing a HeapObject* pointer to the | ||
|
@@ -165,19 +109,19 @@ using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>; | |
/// appropriate to store a value of the given type. | ||
/// The heap object has an initial retain count of 1, and its metadata is set | ||
/// such that destroying the heap object destroys the contained value. | ||
SWIFT_RUNTIME_EXPORT | ||
BoxPair::Return swift_allocBox(Metadata const *type); | ||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT | ||
BoxPair swift_allocBox(Metadata const *type); | ||
|
||
SWIFT_RUNTIME_EXPORT | ||
BoxPair::Return (*_swift_allocBox)(Metadata const *type); | ||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT | ||
BoxPair (*_swift_allocBox)(Metadata const *type); | ||
|
||
/// Performs a uniqueness check on the pointer to a box structure. If the check | ||
/// fails allocates a new box and stores the pointer in the buffer. | ||
/// | ||
/// if (!isUnique(buffer[0])) | ||
/// buffer[0] = swift_allocBox(type) | ||
SWIFT_RUNTIME_EXPORT | ||
BoxPair::Return swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type, | ||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT | ||
BoxPair swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type, | ||
size_t alignMask); | ||
|
||
/// Returns the address of a heap object representing all empty box types. | ||
|
@@ -1242,11 +1186,16 @@ static inline bool swift_unknownUnownedIsEqual(UnownedReference *ref, | |
|
||
#endif /* SWIFT_OBJC_INTEROP */ | ||
|
||
struct TypeNamePair { | ||
const char *data; | ||
uintptr_t length; | ||
}; | ||
|
||
/// Return the name of a Swift type represented by a metadata object. | ||
/// func _getTypeName(_ type: Any.Type, qualified: Bool) | ||
/// -> (UnsafePointer<UInt8>, Int) | ||
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API | ||
TwoWordPair<const char *, uintptr_t>::Return | ||
TypeNamePair | ||
swift_getTypeName(const Metadata *type, bool qualified); | ||
|
||
} // end namespace swift | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe 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 commentThe 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 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 commentThe reason will be displayed to describe this comment to others. Learn more. Oops, didn't think to check for that. Thanks for the explanation. |
||
|
||
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_RegisterPreservingCC( \ | ||
ID, NAME, SYMBOL, CC, RETURNS, ARGS, ATTRS) \ | ||
FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SYMBOL, CC, QUOTE(RETURNS), \ | ||
|
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 andSWIFT_LLVM_CC_SwiftCC
to refer to the LLVM name. These need to match (eitherswift
orSwiftCC
) for the purposes of the macros in RuntimeFunctions.def, so I chose to aliasSwiftCC
toswift
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 theFUNCTION
macro. However,swift_allocBox
usesFUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL
.In
RuntimeEntrySymbols.cpp
, thatFUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL
expands intoDEFINE_SYMBOL
, whereasFUNCTION
, as defined in that same file, expands to nothing for any calling convention other thanRegisterPreservingCC
.DEFINE_SYMBOL
uses theSWIFT_CC
macro, which expands toSWIFT_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.