Skip to content

Commit 97b0e2e

Browse files
committed
[concurrency] Create builtins for invoking specific concurrency runtime functions.
Specifically: 1. swift_task_addCancellationHandler 2. swift_task_removeCancellationHandler 3. swift_task_addPriorityEscalationHandler 4. swift_task_removePriorityEscalationHandler 5. swift_task_localValuePush 6. swift_task_localValuePop rdar://109850951
1 parent 1711ef2 commit 97b0e2e

File tree

13 files changed

+450
-0
lines changed

13 files changed

+450
-0
lines changed

include/swift/AST/Builtins.def

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,42 @@ BUILTIN_TYPE_CHECKER_OPERATION(TriggerFallbackDiagnostic, trigger_fallback_diagn
11741174
/// Maybe.
11751175
BUILTIN_TYPE_TRAIT_OPERATION(CanBeObjCClass, canBeClass)
11761176

1177+
/// Equivalent to calling swift_task_addCancellationHandler.
1178+
///
1179+
/// Signature: (handler: () -> Void) -> UnsafeRawPointer
1180+
BUILTIN_MISC_OPERATION_WITH_SILGEN(TaskAddCancellationHandler,
1181+
"taskAddCancellationHandler", "",
1182+
Special)
1183+
1184+
/// Equivalent to calling swift_task_removeCancellationHandler.
1185+
///
1186+
/// Signature: (record: UnsafeRawPointer) -> ()
1187+
BUILTIN_MISC_OPERATION(TaskRemoveCancellationHandler,
1188+
"taskRemoveCancellationHandler", "", Special)
1189+
1190+
/// Equivalent to calling swift_task_addPriorityEscalationHandler.
1191+
///
1192+
/// Signature: (handler: (UInt8, UInt8) -> Void) -> UnsafeRawPointer
1193+
BUILTIN_MISC_OPERATION_WITH_SILGEN(TaskAddPriorityEscalationHandler,
1194+
"taskAddPriorityEscalationHandler", "",
1195+
Special)
1196+
1197+
/// Equivalent to calling swift_task_removePriorityEscalationHandler.
1198+
///
1199+
/// Signature: (record: UnsafeRawPointer) -> ()
1200+
BUILTIN_MISC_OPERATION(TaskRemovePriorityEscalationHandler,
1201+
"taskRemovePriorityEscalationHandler", "", Special)
1202+
1203+
/// Equivalent to calling swift_task_localValuePush.
1204+
///
1205+
/// Signature: <Value> (key: Builtin.RawPointer, value: __owned Value) -> ()
1206+
BUILTIN_MISC_OPERATION(TaskLocalValuePush, "taskLocalValuePush", "", Special)
1207+
1208+
/// Equivalent to calling swift_task_localValuePop.
1209+
///
1210+
/// Signature: () -> ()
1211+
BUILTIN_MISC_OPERATION(TaskLocalValuePop, "taskLocalValuePop", "", Special)
1212+
11771213
#undef BUILTIN_TYPE_TRAIT_OPERATION
11781214
#undef BUILTIN_UNARY_OPERATION
11791215
#undef BUILTIN_BINARY_PREDICATE

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,6 +2660,72 @@ FUNCTION(TaskGroupDestroy,
26602660
EFFECT(RuntimeEffect::Concurrency),
26612661
UNKNOWN_MEMEFFECTS)
26622662

2663+
// CancellationNotificationStatusRecord*
2664+
// swift_task_addCancellationHandler(
2665+
// CancellationNotificationStatusRecord::FunctionType handler,
2666+
// void *context);
2667+
FUNCTION(TaskAddCancellationHandler,
2668+
_Concurrency, swift_task_addCancellationHandler, SwiftCC,
2669+
ConcurrencyAvailability,
2670+
RETURNS(Int8PtrTy),
2671+
ARGS(Int8PtrTy, Int8PtrTy),
2672+
ATTRS(NoUnwind),
2673+
EFFECT(RuntimeEffect::Concurrency),
2674+
UNKNOWN_MEMEFFECTS)
2675+
2676+
// void swift_task_removeCancellationHandler(
2677+
// CancellationNotificationStatusRecord *record);
2678+
FUNCTION(TaskRemoveCancellationHandler,
2679+
_Concurrency, swift_task_removeCancellationHandler, SwiftCC,
2680+
ConcurrencyAvailability,
2681+
RETURNS(VoidTy),
2682+
ARGS(Int8PtrTy),
2683+
ATTRS(NoUnwind),
2684+
EFFECT(RuntimeEffect::Concurrency),
2685+
UNKNOWN_MEMEFFECTS)
2686+
2687+
// EscalationNotificationStatusRecord*
2688+
// swift_task_addPriorityEscalationHandler(
2689+
// EscalationNotificationStatusRecord::FunctionType handler,
2690+
// void *context);
2691+
FUNCTION(TaskAddPriorityEscalationHandler,
2692+
_Concurrency, swift_task_addPriorityEscalationHandler, SwiftCC,
2693+
ConcurrencyAvailability,
2694+
RETURNS(Int8PtrTy),
2695+
ARGS(Int8PtrTy, Int8PtrTy),
2696+
ATTRS(NoUnwind),
2697+
EFFECT(RuntimeEffect::Concurrency),
2698+
UNKNOWN_MEMEFFECTS)
2699+
2700+
// void swift_task_removePriorityEscalationHandler(
2701+
// EscalationNotificationStatusRecord *record);
2702+
FUNCTION(TaskRemovePriorityEscalationHandler,
2703+
_Concurrency, swift_task_removePriorityEscalationHandler, SwiftCC,
2704+
ConcurrencyAvailability,
2705+
RETURNS(VoidTy),
2706+
ARGS(Int8PtrTy),
2707+
ATTRS(NoUnwind),
2708+
EFFECT(RuntimeEffect::Concurrency),
2709+
UNKNOWN_MEMEFFECTS)
2710+
2711+
// void swift_task_localValuePush(const HeapObject *key,
2712+
// /* +1 */ OpaqueValue *value,
2713+
// const Metadata *valueType);
2714+
FUNCTION(TaskLocalValuePush, _Concurrency, swift_task_localValuePush, SwiftCC,
2715+
ConcurrencyAvailability, RETURNS(),
2716+
ARGS(RefCountedPtrTy, OpaquePtrTy, TypeMetadataPtrTy), ATTRS(NoUnwind),
2717+
EFFECT(RuntimeEffect::Concurrency), UNKNOWN_MEMEFFECTS)
2718+
2719+
// void swift_task_localValuePop();
2720+
FUNCTION(TaskLocalValuePop,
2721+
_Concurrency, swift_task_localValuePop, SwiftCC,
2722+
ConcurrencyAvailability,
2723+
RETURNS(),
2724+
ARGS(),
2725+
ATTRS(NoUnwind),
2726+
EFFECT(RuntimeEffect::Concurrency),
2727+
UNKNOWN_MEMEFFECTS)
2728+
26632729
// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContextWithType(const Metadata *);
26642730
FUNCTION(AutoDiffCreateLinearMapContextWithType,
26652731
Swift, swift_autoDiffCreateLinearMapContextWithType, SwiftCC,

include/swift/SIL/AddressWalker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) {
295295
case BuiltinValueKind::AddressOfRawLayout:
296296
case BuiltinValueKind::FlowSensitiveSelfIsolation:
297297
case BuiltinValueKind::FlowSensitiveDistributedSelfIsolation:
298+
case BuiltinValueKind::TaskLocalValuePush:
298299
callVisitUse(op);
299300
continue;
300301
default:

lib/AST/Builtins.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2364,6 +2364,52 @@ static ValueDecl *getEmplace(ASTContext &ctx, Identifier id) {
23642364
return builder.build(id);
23652365
}
23662366

2367+
static ValueDecl *getTaskAddCancellationHandler(ASTContext &ctx,
2368+
Identifier id) {
2369+
auto extInfo = ASTExtInfoBuilder().withNoEscape().build();
2370+
auto fnType = FunctionType::get({}, ctx.TheEmptyTupleType, extInfo);
2371+
return getBuiltinFunction(ctx, id, _thin,
2372+
_parameters(_label("handler", fnType)),
2373+
_unsafeRawPointer);
2374+
}
2375+
2376+
static ValueDecl *getTaskRemoveCancellationHandler(ASTContext &ctx,
2377+
Identifier id) {
2378+
return getBuiltinFunction(
2379+
ctx, id, _thin, _parameters(_label("record", _unsafeRawPointer)), _void);
2380+
}
2381+
2382+
static ValueDecl *getTaskAddPriorityEscalationHandler(ASTContext &ctx,
2383+
Identifier id) {
2384+
std::array<AnyFunctionType::Param, 2> params = {
2385+
AnyFunctionType::Param(ctx.getUInt8Type()),
2386+
AnyFunctionType::Param(ctx.getUInt8Type()),
2387+
};
2388+
// (UInt8, UInt8) -> ()
2389+
auto extInfo = ASTExtInfoBuilder().withNoEscape().build();
2390+
auto *functionType =
2391+
FunctionType::get(params, ctx.TheEmptyTupleType, extInfo);
2392+
return getBuiltinFunction(ctx, id, _thin,
2393+
_parameters(_label("handler", functionType)),
2394+
_unsafeRawPointer);
2395+
}
2396+
2397+
static ValueDecl *getTaskRemovePriorityEscalationHandler(ASTContext &ctx,
2398+
Identifier id) {
2399+
return getBuiltinFunction(
2400+
ctx, id, _thin, _parameters(_label("record", _unsafeRawPointer)), _void);
2401+
}
2402+
2403+
static ValueDecl *getTaskLocalValuePush(ASTContext &ctx, Identifier id) {
2404+
return getBuiltinFunction(ctx, id, _thin, _generics(_unrestricted),
2405+
_parameters(_rawPointer, _consuming(_typeparam(0))),
2406+
_void);
2407+
}
2408+
2409+
static ValueDecl *getTaskLocalValuePop(ASTContext &ctx, Identifier id) {
2410+
return getBuiltinFunction(ctx, id, _thin, _parameters(), _void);
2411+
}
2412+
23672413
/// An array of the overloaded builtin kinds.
23682414
static const OverloadedBuiltinKind OverloadedBuiltinKinds[] = {
23692415
OverloadedBuiltinKind::None,
@@ -3450,6 +3496,24 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
34503496

34513497
case BuiltinValueKind::Emplace:
34523498
return getEmplace(Context, Id);
3499+
3500+
case BuiltinValueKind::TaskAddCancellationHandler:
3501+
return getTaskAddCancellationHandler(Context, Id);
3502+
3503+
case BuiltinValueKind::TaskRemoveCancellationHandler:
3504+
return getTaskRemoveCancellationHandler(Context, Id);
3505+
3506+
case BuiltinValueKind::TaskAddPriorityEscalationHandler:
3507+
return getTaskAddPriorityEscalationHandler(Context, Id);
3508+
3509+
case BuiltinValueKind::TaskRemovePriorityEscalationHandler:
3510+
return getTaskRemovePriorityEscalationHandler(Context, Id);
3511+
3512+
case BuiltinValueKind::TaskLocalValuePush:
3513+
return getTaskLocalValuePush(Context, Id);
3514+
3515+
case BuiltinValueKind::TaskLocalValuePop:
3516+
return getTaskLocalValuePop(Context, Id);
34533517
}
34543518

34553519
llvm_unreachable("bad builtin value!");

lib/IRGen/GenBuiltin.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,29 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
15651565
return;
15661566
}
15671567

1568+
case BuiltinValueKind::TaskRemovePriorityEscalationHandler:
1569+
case BuiltinValueKind::TaskRemoveCancellationHandler: {
1570+
auto rawPointer = args.claimNext();
1571+
emitBuiltinTaskRemoveHandler(IGF, Builtin.ID, rawPointer);
1572+
return;
1573+
}
1574+
case BuiltinValueKind::TaskAddCancellationHandler:
1575+
case BuiltinValueKind::TaskAddPriorityEscalationHandler: {
1576+
auto func = args.claimNext();
1577+
auto context = args.claimNext();
1578+
out.add(emitBuiltinTaskAddHandler(IGF, Builtin.ID, func, context));
1579+
return;
1580+
}
1581+
case BuiltinValueKind::TaskLocalValuePop:
1582+
return emitBuiltinTaskLocalValuePop(IGF);
1583+
case BuiltinValueKind::TaskLocalValuePush: {
1584+
auto *key = args.claimNext();
1585+
auto *value = args.claimNext();
1586+
// Grab T from the builtin.
1587+
auto *valueMetatype = IGF.emitTypeMetadataRef(argTypes[1].getASTType());
1588+
return emitBuiltinTaskLocalValuePush(IGF, key, value, valueMetatype);
1589+
}
1590+
15681591
// Builtins without IRGen implementations.
15691592
case BuiltinValueKind::None:
15701593
case BuiltinValueKind::CondFailMessage:

lib/IRGen/GenConcurrency.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,61 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF,
313313
return alet;
314314
}
315315

