diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index 7540421f671..826f8305a13 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -1174,6 +1174,42 @@ BUILTIN_TYPE_CHECKER_OPERATION(TriggerFallbackDiagnostic, trigger_fallback_diagn /// Maybe. BUILTIN_TYPE_TRAIT_OPERATION(CanBeObjCClass, canBeClass) +/// Equivalent to calling swift_task_addCancellationHandler. +/// +/// Signature: (handler: () -> Void) -> UnsafeRawPointer +BUILTIN_MISC_OPERATION_WITH_SILGEN(TaskAddCancellationHandler, + "taskAddCancellationHandler", "", + Special) + +/// Equivalent to calling swift_task_removeCancellationHandler. +/// +/// Signature: (record: UnsafeRawPointer) -> () +BUILTIN_MISC_OPERATION(TaskRemoveCancellationHandler, + "taskRemoveCancellationHandler", "", Special) + +/// Equivalent to calling swift_task_addPriorityEscalationHandler. +/// +/// Signature: (handler: (UInt8, UInt8) -> Void) -> UnsafeRawPointer +BUILTIN_MISC_OPERATION_WITH_SILGEN(TaskAddPriorityEscalationHandler, + "taskAddPriorityEscalationHandler", "", + Special) + +/// Equivalent to calling swift_task_removePriorityEscalationHandler. +/// +/// Signature: (record: UnsafeRawPointer) -> () +BUILTIN_MISC_OPERATION(TaskRemovePriorityEscalationHandler, + "taskRemovePriorityEscalationHandler", "", Special) + +/// Equivalent to calling swift_task_localValuePush. +/// +/// Signature: (key: Builtin.RawPointer, value: __owned Value) -> () +BUILTIN_MISC_OPERATION(TaskLocalValuePush, "taskLocalValuePush", "", Special) + +/// Equivalent to calling swift_task_localValuePop. +/// +/// Signature: () -> () +BUILTIN_MISC_OPERATION(TaskLocalValuePop, "taskLocalValuePop", "", Special) + #undef BUILTIN_TYPE_TRAIT_OPERATION #undef BUILTIN_UNARY_OPERATION #undef BUILTIN_BINARY_PREDICATE diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def index b802873309a..31db6ed1cdf 100644 --- a/include/swift/Runtime/RuntimeFunctions.def +++ b/include/swift/Runtime/RuntimeFunctions.def @@ -2660,6 +2660,72 @@ FUNCTION(TaskGroupDestroy, EFFECT(RuntimeEffect::Concurrency), UNKNOWN_MEMEFFECTS) +// CancellationNotificationStatusRecord* +// swift_task_addCancellationHandler( +// CancellationNotificationStatusRecord::FunctionType handler, +// void *context); +FUNCTION(TaskAddCancellationHandler, + _Concurrency, swift_task_addCancellationHandler, SwiftCC, + ConcurrencyAvailability, + RETURNS(Int8PtrTy), + ARGS(Int8PtrTy, Int8PtrTy), + ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), + UNKNOWN_MEMEFFECTS) + +// void swift_task_removeCancellationHandler( +// CancellationNotificationStatusRecord *record); +FUNCTION(TaskRemoveCancellationHandler, + _Concurrency, swift_task_removeCancellationHandler, SwiftCC, + ConcurrencyAvailability, + RETURNS(VoidTy), + ARGS(Int8PtrTy), + ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), + UNKNOWN_MEMEFFECTS) + +// EscalationNotificationStatusRecord* +// swift_task_addPriorityEscalationHandler( +// EscalationNotificationStatusRecord::FunctionType handler, +// void *context); +FUNCTION(TaskAddPriorityEscalationHandler, + _Concurrency, swift_task_addPriorityEscalationHandler, SwiftCC, + ConcurrencyAvailability, + RETURNS(Int8PtrTy), + ARGS(Int8PtrTy, Int8PtrTy), + ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), + UNKNOWN_MEMEFFECTS) + +// void swift_task_removePriorityEscalationHandler( +// EscalationNotificationStatusRecord *record); +FUNCTION(TaskRemovePriorityEscalationHandler, + _Concurrency, swift_task_removePriorityEscalationHandler, SwiftCC, + ConcurrencyAvailability, + RETURNS(VoidTy), + ARGS(Int8PtrTy), + ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), + UNKNOWN_MEMEFFECTS) + +// void swift_task_localValuePush(const HeapObject *key, +// /* +1 */ OpaqueValue *value, +// const Metadata *valueType); +FUNCTION(TaskLocalValuePush, _Concurrency, swift_task_localValuePush, SwiftCC, + ConcurrencyAvailability, RETURNS(), + ARGS(RefCountedPtrTy, OpaquePtrTy, TypeMetadataPtrTy), ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), UNKNOWN_MEMEFFECTS) + +// void swift_task_localValuePop(); +FUNCTION(TaskLocalValuePop, + _Concurrency, swift_task_localValuePop, SwiftCC, + ConcurrencyAvailability, + RETURNS(), + ARGS(), + ATTRS(NoUnwind), + EFFECT(RuntimeEffect::Concurrency), + UNKNOWN_MEMEFFECTS) + // AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContextWithType(const Metadata *); FUNCTION(AutoDiffCreateLinearMapContextWithType, Swift, swift_autoDiffCreateLinearMapContextWithType, SwiftCC, diff --git a/include/swift/SIL/AddressWalker.h b/include/swift/SIL/AddressWalker.h index db2b564f96e..e9f7868bdaa 100644 --- a/include/swift/SIL/AddressWalker.h +++ b/include/swift/SIL/AddressWalker.h @@ -295,6 +295,7 @@ TransitiveAddressWalker::walk(SILValue projectedAddress) { case BuiltinValueKind::AddressOfRawLayout: case BuiltinValueKind::FlowSensitiveSelfIsolation: case BuiltinValueKind::FlowSensitiveDistributedSelfIsolation: + case BuiltinValueKind::TaskLocalValuePush: callVisitUse(op); continue; default: diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index a7b9b3d1e49..3ad5bc65023 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -2364,6 +2364,52 @@ static ValueDecl *getEmplace(ASTContext &ctx, Identifier id) { return builder.build(id); } +static ValueDecl *getTaskAddCancellationHandler(ASTContext &ctx, + Identifier id) { + auto extInfo = ASTExtInfoBuilder().withNoEscape().build(); + auto fnType = FunctionType::get({}, ctx.TheEmptyTupleType, extInfo); + return getBuiltinFunction(ctx, id, _thin, + _parameters(_label("handler", fnType)), + _unsafeRawPointer); +} + +static ValueDecl *getTaskRemoveCancellationHandler(ASTContext &ctx, + Identifier id) { + return getBuiltinFunction( + ctx, id, _thin, _parameters(_label("record", _unsafeRawPointer)), _void); +} + +static ValueDecl *getTaskAddPriorityEscalationHandler(ASTContext &ctx, + Identifier id) { + std::array params = { + AnyFunctionType::Param(ctx.getUInt8Type()), + AnyFunctionType::Param(ctx.getUInt8Type()), + }; + // (UInt8, UInt8) -> () + auto extInfo = ASTExtInfoBuilder().withNoEscape().build(); + auto *functionType = + FunctionType::get(params, ctx.TheEmptyTupleType, extInfo); + return getBuiltinFunction(ctx, id, _thin, + _parameters(_label("handler", functionType)), + _unsafeRawPointer); +} + +static ValueDecl *getTaskRemovePriorityEscalationHandler(ASTContext &ctx, + Identifier id) { + return getBuiltinFunction( + ctx, id, _thin, _parameters(_label("record", _unsafeRawPointer)), _void); +} + +static ValueDecl *getTaskLocalValuePush(ASTContext &ctx, Identifier id) { + return getBuiltinFunction(ctx, id, _thin, _generics(_unrestricted), + _parameters(_rawPointer, _consuming(_typeparam(0))), + _void); +} + +static ValueDecl *getTaskLocalValuePop(ASTContext &ctx, Identifier id) { + return getBuiltinFunction(ctx, id, _thin, _parameters(), _void); +} + /// An array of the overloaded builtin kinds. static const OverloadedBuiltinKind OverloadedBuiltinKinds[] = { OverloadedBuiltinKind::None, @@ -3450,6 +3496,24 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { case BuiltinValueKind::Emplace: return getEmplace(Context, Id); + + case BuiltinValueKind::TaskAddCancellationHandler: + return getTaskAddCancellationHandler(Context, Id); + + case BuiltinValueKind::TaskRemoveCancellationHandler: + return getTaskRemoveCancellationHandler(Context, Id); + + case BuiltinValueKind::TaskAddPriorityEscalationHandler: + return getTaskAddPriorityEscalationHandler(Context, Id); + + case BuiltinValueKind::TaskRemovePriorityEscalationHandler: + return getTaskRemovePriorityEscalationHandler(Context, Id); + + case BuiltinValueKind::TaskLocalValuePush: + return getTaskLocalValuePush(Context, Id); + + case BuiltinValueKind::TaskLocalValuePop: + return getTaskLocalValuePop(Context, Id); } llvm_unreachable("bad builtin value!"); diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp index bdcbee51c1f..e278a41911c 100644 --- a/lib/IRGen/GenBuiltin.cpp +++ b/lib/IRGen/GenBuiltin.cpp @@ -1565,6 +1565,29 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin, return; } + case BuiltinValueKind::TaskRemovePriorityEscalationHandler: + case BuiltinValueKind::TaskRemoveCancellationHandler: { + auto rawPointer = args.claimNext(); + emitBuiltinTaskRemoveHandler(IGF, Builtin.ID, rawPointer); + return; + } + case BuiltinValueKind::TaskAddCancellationHandler: + case BuiltinValueKind::TaskAddPriorityEscalationHandler: { + auto func = args.claimNext(); + auto context = args.claimNext(); + out.add(emitBuiltinTaskAddHandler(IGF, Builtin.ID, func, context)); + return; + } + case BuiltinValueKind::TaskLocalValuePop: + return emitBuiltinTaskLocalValuePop(IGF); + case BuiltinValueKind::TaskLocalValuePush: { + auto *key = args.claimNext(); + auto *value = args.claimNext(); + // Grab T from the builtin. + auto *valueMetatype = IGF.emitTypeMetadataRef(argTypes[1].getASTType()); + return emitBuiltinTaskLocalValuePush(IGF, key, value, valueMetatype); + } + // Builtins without IRGen implementations. case BuiltinValueKind::None: case BuiltinValueKind::CondFailMessage: diff --git a/lib/IRGen/GenConcurrency.cpp b/lib/IRGen/GenConcurrency.cpp index ea8e37d1064..3f7f476daa2 100644 --- a/lib/IRGen/GenConcurrency.cpp +++ b/lib/IRGen/GenConcurrency.cpp @@ -313,6 +313,61 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF, return alet; } +llvm::Value *irgen::emitBuiltinTaskAddHandler(IRGenFunction &IGF, + BuiltinValueKind kind, + llvm::Value *func, + llvm::Value *context) { + auto callee = [&]() -> FunctionPointer { + if (kind == BuiltinValueKind::TaskAddCancellationHandler) { + return IGF.IGM.getTaskAddCancellationHandlerFunctionPointer(); + } + if (kind == BuiltinValueKind::TaskAddPriorityEscalationHandler) { + return IGF.IGM.getTaskAddPriorityEscalationHandlerFunctionPointer(); + } + llvm::report_fatal_error("Unhandled builtin"); + }(); + auto *call = IGF.Builder.CreateCall(callee, {func, context}); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.SwiftCC); + return call; +} + +void irgen::emitBuiltinTaskRemoveHandler(IRGenFunction &IGF, + BuiltinValueKind kind, + llvm::Value *record) { + auto callee = [&]() -> FunctionPointer { + if (kind == BuiltinValueKind::TaskRemoveCancellationHandler) { + return IGF.IGM.getTaskRemoveCancellationHandlerFunctionPointer(); + } + if (kind == BuiltinValueKind::TaskRemovePriorityEscalationHandler) { + return IGF.IGM.getTaskRemovePriorityEscalationHandlerFunctionPointer(); + } + llvm::report_fatal_error("Unhandled builtin"); + }(); + auto *call = IGF.Builder.CreateCall(callee, {record}); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.SwiftCC); +} + +void irgen::emitBuiltinTaskLocalValuePush(IRGenFunction &IGF, llvm::Value *key, + llvm::Value *value, + llvm::Value *valueMetatype) { + auto callee = IGF.IGM.getTaskLocalValuePushFunctionPointer(); + + // We pass in Value at +1, but we are luckily given the value already at +1, + // so the end lifetime is performed for us. + auto *call = IGF.Builder.CreateCall(callee, {key, value, valueMetatype}); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.SwiftCC); +} + +void irgen::emitBuiltinTaskLocalValuePop(IRGenFunction &IGF) { + auto *call = + IGF.Builder.CreateCall(IGF.IGM.getTaskLocalValuePopFunctionPointer(), {}); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.SwiftCC); +} + void irgen::emitFinishAsyncLet(IRGenFunction &IGF, llvm::Value *asyncLet, llvm::Value *resultBuffer) { diff --git a/lib/IRGen/GenConcurrency.h b/lib/IRGen/GenConcurrency.h index 4f59a715208..062b4f74cbd 100644 --- a/lib/IRGen/GenConcurrency.h +++ b/lib/IRGen/GenConcurrency.h @@ -115,6 +115,29 @@ emitTaskCreate(IRGenFunction &IGF, llvm::Value *flags, llvm::Value *clearImplicitIsolatedActorBits(IRGenFunction &IGF, llvm::Value *value); +/// Emit IR for a builtin that adds a handler to the Task's task record. +/// +/// \returns the record that can be used to refer to and cancel the handler. +/// +/// Currently supports TaskAddCancellationHandler and +/// TaskAddPriorityEscalationHandler. +llvm::Value *emitBuiltinTaskAddHandler(IRGenFunction &IGF, + BuiltinValueKind kind, llvm::Value *func, + llvm::Value *context); + +/// Emit IR for a builtin that cancels some sort of handler by calling an ABI +/// entry point. Record is a value that was returned by the handler creator. +/// +/// E.x.: TaskRemoveCancellationHandler, TaskRemovePriorityEscalationHandler. +void emitBuiltinTaskRemoveHandler(IRGenFunction &IGF, BuiltinValueKind kind, + llvm::Value *record); + +void emitBuiltinTaskLocalValuePush(IRGenFunction &IGF, llvm::Value *key, + llvm::Value *value, + llvm::Value *valueMetatype); + +void emitBuiltinTaskLocalValuePop(IRGenFunction &IGF); + } // end namespace irgen } // end namespace swift diff --git a/lib/SIL/IR/OperandOwnership.cpp b/lib/SIL/IR/OperandOwnership.cpp index 23f8f312fbc..b97d3de1f9a 100644 --- a/lib/SIL/IR/OperandOwnership.cpp +++ b/lib/SIL/IR/OperandOwnership.cpp @@ -1052,6 +1052,19 @@ BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildDefaultActorExecutorRef) BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildMainActorExecutorRef) BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContextWithType) + +// InstantaneousUse since we take in a closure at +0. +BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TaskAddCancellationHandler) +// Trivial use since our operand is just an UnsafeRawPointer. +BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskRemoveCancellationHandler) +// InstantaneousUse since we take in a closure at +0. +BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TaskAddPriorityEscalationHandler) +// Trivial use since our operand is just an UnsafeRawPointer. +BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskRemovePriorityEscalationHandler) +// This is a trivial use since our first operand is a Builtin.RawPointer and our +// second is an address to our generic Value. +BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskLocalValuePush) + #undef BUILTIN_OPERAND_OWNERSHIP #define SHOULD_NEVER_VISIT_BUILTIN(ID) \ @@ -1062,6 +1075,7 @@ BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContextWithType) } SHOULD_NEVER_VISIT_BUILTIN(GetCurrentAsyncTask) SHOULD_NEVER_VISIT_BUILTIN(GetCurrentExecutor) +SHOULD_NEVER_VISIT_BUILTIN(TaskLocalValuePop) #undef SHOULD_NEVER_VISIT_BUILTIN // Builtins that should be lowered to SIL instructions so we should never see diff --git a/lib/SIL/IR/ValueOwnership.cpp b/lib/SIL/IR/ValueOwnership.cpp index 7731af0a564..3cb2dcc55f3 100644 --- a/lib/SIL/IR/ValueOwnership.cpp +++ b/lib/SIL/IR/ValueOwnership.cpp @@ -664,6 +664,13 @@ CONSTANT_OWNERSHIP_BUILTIN(Owned, DistributedActorAsAnyActor) CONSTANT_OWNERSHIP_BUILTIN(Guaranteed, ExtractFunctionIsolation) // unreachable CONSTANT_OWNERSHIP_BUILTIN(None, AddressOfRawLayout) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskAddCancellationHandler) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskRemoveCancellationHandler) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskAddPriorityEscalationHandler) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskRemovePriorityEscalationHandler) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskLocalValuePush) +CONSTANT_OWNERSHIP_BUILTIN(None, TaskLocalValuePop) + #undef CONSTANT_OWNERSHIP_BUILTIN // Check all of these... diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index 6765b2a1f0a..974fead29df 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -2182,6 +2182,26 @@ static ManagedValue emitBuiltinEmplace(SILGenFunction &SGF, return SGF.B.createLoadTake(loc, result); } +static ManagedValue emitBuiltinTaskAddCancellationHandler( + SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs, + ArrayRef args, SGFContext C) { + auto *b = + SGF.B.createBuiltin(loc, BuiltinNames::TaskAddCancellationHandler, + SILType::getUnsafeRawPointer(SGF.getASTContext()), + subs, {args[0].getValue()}); + return ManagedValue::forRValueWithoutOwnership(b); +} + +static ManagedValue emitBuiltinTaskAddPriorityEscalationHandler( + SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs, + ArrayRef args, SGFContext C) { + auto *b = + SGF.B.createBuiltin(loc, BuiltinNames::TaskAddPriorityEscalationHandler, + SILType::getUnsafeRawPointer(SGF.getASTContext()), + subs, {args[0].getValue()}); + return ManagedValue::forRValueWithoutOwnership(b); +} + std::optional SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) { // Only consider standalone declarations in the Builtin module. diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp index 1c3e62eaa2a..1134d0f0f4b 100644 --- a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp +++ b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp @@ -214,6 +214,12 @@ static bool isBarrier(SILInstruction *inst) { case BuiltinValueKind::AddressOfBorrowOpaque: case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque: case BuiltinValueKind::DistributedActorAsAnyActor: + case BuiltinValueKind::TaskAddCancellationHandler: + case BuiltinValueKind::TaskRemoveCancellationHandler: + case BuiltinValueKind::TaskAddPriorityEscalationHandler: + case BuiltinValueKind::TaskRemovePriorityEscalationHandler: + case BuiltinValueKind::TaskLocalValuePush: + case BuiltinValueKind::TaskLocalValuePop: return true; } } diff --git a/test/IRGen/builtins.swift b/test/IRGen/builtins.swift index 5dd61da3026..06b529173d5 100644 --- a/test/IRGen/builtins.swift +++ b/test/IRGen/builtins.swift @@ -928,4 +928,63 @@ func allocateVector(elementType: Element.Type, capacity: Builtin.Word) return Builtin.allocVector(elementType, capacity) } +// CHECK-LABEL: define{{.*}} void @"$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaF"(ptr swiftasync %0, i64 %1, i64 %2) +// CHECK: [[RESULT:%.*]] = call{{.*}} @swift_task_addCancellationHandler(ptr @"$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaFyyXEfU_", ptr null) +// CHECK: [[CONTEXT:%.*]] = call{{.*}} @swift_allocObject(ptr getelementptr inbounds (%swift.full_boxmetadata, ptr @metadata, i32 0, i32 2), i64 32, i64 7) +// CHECK: [[RESULT_2:%.*]] = call {{.*}} @swift_task_addCancellationHandler(ptr @"$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaFyyXEfU0_TA", ptr [[CONTEXT]]) +// CHECK: musttail call swifttailcc void {{%.*}}(ptr swiftasync {{.*}}, ptr [[RESULT]], ptr [[RESULT_2]]) +nonisolated(nonsending) func testTaskAddCancellationHandler() async -> (UnsafeRawPointer, UnsafeRawPointer) { + let result = Builtin.taskAddCancellationHandler {} + let x = "123" + let result2 = Builtin.taskAddCancellationHandler { + print(x) + } + return (result, result2) +} + +// CHECK-LABEL: define {{.*}}void @"$s8builtins33testTaskRemoveCancellationHandleryySVYaF"(ptr swiftasync %0, i64 %1, i64 %2, ptr %3) +// CHECK: call{{.*}} @swift_task_removeCancellationHandler(ptr %3) +nonisolated(nonsending) func testTaskRemoveCancellationHandler(_ x: UnsafeRawPointer) async { + Builtin.taskRemoveCancellationHandler(record: x) +} + +// CHECK-LABEL: define {{.*}}void @"$s8builtins36testTaskAddPriorityEscalationHandlerSV_SVtyYaF"(ptr swiftasync %0, i64 %1, i64 %2) +// CHECK: [[RESULT:%.*]] = call{{.*}} @swift_task_addPriorityEscalationHandler(ptr @"$s8builtins36testTaskAddPriorityEscalationHandlerSV_SVtyYaFys5UInt8V_ADtXEfU_", ptr null) +// CHECK: [[CONTEXT:%.*]] = call {{.*}}@swift_allocObject(ptr getelementptr inbounds (%swift.full_boxmetadata, ptr @metadata.3, i32 0, i32 2), i64 32, i64 7) +// CHECK: [[RESULT_2:%.*]] = call{{.*}} @swift_task_addPriorityEscalationHandler(ptr @"$s8builtins36testTaskAddPriorityEscalationHandlerSV_SVtyYaFys5UInt8V_ADtXEfU0_TA", ptr [[CONTEXT]]) +// CHECK: musttail call swifttailcc void {{%.*}}(ptr swiftasync {{%.*}}, ptr [[RESULT]], ptr [[RESULT_2]]) +nonisolated(nonsending) func testTaskAddPriorityEscalationHandler() async -> (UnsafeRawPointer, UnsafeRawPointer) { + let result = Builtin.taskAddPriorityEscalationHandler { (x: UInt8, y: UInt8) in + _ = x + _ = y + } + let str = "123" + let result2 = Builtin.taskAddPriorityEscalationHandler { (x: UInt8, y: UInt8) in + print(str) + _ = x + _ = y + } + return (result, result2) +} + +// CHECK-LABEL: define {{.*}}void @"$s8builtins39testTaskRemovePriorityEscalationHandleryySVYaF"(ptr swiftasync %0, i64 %1, i64 %2, ptr %3) +// CHECK: call{{.*}} @swift_task_removePriorityEscalationHandler(ptr %3) +nonisolated(nonsending) func testTaskRemovePriorityEscalationHandler(_ x: UnsafeRawPointer) async { + Builtin.taskRemovePriorityEscalationHandler(record: x) +} + +// CHECK-LABEL: define {{.*}}void @"$s8builtins22testTaskLocalValuePushyyBp_xntYalF"(ptr swiftasync %0, i64 %1, i64 %2, ptr %3, ptr noalias %4, ptr %Value) +// CHECK: [[TASK_VAR:%.*]] = call swiftcc ptr @swift_task_alloc({{.*}} +// CHECK: call ptr %InitializeWithTake(ptr noalias [[TASK_VAR]], ptr noalias {{%.*}}, ptr %Value) +// CHECK: call swiftcc {} @swift_task_localValuePush(ptr %3, ptr [[TASK_VAR]], ptr %Value) +nonisolated(nonsending) func testTaskLocalValuePush(_ key: Builtin.RawPointer, _ value: consuming Value) async { + Builtin.taskLocalValuePush(key, value) +} + +// CHECK-LABEL: define {{.*}}void @"$s8builtins21testTaskLocalValuePopyyYaF"(ptr swiftasync %0, i64 %1, i64 %2) +// CHECK: call swiftcc {} @swift_task_localValuePop() +nonisolated(nonsending) func testTaskLocalValuePop() async { + Builtin.taskLocalValuePop() +} + // CHECK: ![[R]] = !{i64 0, i64 9223372036854775807} diff --git a/test/SILGen/builtins.swift b/test/SILGen/builtins.swift index 8d972b06e7c..cf9fe9f2dbd 100644 --- a/test/SILGen/builtins.swift +++ b/test/SILGen/builtins.swift @@ -903,3 +903,79 @@ func getEnumTag(_ x: T) -> Builtin.Int32 { func injectEnumTag(_ x: inout T, tag: Builtin.Int32) { Builtin.injectEnumTag(&x, tag) } + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaF : $@convention(thin) @async () -> (UnsafeRawPointer, UnsafeRawPointer) { +// CHECK: [[CLOSURE_FN:%.*]] = function_ref @$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaFyyXEfU_ : $@convention(thin) () -> () +// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[CLOSURE_FN]] +// CHECK: [[RESULT_VALUE:%.*]] = builtin "taskAddCancellationHandler"([[CLOSURE]] : $@noescape @callee_guaranteed () -> ()) : $UnsafeRawPointer +// CHECK: [[RESULT:%.*]] = move_value [var_decl] [[RESULT_VALUE]] +// CHECK: [[CLOSURE_FN_2:%.*]] = function_ref @$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaFyyXEfU0_ : $@convention(thin) (@guaranteed String) -> () +// CHECK: [[CLOSURE_PA:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_FN_2]]({{%.*}}) : +// CHECK: [[CLOSURE_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CLOSURE_PA]] +// CHECK: [[RESULT_VALUE_2:%.*]] = builtin "taskAddCancellationHandler"([[CLOSURE_CVT]] : $@noescape @callee_guaranteed () -> ()) : $UnsafeRawPointer +// CHECK: [[RESULT_2:%.*]] = move_value [var_decl] [[RESULT_VALUE_2]] +// CHECK: [[TUPLE:%.*]] = tuple ([[RESULT]] : $UnsafeRawPointer, [[RESULT_2]] : $UnsafeRawPointer) +// CHECK: return [[TUPLE]] +// CHECK: } // end sil function '$s8builtins30testTaskAddCancellationHandlerSV_SVtyYaF' +func testTaskAddCancellationHandler() async -> (UnsafeRawPointer, UnsafeRawPointer) { + let result = Builtin.taskAddCancellationHandler { + } + let x = "123" + let result2 = Builtin.taskAddCancellationHandler { print(x) } + return (result, result2) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins33testTaskRemoveCancellationHandleryySVYaF : $@convention(thin) @async (UnsafeRawPointer) -> () +// CHECK: bb0([[PTR:%.*]] : $UnsafeRawPointer): +// CHECK: builtin "taskRemoveCancellationHandler"([[PTR]] : $UnsafeRawPointer) : $() +// CHECK: } // end sil function '$s8builtins33testTaskRemoveCancellationHandleryySVYaF' +func testTaskRemoveCancellationHandler(_ x: UnsafeRawPointer) async { + Builtin.taskRemoveCancellationHandler(record: x) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins36testTaskAddPriorityEscalationHandlerSVyYaF : $@convention(thin) @async () -> UnsafeRawPointer { +// CHECK: [[CLOSURE_FN:%.*]] = function_ref @$s8builtins36testTaskAddPriorityEscalationHandlerSVyYaFys5UInt8V_ADtXEfU_ : $@convention(thin) (UInt8, UInt8) -> () +// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[CLOSURE_FN]] +// CHECK: [[RESULT_VALUE:%.*]] = builtin "taskAddPriorityEscalationHandler"([[CLOSURE]] : $@noescape @callee_guaranteed (UInt8, UInt8) -> ()) : $UnsafeRawPointer +// CHECK: [[RESULT:%.*]] = move_value [var_decl] [[RESULT_VALUE]] +// CHECK: return [[RESULT]] +// CHECK: } // end sil function '$s8builtins36testTaskAddPriorityEscalationHandlerSVyYaF' +func testTaskAddPriorityEscalationHandler() async -> UnsafeRawPointer { + let result = Builtin.taskAddPriorityEscalationHandler { (x: UInt8, y: UInt8) in + _ = x + _ = y + } + return result +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins39testTaskRemovePriorityEscalationHandleryySVYaF : $@convention(thin) @async (UnsafeRawPointer) -> () { +// CHECK: bb0([[PTR:%.*]] : $UnsafeRawPointer): +// CHECK: builtin "taskRemovePriorityEscalationHandler"(%0 : $UnsafeRawPointer) : $() +// CHECK: } // end sil function '$s8builtins39testTaskRemovePriorityEscalationHandleryySVYaF' +func testTaskRemovePriorityEscalationHandler(_ x: UnsafeRawPointer) async { + Builtin.taskRemovePriorityEscalationHandler(record: x) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins22testTaskLocalValuePushyyBp_xntYalF : $@convention(thin) @async (Builtin.RawPointer, @in Value) -> () { +// CHECK: bb0([[PTR_ARG:%.*]] : $Builtin.RawPointer, [[VALUE:%.*]] : @noImplicitCopy @_eagerMove $*Value): +// CHECK: [[CONSUME_BOX:%.*]] = alloc_box $<τ_0_0> { var @moveOnly τ_0_0 } , var, name "value" +// CHECK: [[BORROW_BOX:%.*]] = begin_borrow [var_decl] [[CONSUME_BOX]] +// CHECK: [[PROJECT_BOX:%.*]] = project_box [[BORROW_BOX]] +// CHECK: [[WRAPPER:%.*]] = moveonlywrapper_to_copyable_addr [[PROJECT_BOX]] +// CHECK: copy_addr [take] [[VALUE]] to [init] [[WRAPPER]] +// CHECK: [[DEINIT_ADDR:%.*]] = begin_access [deinit] [unknown] [[PROJECT_BOX]] +// CHECK: [[MOVE_ONLY_ADDR:%.*]] = mark_unresolved_non_copyable_value [assignable_but_not_consumable] [[DEINIT_ADDR]] +// CHECK: [[STACK:%.*]] = alloc_stack $@moveOnly Value +// CHECK: copy_addr [[MOVE_ONLY_ADDR]] to [init] [[STACK]] +// CHECK: builtin "taskLocalValuePush"([[PTR_ARG]] : $Builtin.RawPointer, [[STACK]] : $*@moveOnly Value) : $() +// CHECK: } // end sil function '$s8builtins22testTaskLocalValuePushyyBp_xntYalF' +func testTaskLocalValuePush(_ key: Builtin.RawPointer, _ value: consuming Value) async { + Builtin.taskLocalValuePush(key, value) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins21testTaskLocalValuePopyyYaF : $@convention(thin) @async () -> () { +// CHECK: builtin "taskLocalValuePop"() : $() +// CHECK: } // end sil function '$s8builtins21testTaskLocalValuePopyyYaF' +func testTaskLocalValuePop() async { + Builtin.taskLocalValuePop() +}