Skip to content

Commit a302d4e

Browse files
authored
Merge pull request #85224 from gottesmm/pr-6cb303a9f5f15489fa44c26d00c70155a6d7cc97
[concurrency] Create builtins for invoking specific concurrency runtime functions.
2 parents 8b73c9c + 48b253d commit a302d4e

File tree

23 files changed

+545
-147
lines changed

23 files changed

+545
-147
lines changed

include/swift/AST/ASTSynthesis.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ enum SingletonTypeSynthesizer {
5252
_rawUnsafeContinuation,
5353
_void,
5454
_word,
55-
_swiftInt, // Swift.Int
56-
_serialExecutor, // the '_Concurrency.SerialExecutor' protocol
57-
_taskExecutor, // the '_Concurrency.TaskExecutor' protocol
58-
_actor, // the '_Concurrency.Actor' protocol
59-
_distributedActor, // the 'Distributed.DistributedActor' protocol
55+
_swiftInt, // Swift.Int
56+
_serialExecutor, // the '_Concurrency.SerialExecutor' protocol
57+
_taskExecutor, // the '_Concurrency.TaskExecutor' protocol
58+
_actor, // the '_Concurrency.Actor' protocol
59+
_distributedActor, // the 'Distributed.DistributedActor' protocol
6060
_unsafeRawBufferPointer, // UnsafeRawBufferPointer
61-
_unconstrainedAny, // any ~Copyable & ~Escapable
61+
_unconstrainedAny, // any ~Copyable & ~Escapable
62+
_unsafeRawPointer, // UnsafeRawPointer
6263
};
6364
inline Type synthesizeType(SynthesisContext &SC,
6465
SingletonTypeSynthesizer kind) {
@@ -93,6 +94,8 @@ inline Type synthesizeType(SynthesisContext &SC,
9394
->getDeclaredInterfaceType();
9495
case _unsafeRawBufferPointer:
9596
return SC.Context.getUnsafeRawBufferPointerType();
97+
case _unsafeRawPointer:
98+
return SC.Context.getUnsafeRawPointerType();
9699
case _copyable:
97100
return SC.Context.getProtocol(KnownProtocolKind::Copyable)
98101
->getDeclaredInterfaceType();

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/AST/Builtins.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,21 @@ getLLVMIntrinsicIDForBuiltinWithOverflow(BuiltinValueKind ID);
107107
///
108108
/// Returns null if the name does not identifier a known builtin value.
109109
ValueDecl *getBuiltinValueDecl(ASTContext &Context, Identifier Name);
110-
110+
111+
/// Overload that takes a StringRef instead of an Identifier. We convert it to
112+
/// an identifier internally.
113+
ValueDecl *getBuiltinValueDecl(ASTContext &Context, StringRef Name);
114+
111115
/// Returns the name of a builtin declaration given a builtin ID.
112116
StringRef getBuiltinName(BuiltinValueKind ID);
113-
117+
118+
/// Namespace containing constexpr StringLiterals of BuiltinNames so that
119+
/// builtin names can be referred to without using raw string literals.
120+
namespace BuiltinNames {
121+
#define BUILTIN(Id, Name, Attrs) constexpr StringLiteral Id = Name;
122+
#include "swift/AST/Builtins.def"
123+
} // namespace BuiltinNames
124+
114125
/// The information identifying the builtin - its kind and types.
115126
class BuiltinInfo {
116127
public:

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:

include/swift/SIL/SILBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,12 @@ class SILBuilder {
611611
Subs, Args, getInstructionContext()));
612612
}
613613

614+
BuiltinInst *createBuiltin(SILLocation Loc, StringRef Name, SILType ResultTy,
615+
SubstitutionMap Subs, ArrayRef<SILValue> Args) {
616+
return createBuiltin(Loc, getASTContext().getIdentifier(Name), ResultTy,
617+
Subs, Args);
618+
}
619+
614620
/// Create a binary function with the signature: OpdTy, OpdTy -> ResultTy.
615621
BuiltinInst *createBuiltinBinaryFunction(SILLocation Loc, StringRef Name,
616622
SILType OpdTy, SILType ResultTy,

include/swift/SIL/SILType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,9 @@ class SILType {
10671067
/// Return Builtin.ImplicitActor.
10681068
static SILType getBuiltinImplicitActorType(const ASTContext &ctx);
10691069

1070+
/// Return UnsafeRawPointer.
1071+
static SILType getUnsafeRawPointer(const ASTContext &ctx);
1072+
10701073
//
10711074
// Utilities for treating SILType as a pointer-like type.
10721075
//

lib/AST/Builtins.cpp

Lines changed: 68 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,
@@ -3452,6 +3498,24 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
34523498

34533499
case BuiltinValueKind::Emplace:
34543500
return getEmplace(Context, Id);
3501+
3502+
case BuiltinValueKind::TaskAddCancellationHandler:
3503+
return getTaskAddCancellationHandler(Context, Id);
3504+
3505+
case BuiltinValueKind::TaskRemoveCancellationHandler:
3506+
return getTaskRemoveCancellationHandler(Context, Id);
3507+
3508+
case BuiltinValueKind::TaskAddPriorityEscalationHandler:
3509+
return getTaskAddPriorityEscalationHandler(Context, Id);
3510+
3511+
case BuiltinValueKind::TaskRemovePriorityEscalationHandler:
3512+
return getTaskRemovePriorityEscalationHandler(Context, Id);
3513+
3514+
case BuiltinValueKind::TaskLocalValuePush:
3515+
return getTaskLocalValuePush(Context, Id);
3516+
3517+
case BuiltinValueKind::TaskLocalValuePop:
3518+
return getTaskLocalValuePop(Context, Id);
34553519
}
34563520

34573521
llvm_unreachable("bad builtin value!");
@@ -3815,3 +3879,7 @@ BuiltinFixedArrayType::isFixedNegativeSize() const {
38153879
}
38163880
return false;
38173881
}
3882+
3883+
ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, StringRef Name) {
3884+
return getBuiltinValueDecl(Context, Context.getIdentifier(Name));
3885+
}

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) {

0 commit comments

Comments
 (0)