316+
llvm::Value *irgen::emitBuiltinTaskAddHandler(IRGenFunction &IGF,
317+
BuiltinValueKind kind,
318+
llvm::Value *func,
319+
llvm::Value *context) {
320+
auto callee = [&]() -> FunctionPointer {
321+
if (kind == BuiltinValueKind::TaskAddCancellationHandler) {
322+
return IGF.IGM.getTaskAddCancellationHandlerFunctionPointer();
323+
}
324+
if (kind == BuiltinValueKind::TaskAddPriorityEscalationHandler) {
325+
return IGF.IGM.getTaskAddPriorityEscalationHandlerFunctionPointer();
326+
}
327+
llvm::report_fatal_error("Unhandled builtin");
328+
}();
329+
auto *call = IGF.Builder.CreateCall(callee, {func, context});
330+
call->setDoesNotThrow();
331+
call->setCallingConv(IGF.IGM.SwiftCC);
332+
return call;
333+
}
334+
335+
void irgen::emitBuiltinTaskRemoveHandler(IRGenFunction &IGF,
336+
BuiltinValueKind kind,
337+
llvm::Value *record) {
338+
auto callee = [&]() -> FunctionPointer {
339+
if (kind == BuiltinValueKind::TaskRemoveCancellationHandler) {
340+
return IGF.IGM.getTaskRemoveCancellationHandlerFunctionPointer();
341+
}
342+
if (kind == BuiltinValueKind::TaskRemovePriorityEscalationHandler) {
343+
return IGF.IGM.getTaskRemovePriorityEscalationHandlerFunctionPointer();
344+
}
345+
llvm::report_fatal_error("Unhandled builtin");
346+
}();
347+
auto *call = IGF.Builder.CreateCall(callee, {record});
348+
call->setDoesNotThrow();
349+
call->setCallingConv(IGF.IGM.SwiftCC);
350+
}
351+
352+
void irgen::emitBuiltinTaskLocalValuePush(IRGenFunction &IGF, llvm::Value *key,
353+
llvm::Value *value,
354+
llvm::Value *valueMetatype) {
355+
auto callee = IGF.IGM.getTaskLocalValuePushFunctionPointer();
356+
357+
// We pass in Value at +1, but we are luckily given the value already at +1,
358+
// so the end lifetime is performed for us.
359+
auto *call = IGF.Builder.CreateCall(callee, {key, value, valueMetatype});
360+
call->setDoesNotThrow();
361+
call->setCallingConv(IGF.IGM.SwiftCC);
362+
}
363+
364+
void irgen::emitBuiltinTaskLocalValuePop(IRGenFunction &IGF) {
365+
auto *call =
366+
IGF.Builder.CreateCall(IGF.IGM.getTaskLocalValuePopFunctionPointer(), {});
367+
call->setDoesNotThrow();
368+
call->setCallingConv(IGF.IGM.SwiftCC);
369+
}
370+
316371
void irgen::emitFinishAsyncLet(IRGenFunction &IGF,
317372
llvm::Value *asyncLet,
318373
llvm::Value *resultBuffer) {

lib/IRGen/GenConcurrency.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,29 @@ emitTaskCreate(IRGenFunction &IGF, llvm::Value *flags,
115115
llvm::Value *clearImplicitIsolatedActorBits(IRGenFunction &IGF,
116116
llvm::Value *value);
117117

118+
/// Emit IR for a builtin that adds a handler to the Task's task record.
119+
///
120+
/// \returns the record that can be used to refer to and cancel the handler.
121+
///
122+
/// Currently supports TaskAddCancellationHandler and
123+
/// TaskAddPriorityEscalationHandler.
124+
llvm::Value *emitBuiltinTaskAddHandler(IRGenFunction &IGF,
125+
BuiltinValueKind kind, llvm::Value *func,
126+
llvm::Value *context);
127+
128+
/// Emit IR for a builtin that cancels some sort of handler by calling an ABI
129+
/// entry point. Record is a value that was returned by the handler creator.
130+
///
131+
/// E.x.: TaskRemoveCancellationHandler, TaskRemovePriorityEscalationHandler.
132+
void emitBuiltinTaskRemoveHandler(IRGenFunction &IGF, BuiltinValueKind kind,
133+
llvm::Value *record);
134+
135+
void emitBuiltinTaskLocalValuePush(IRGenFunction &IGF, llvm::Value *key,
136+
llvm::Value *value,
137+
llvm::Value *valueMetatype);
138+
139+
void emitBuiltinTaskLocalValuePop(IRGenFunction &IGF);
140+
118141
} // end namespace irgen
119142
} // end namespace swift
120143

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,19 @@ BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildDefaultActorExecutorRef)
10521052
BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildMainActorExecutorRef)
10531053

