Skip to content

Commit 2573782

Browse files
committed
Merge pull request #1357 from swiftix/wip-runtime-calling-convention
Prepare the ground for using a new calling convention for functions from the runtime library
2 parents 906d6f1 + aa8350e commit 2573782

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1612
-702
lines changed

include/swift/Runtime/Config.h

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,127 @@
6262
// Bring in visibility attribute macros
6363
#include "../../../stdlib/public/SwiftShims/Visibility.h"
6464

65+
// Define mappings for calling conventions.
66+
67+
// Annotation for specifying a calling convention of
68+
// a runtime function. It should be used with declarations
69+
// of runtime functions like this:
70+
// void runtime_function_name() SWIFT_CC(RegisterPreservingCC)
71+
#define SWIFT_CC(CC) SWIFT_CC_##CC
72+
73+
#define SWIFT_CC_preserve_most __attribute__((preserve_most))
74+
#define SWIFT_CC_preserve_all __attribute__((preserve_all))
75+
#define SWIFT_CC_c
76+
77+
// Map a logical calling convention (e.g. RegisterPreservingCC) to LLVM calling
78+
// convention.
79+
#define SWIFT_LLVM_CC(CC) SWIFT_LLVM_CC_##CC
80+
81+
// Currently, RuntimeFunction.def uses the following calling conventions:
82+
// DefaultCC, RegisterPreservingCC.
83+
// If new runtime calling conventions are added later, they need to be mapped
84+
// here to something appropriate.
85+
86+
// DefaultCC is usually the standard C calling convention.
87+
#define SWIFT_CC_DefaultCC SWIFT_CC_c
88+
#define SWIFT_CC_DefaultCC_IMPL SWIFT_CC_c
89+
#define SWIFT_LLVM_CC_DefaultCC llvm::CallingConv::C
90+
91+
// If defined, it indicates that runtime function wrappers
92+
// should be used on all platforms, even they do not support
93+
// the new calling convention which requires this.
94+
#define SWIFT_RT_USE_WRAPPERS_ALWAYS 1
95+
96+
// If defined, it indicates that this calling convention is
97+
// supported by the currnet target.
98+
// TODO: Define it once the runtime calling convention support has
99+
// been integrated into clang and llvm.
100+
//#define RT_USE_RegisterPreservingCC
101+
102+
// RegisterPreservingCC is a dedicated runtime calling convention to be used
103+
// when calling the most popular runtime functions.
104+
#if defined(RT_USE_RegisterPreservingCC) && __has_attribute(preserve_most) && \
105+
(defined(__aarch64__) || defined(__x86_64__))
106+
107+
// Targets supporting the dedicated runtime convention should use it.
108+
// If a runtime function is using this calling convention, it can
109+
// be invoked only by means of a wrapper, which performs an indirect
110+
// call. Wrappers are generated by the IRGen and added to object files.
111+
// As a result, runtime functions are invoked only indirectly from
112+
// the user code.
113+
// This is a workaround for dynamic linking issues, where a dynamic
114+
// linker may clobber some of the callee-saved registers defined by
115+
// this new calling convention when it performs lazy binding of
116+
// runtime functions using this new calling convention.
117+
#define SWIFT_CC_RegisterPreservingCC \
118+
SWIFT_CC_preserve_most
119+
#define SWIFT_CC_RegisterPreservingCC_IMPL \
120+
SWIFT_CC_preserve_most
121+
#define SWIFT_LLVM_CC_RegisterPreservingCC llvm::CallingConv::PreserveMost
122+
123+
// Indicate that wrappers should be used, because it is required
124+
// for the calling convention to get around dynamic linking issues.
125+
#define SWIFT_RT_USE_WRAPPERS 1
126+
127+
#else
128+
129+
// Targets not supporting the dedicated runtime calling convention
130+
// should use the standard calling convention instead.
131+
// No wrappers are required in this case by the calling convention.
132+
#define SWIFT_CC_RegisterPreservingCC SWIFT_CC_c
133+
#define SWIFT_CC_RegisterPreservingCC_IMPL SWIFT_CC_c
134+
#define SWIFT_LLVM_CC_RegisterPreservingCC llvm::CallingConv::C
135+
136+
#endif
137+
138+
// Bring in visibility attribute macros for library visibility.
139+
#include "llvm/Support/Compiler.h"
140+
141+
// Generates a name of the runtime enrty's implementation by
142+
// adding an underscore as a prefix and a suffix.
143+
#define SWIFT_RT_ENTRY_IMPL(Name) _##Name##_
144+
145+
// Library internal way to invoke the implementation of a runtime entry.
146+
// E.g. a runtime function may be called internally via its public API
147+
// or via the function pointer.
148+
#define SWIFT_RT_ENTRY_CALL(Name) Name
149+
150+
// Name of the symbol holding a reference to the
151+
// implementation of a runtime entry.
152+
#define SWIFT_RT_ENTRY_REF(Name) _##Name
153+
154+
// String representation of the symbol's name.
155+
#define SWIFT_RT_ENTRY_REF_AS_STR(Name) "_" #Name
156+
157+
#if defined(SWIFT_RT_USE_WRAPPERS_ALWAYS)
158+
#define SWIFT_RT_USE_WRAPPERS
159+
#endif
160+
161+
#if defined(SWIFT_RT_USE_WRAPPERS)
162+
163+
// Both the runtime functions and their implementation are hidden and
164+
// can be directly referenced only inside the runtime library.
165+
// User code can access these runtime entries only indirectly
166+
// via a global function pointer.
167+
// NOTE: In principle, entries may have LLVM_LIBRARY_VISIBILITY,
168+
// because they are never called directly from the code
169+
// produced by IRGen.
170+
// But some of the runtime entries are invoked directly from
171+
// the foundation. Therefore they should be visible.
172+
#define SWIFT_RT_ENTRY_VISIBILITY SWIFT_RUNTIME_EXPORT
173+
#define SWIFT_RT_ENTRY_IMPL_VISIBILITY LLVM_LIBRARY_VISIBILITY
174+
175+
// Prefix of wrappers generated for runtime functions.
176+
#define SWIFT_WRAPPER_PREFIX "rt_"
177+
178+
#else
179+
180+
// Runtime functions are exported, because it should be possible
181+
// to invoke them directly from the user code. But internal
182+
// implementations of runtime functions do not need to be exported.
183+
#define SWIFT_RT_ENTRY_VISIBILITY SWIFT_RUNTIME_EXPORT
184+
#define SWIFT_RT_ENTRY_IMPL_VISIBILITY LLVM_LIBRARY_VISIBILITY
185+
186+
#endif
187+
65188
#endif // SWIFT_RUNTIME_CONFIG_H

