Skip to content

Commit b0d3173

Browse files
Merge pull request swiftlang#35303 from aschwaighofer/introduce_swiftasync_lowering
Add llvm::Attribute::SwiftAsync to the context parameter
2 parents f55f290 + 12e6ec1 commit b0d3173

File tree

62 files changed

+176
-127
lines changed

Some content is hidden

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

62 files changed

+176
-127
lines changed

include/swift/ABI/Executor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ using JobInvokeFunction =
118118

119119
using TaskContinuationFunction =
120120
SWIFT_CC(swiftasync)
121-
void (AsyncTask *, ExecutorRef, AsyncContext *);
121+
void (AsyncTask *, ExecutorRef, SWIFT_ASYNC_CONTEXT AsyncContext *);
122122

123123
template <class AsyncSignature>
124124
class AsyncFunctionPointer;

include/swift/ABI/MetadataValues.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,9 @@ namespace SpecialPointerAuthDiscriminators {
11721172
const uint16_t AsyncContextYield = 0xe207; // = 57863
11731173
const uint16_t CancellationNotificationFunction = 0x1933; // = 6451
11741174
const uint16_t EscalationNotificationFunction = 0x5be4; // = 23524
1175+
1176+
/// Swift async context parameter stored in the extended frame info.
1177+
const uint16_t SwiftAsyncContextExtendedFrameEntry = 0xc31a;
11751178
}
11761179

11771180
/// The number of arguments that will be passed directly to a generic

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
146146

147147
/// The resume function stored in AsyncTask.
148148
PointerAuthSchema TaskResumeFunction;
149+
150+
/// The swift async context entry in the extended frame info.
151+
PointerAuthSchema AsyncContextExtendedFrameEntry;
149152
};
150153