10541054
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContextWithType)
1055+
1056+
// InstantaneousUse since we take in a closure at +0.
1057+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TaskAddCancellationHandler)
1058+
// Trivial use since our operand is just an UnsafeRawPointer.
1059+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskRemoveCancellationHandler)
1060+
// InstantaneousUse since we take in a closure at +0.
1061+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TaskAddPriorityEscalationHandler)
1062+
// Trivial use since our operand is just an UnsafeRawPointer.
1063+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskRemovePriorityEscalationHandler)
1064+
// This is a trivial use since our first operand is a Builtin.RawPointer and our
1065+
// second is an address to our generic Value.
1066+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskLocalValuePush)
1067+
10551068
#undef BUILTIN_OPERAND_OWNERSHIP
10561069

10571070
#define SHOULD_NEVER_VISIT_BUILTIN(ID) \
@@ -1062,6 +1075,7 @@ BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContextWithType)
10621075
}
10631076
SHOULD_NEVER_VISIT_BUILTIN(GetCurrentAsyncTask)
10641077
SHOULD_NEVER_VISIT_BUILTIN(GetCurrentExecutor)
1078+
SHOULD_NEVER_VISIT_BUILTIN(TaskLocalValuePop)
10651079
#undef SHOULD_NEVER_VISIT_BUILTIN
10661080