include/swift/Runtime/Enum.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ extern "C" void swift_initEnumValueWitnessTableSinglePayload(
5050
/// \returns -1 if the payload case is inhabited. If an empty case is inhabited,
5151
/// returns a value greater than or equal to zero and less than
5252
/// emptyCases.
53-
SWIFT_RUNTIME_EXPORT
53+
SWIFT_RT_ENTRY_VISIBILITY
5454
extern "C" int swift_getEnumCaseSinglePayload(const OpaqueValue *value,
5555
const Metadata *payload,
56-
unsigned emptyCases);
56+
unsigned emptyCases)
57+
SWIFT_CC(RegisterPreservingCC);
58+
59+
5760

5861
/// \brief Store the tag value for the given case into a single-payload enum,
5962
/// whose associated payload (if any) has already been initialized.
@@ -66,11 +69,12 @@ extern "C" int swift_getEnumCaseSinglePayload(const OpaqueValue *value,
6669
/// case, or a value greater than or equal to zero and less
6770
/// than emptyCases for an empty case.
6871
/// \param emptyCases - the number of empty cases in the enum.
69-
SWIFT_RUNTIME_EXPORT
72+
SWIFT_RT_ENTRY_VISIBILITY
7073
extern "C" void swift_storeEnumTagSinglePayload(OpaqueValue *value,
7174
const Metadata *payload,
7275
int whichCase,
73-
unsigned emptyCases);
76+
unsigned emptyCases)
77+
SWIFT_CC(RegisterPreservingCC);
7478

7579
/// \brief Initialize the value witness table for a generic, multi-payload
7680
/// enum instance.

0 commit comments

Comments
 (0)