151154
enum class JITDebugArtifact : unsigned {

include/swift/Runtime/Config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
176176
#define SWIFT_INDIRECT_RESULT
177177
#endif
178178

179+
#if __has_attribute(swift_async_context)
180+
#define SWIFT_ASYNC_CONTEXT __attribute__((swift_async_context))
181+
#else
182+
#define SWIFT_ASYNC_CONTEXT
183+
#endif
184+
179185
// SWIFT_CC(swiftasync) is the Swift async calling convention.
180186
// We assume that it supports mandatory tail call elimination.
181187
#if __has_attribute(swiftasynccall)

lib/IRGen/GenCall.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,8 @@ void SignatureExpansion::addAsyncParameters() {
817817
// void (AsyncTask *, ExecutorRef, AsyncContext *);
818818
ParamIRTypes.push_back(IGM.SwiftTaskPtrTy);
819819
ParamIRTypes.push_back(IGM.SwiftExecutorPtrTy);
820+
Attrs = Attrs.addParamAttribute(IGM.getLLVMContext(), getCurParamIndex(),
821+
llvm::Attribute::SwiftAsync);
820822
ParamIRTypes.push_back(IGM.SwiftContextPtrTy);
821823
}
822824

lib/IRGen/GenFunc.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,7 @@ void irgen::emitBlockHeader(IRGenFunction &IGF,
23852385

23862386
llvm::Function *IRGenFunction::getOrCreateResumePrjFn() {
23872387
auto name = "__swift_async_resume_project_context";
2388-
return cast<llvm::Function>(IGM.getOrCreateHelperFunction(
2388+
auto Fn = cast<llvm::Function>(IGM.getOrCreateHelperFunction(
23892389
name, IGM.Int8PtrTy, {IGM.Int8PtrTy},
23902390
[&](IRGenFunction &IGF) {
23912391
auto it = IGF.CurFn->arg_begin();
@@ -2398,9 +2398,29 @@ llvm::Function *IRGenFunction::getOrCreateResumePrjFn() {
23982398
PointerAuthInfo::emit(IGF, schema, addr, PointerAuthEntity());
23992399
callerContext = emitPointerAuthAuth(IGF, callerContext, authInfo);
24002400
}
2401+
// TODO: remove this once all platforms support lowering the intrinsic.
2402+
// At the time of this writing only arm64 supports it.
2403+
if (IGM.TargetInfo.canUseSwiftAsyncContextAddrIntrinsic()) {
2404+
auto contextLocationInExtendedFrame =
2405+
Address(Builder.CreateIntrinsicCall(
2406+
llvm::Intrinsic::swift_async_context_addr, {}),
2407+
IGM.getPointerAlignment());
2408+
// On arm64e we need to sign this pointer address discriminated
2409+
// with 0xc31a and process dependent key.
2410+
if (auto schema = IGF.IGM.getOptions()
2411+
.PointerAuth.AsyncContextExtendedFrameEntry) {
2412+
auto authInfo = PointerAuthInfo::emit(
2413+
IGF, schema, contextLocationInExtendedFrame.getAddress(),
2414+
PointerAuthEntity());
2415+
callerContext = emitPointerAuthSign(IGF, callerContext, authInfo);
2416+
}
2417+
Builder.CreateStore(callerContext, contextLocationInExtendedFrame);
2418+
}
24012419
Builder.CreateRet(callerContext);
24022420
},
24032421
false /*isNoInline*/));
2422+
Fn->addFnAttr(llvm::Attribute::AlwaysInline);
2423+
return Fn;
24042424
}
24052425
llvm::Function *
24062426
IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr,

lib/IRGen/IRGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,10 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
702702
opts.TaskResumeFunction =
703703
PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Constant,
704704
SpecialPointerAuthDiscriminators::TaskResumeFunction);
705+
706+
opts.AsyncContextExtendedFrameEntry = PointerAuthSchema(
707+
dataKey, /*address*/ true, Discrimination::Constant,
708+
SpecialPointerAuthDiscriminators::SwiftAsyncContextExtendedFrameEntry);
705709
}
706710

707711
std::unique_ptr<llvm::TargetMachine>

lib/IRGen/SwiftTargetInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ static void configureARM64(IRGenModule &IGM, const llvm::Triple &triple,
6060
// arm64 tops out at 56 effective bits of address space and reserves the high
6161
// half for the kernel.
6262
target.SwiftRetainIgnoresNegativeValues = true;
63+
64+
target.UsableSwiftAsyncContextAddrIntrinsic = true;
6365
}
6466

6567
/// Configures target-specific information for x86-64 platforms.

lib/IRGen/SwiftTargetInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ class SwiftTargetInfo {
5151
return ObjCHasOpaqueISAs;
5252
}
5353

54+
bool canUseSwiftAsyncContextAddrIntrinsic() const {
55+
return UsableSwiftAsyncContextAddrIntrinsic;
56+
}
57+
5458
/// The target's object format type.
5559
llvm::Triple::ObjectFormatType OutputObjectFormat;
5660

@@ -104,6 +108,8 @@ class SwiftTargetInfo {
104108
/// True if `swift_retain` and `swift_release` are no-ops when passed
105109
/// "negative" pointer values.
106110
bool SwiftRetainIgnoresNegativeValues = false;
111+
112+
bool UsableSwiftAsyncContextAddrIntrinsic = false;
107113
};
108114

109115
}

stdlib/public/Concurrency/Task.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ static FullMetadata<HeapMetadata> taskHeapMetadata = {
172172
/// to handle the final return.
173173
SWIFT_CC(swift)
174174
static void completeTask(AsyncTask *task, ExecutorRef executor,
175-
AsyncContext *context) {
175+
SWIFT_ASYNC_CONTEXT AsyncContext *context) {
176176
// Tear down the task-local allocator immediately;
177177
// there's no need to wait for the object to be destroyed.
178178
_swift_task_alloc_destroy(task);
@@ -305,7 +305,7 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
305305

306306
void swift::swift_task_future_wait(
307307
AsyncTask *waitingTask, ExecutorRef executor,
308-
AsyncContext *rawContext) {
308+
SWIFT_ASYNC_CONTEXT AsyncContext *rawContext) {
309309
// Suspend the waiting task.
310310
waitingTask->ResumeTask = rawContext->ResumeParent;
311311
waitingTask->ResumeContext = rawContext;
@@ -402,7 +402,7 @@ using RunAndBlockCalleeContext =
402402
/// Second half of the runAndBlock async function.
403403
SWIFT_CC(swiftasync)
404404
static void runAndBlock_finish(AsyncTask *task, ExecutorRef executor,
405-
AsyncContext *_context) {
405+
SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
406406
auto calleeContext = static_cast<RunAndBlockCalleeContext*>(_context);
407407
auto context = popAsyncContext(task, calleeContext);
408408

@@ -414,7 +414,7 @@ static void runAndBlock_finish(AsyncTask *task, ExecutorRef executor,
414414
/// First half of the runAndBlock async function.
415415
SWIFT_CC(swiftasync)
416416
static void runAndBlock_start(AsyncTask *task, ExecutorRef executor,
417-
AsyncContext *_context) {
417+
SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
418418
auto callerContext = static_cast<RunAndBlockContext*>(_context);
419419

420420
size_t calleeContextSize;

0 commit comments

Comments
 (0)