10671081
// Builtins that should be lowered to SIL instructions so we should never see

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,13 @@ CONSTANT_OWNERSHIP_BUILTIN(Owned, DistributedActorAsAnyActor)
664664
CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, ExtractFunctionIsolation) // unreachable
665665
CONSTANT_OWNERSHIP_BUILTIN(None, AddressOfRawLayout)
666666

667+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskAddCancellationHandler)
668+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskRemoveCancellationHandler)
669+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskAddPriorityEscalationHandler)
670+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskRemovePriorityEscalationHandler)
671+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskLocalValuePush)
672+
CONSTANT_OWNERSHIP_BUILTIN(None, TaskLocalValuePop)
673+
667674
#undef CONSTANT_OWNERSHIP_BUILTIN
668675

669676
// Check all of these...

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,26 @@ static ManagedValue emitBuiltinEmplace(SILGenFunction &SGF,
21822182
return SGF.B.createLoadTake(loc, result);
21832183
}
21842184

2185+
static ManagedValue emitBuiltinTaskAddCancellationHandler(
2186+
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
2187+
ArrayRef<ManagedValue> args, SGFContext C) {
2188+
auto *b =
2189+
SGF.B.createBuiltin(loc, BuiltinNames::TaskAddCancellationHandler,
2190+
SILType::getUnsafeRawPointer(SGF.getASTContext()),
2191+
subs, {args[0].getValue()});
2192+
return ManagedValue::forRValueWithoutOwnership(b);
2193+
}
2194+
2195+
static ManagedValue emitBuiltinTaskAddPriorityEscalationHandler(
2196+
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
2197+
ArrayRef<ManagedValue> args, SGFContext C) {
2198+
auto *b =
2199+
SGF.B.createBuiltin(loc, BuiltinNames::TaskAddPriorityEscalationHandler,
2200+
SILType::getUnsafeRawPointer(SGF.getASTContext()),
2201+
subs, {args[0].getValue()});
2202+
return ManagedValue::forRValueWithoutOwnership(b);
2203+
}
2204+
21852205
std::optional<SpecializedEmitter>
21862206
SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) {
21872207
// Only consider standalone declarations in the Builtin module.

0 commit comments

Comments
 (0)