Skip to content

Commit 02ddc29

Browse files
committed
Add Builtin.createTask and Builtin.createDiscardingTask.
1 parent 2889d55 commit 02ddc29

File tree

6 files changed

+165
-12
lines changed

6 files changed

+165
-12
lines changed

include/swift/AST/Builtins.def

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -952,13 +952,33 @@ BUILTIN_MISC_OPERATION(AddressOfBorrowOpaque, "addressOfBorrowOpaque", "", Speci
952952
/// AddressLowering.
953953
BUILTIN_MISC_OPERATION(UnprotectedAddressOfBorrowOpaque, "unprotectedAddressOfBorrowOpaque", "", Special)
954954

955+
/// createTask<T>(flags: Int,
956+
/// taskGroup: Builtin.RawPointer? = nil,
957+
/// initialTaskExecutor: (Builtin.Executor)? = nil,
958+
/// initialExecutor: (Builtin.Executor)? = nil,
959+
/// operation: @escaping () async throws -> T)
960+
/// -> Builtin.NativeObject, Builtin.RawPointer)
961+
///
962+
/// Create a new task.
963+
BUILTIN_SIL_OPERATION(CreateTask, "createTask", Special)
964+
965+
/// createDiscardingTask(flags: Int,
966+
/// taskGroup: Builtin.RawPointer? = nil,
967+
/// initialTaskExecutor: (Builtin.Executor)? = nil,
968+
/// initialExecutor: (Builtin.Executor)? = nil,
969+
/// operation: @escaping () async throws -> ())
970+
/// -> (Builtin.NativeObject, Builtin.RawPointer)
971+
///
972+
/// Create a new discarding task.
973+
BUILTIN_SIL_OPERATION(CreateDiscardingTask, "createDiscardingTask", Special)
974+
955975
/// createAsyncTask(): (
956976
/// Int, // task-creation flags
957977
/// @escaping () async throws -> T // function
958978
/// ) -> Builtin.NativeObject
959979
///
960-
/// Create a new asynchronous task, given flags, options, and a function to
961-
/// execute.
980+
/// Legacy spelling of:
981+
/// createTask(flags: $0, operation: $1)
962982
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
963983
"createAsyncTask", "", Special)
964984

@@ -968,8 +988,8 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
968988
/// @escaping () async throws -> T // function
969989
/// ) -> Builtin.NativeObject
970990
///
971-
/// Create a new asynchronous task future, given flags, a parent task,
972-
/// task group and a function to execute.
991+
/// Legacy spelling of:
992+
/// createTask(flags: $0, taskGroup: $1, operation: $2)
973993
BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroup,
974994
"createAsyncTaskInGroup", Special)
975995

@@ -979,8 +999,8 @@ BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroup,
979999
/// @escaping () async throws -> Void // function
9801000
/// ) -> Builtin.NativeObject
9811001
///
982-
/// Create a new asynchronous discarding task, given flags, a parent task,
983-
/// task group and a function to execute.
1002+
/// Legacy spelling of:
1003+
/// createDiscardingTask(flags: $0, taskGroup: $1, operation: $2)
9841004
BUILTIN_SIL_OPERATION(CreateAsyncDiscardingTaskInGroup,
9851005
"createAsyncDiscardingTaskInGroup", Special)
9861006

@@ -990,8 +1010,8 @@ BUILTIN_SIL_OPERATION(CreateAsyncDiscardingTaskInGroup,
9901010
/// @escaping () async throws -> T // function
9911011
/// ) -> Builtin.NativeObject
9921012
///
993-
/// Create a new asynchronous task future, given flags, a parent task,
994-
/// task group and a function to execute.
1013+
/// Legacy spelling of:
1014+
/// createTask(flags: $0, initialTaskExecutor: $1, operation: $2)
9951015
BUILTIN_SIL_OPERATION(CreateAsyncTaskWithExecutor,
9961016
"createAsyncTaskWithExecutor", Special)
9971017

@@ -1002,8 +1022,8 @@ BUILTIN_SIL_OPERATION(CreateAsyncTaskWithExecutor,
10021022
/// @escaping () async throws -> T // function
10031023
/// ) -> Builtin.NativeObject
10041024
///
1005-
/// Create a new asynchronous task future, given flags, a parent task,
1006-
/// task group and a function to execute.
1025+
/// Legacy spelling of:
1026+
/// createTask(flags: $0, taskGroup: $1, initialTaskExecutor: $2, operation: $3)
10071027
BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroupWithExecutor,
10081028
"createAsyncTaskInGroupWithExecutor", Special)
10091029

@@ -1014,8 +1034,9 @@ BUILTIN_SIL_OPERATION(CreateAsyncTaskInGroupWithExecutor,
10141034
/// @escaping () async throws -> Void // function
10151035
/// ) -> Builtin.NativeObject
10161036
///
1017-
/// Create a new asynchronous discarding task, given flags, a parent task,
1018-
/// task group and a function to execute.
1037+
/// Legacy spelling of:
1038+
/// createDiscardingTask(flags: $0, taskGroup: $1, initialTaskExecutor: $2,
1039+
/// operation: $3)
10191040
BUILTIN_SIL_OPERATION(CreateAsyncDiscardingTaskInGroupWithExecutor,
10201041
"createAsyncDiscardingTaskInGroupWithExecutor", Special)
10211042

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ LANGUAGE_FEATURE(OptionalIsolatedParameters, 420, "Optional isolated parameters"
168168
SUPPRESSIBLE_LANGUAGE_FEATURE(Extern, 0, "@_extern")
169169
LANGUAGE_FEATURE(ExpressionMacroDefaultArguments, 422, "Expression macro as caller-side default argument")
170170
LANGUAGE_FEATURE(BuiltinStoreRaw, 0, "Builtin.storeRaw")
171+
LANGUAGE_FEATURE(BuiltinCreateTask, 0, "Builtin.createTask and Builtin.createDiscardingTask")
171172

172173
// Swift 6
173174
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)

lib/AST/Builtins.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,32 @@ Type swift::getAsyncTaskAndContextType(ASTContext &ctx) {
15101510
return TupleType::get(resultTupleElements, ctx);
15111511
}
15121512

1513+
static ValueDecl *getCreateTask(ASTContext &ctx, Identifier id) {
1514+
return getBuiltinFunction(
1515+
ctx, id, _thin, _generics(_unrestricted, _conformsToDefaults(0)),
1516+
_parameters(
1517+
_label("flags", _swiftInt),
1518+
_label("taskGroup", _defaulted(_optional(_rawPointer), _nil)),
1519+
//_label("initialExecutor", _defaulted(_optional(_executor), _nil)),
1520+
_label("initialTaskExecutor", _defaulted(_optional(_executor), _nil)),
1521+
_label("operation", _function(_async(_throws(_sendable(_thick))),
1522+
_typeparam(0), _parameters()))),
1523+
_tuple(_nativeObject, _rawPointer));
1524+
}
1525+
1526+
static ValueDecl *getCreateDiscardingTask(ASTContext &ctx, Identifier id) {
1527+
return getBuiltinFunction(
1528+
ctx, id, _thin,
1529+
_parameters(
1530+
_label("flags", _swiftInt),
1531+
_label("taskGroup", _defaulted(_optional(_rawPointer), _nil)),
1532+
//_label("initialExecutor", _defaulted(_optional(_executor), _nil)),
1533+
_label("initialTaskExecutor", _defaulted(_optional(_executor), _nil)),
1534+
_label("operation", _function(_async(_throws(_sendable(_thick))),
1535+
_void, _parameters()))),
1536+
_tuple(_nativeObject, _rawPointer));
1537+
}
1538+
15131539
static ValueDecl *getCreateAsyncTask(ASTContext &ctx, Identifier id,
15141540
bool inGroup, bool withTaskExecutor,
15151541
bool isDiscarding) {
@@ -3015,6 +3041,12 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
30153041
case BuiltinValueKind::CancelAsyncTask:
30163042
return getCancelAsyncTask(Context, Id);
30173043

3044+
case BuiltinValueKind::CreateTask:
3045+
return getCreateTask(Context, Id);
3046+
3047+
case BuiltinValueKind::CreateDiscardingTask:
3048+
return getCreateDiscardingTask(Context, Id);
3049+
30183050
case BuiltinValueKind::CreateAsyncTask:
30193051
return getCreateAsyncTask(Context, Id, /*inGroup=*/false,
30203052
/*withExecutor=*/false, /*isDiscarding=*/false);

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ UNINTERESTING_FEATURE(BuiltinCreateAsyncDiscardingTaskInGroup)
186186
UNINTERESTING_FEATURE(BuiltinCreateAsyncDiscardingTaskInGroupWithExecutor)
187187
UNINTERESTING_FEATURE(BuiltinUnprotectedStackAlloc)
188188
UNINTERESTING_FEATURE(BuiltinAllocVector)
189+
UNINTERESTING_FEATURE(BuiltinCreateTask)
189190

190191
static bool usesFeatureNewCxxMethodSafetyHeuristics(Decl *decl) {
191192
return decl->hasClangNode();

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,23 @@ static ManagedValue emitBuiltinCreateAsyncTask(
16991699
return emitCreateAsyncTask(SGF, loc, subs, std::move(args), {});
17001700
}
17011701

1702+
// Emit SIL for the named builtin: createTask.
1703+
static ManagedValue emitBuiltinCreateTask(
1704+
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
1705+
PreparedArguments &&args, SGFContext C) {
1706+
return emitCreateAsyncTask(SGF, loc, subs, std::move(args),
1707+
{ CreateTaskOptions::OptionalEverything });
1708+
}
1709+
1710+
// Emit SIL for the named builtin: createDiscardingTask.
1711+
static ManagedValue emitBuiltinCreateDiscardingTask(
1712+
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
1713+
PreparedArguments &&args, SGFContext C) {
1714+
return emitCreateAsyncTask(SGF, loc, subs, std::move(args),
1715+
{ CreateTaskOptions::OptionalEverything,
1716+
CreateTaskOptions::Discarding });
1717+
}
1718+
17021719
ManagedValue
17031720
SILGenFunction::emitCreateAsyncMainTask(SILLocation loc, SubstitutionMap subs,
17041721
ManagedValue flags,

test/SILGen/async_builtins.swift

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,87 @@ public struct X {
8989
}
9090
}
9191

92+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A10CreateTask5valueyx_tlF
93+
// CHECK: [[FLAGS:%.*]] = apply
94+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.none
95+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
96+
// CHECK: [[CLOSURE:%.*]] = partial_apply
97+
// CHECK-NEXT: [[CONVERTED_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> (@out T, @error any Error) to $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>
98+
// CHECK-NEXT: builtin "createAsyncTask"<T>([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CONVERTED_CLOSURE]] : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>) : $(Builtin.NativeObject, Builtin.RawPointer)
99+
func testCreateTask<T>(value: T) {
100+
_ = Builtin.createTask(flags: 0) {
101+
value
102+
}
103+
}
104+
105+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A10CreateTask5group5valueyBp_xtlF
106+
// CHECK: [[FLAGS:%.*]] = apply
107+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.some!enumelt, %0 : $Builtin.RawPointer
108+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
109+
// CHECK: [[CLOSURE:%.*]] = partial_apply
110+
// CHECK-NEXT: [[CONVERTED_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> (@out T, @error any Error) to $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>
111+
// CHECK-NEXT: builtin "createAsyncTask"<T>([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CONVERTED_CLOSURE]] : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>) : $(Builtin.NativeObject, Builtin.RawPointer)
112+
func testCreateTask<T>(group: Builtin.RawPointer, value: T) {
113+
_ = Builtin.createTask(flags: 0, taskGroup: group) {
114+
value
115+
}
116+
}
117+
118+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A10CreateTask8executor5valueyBe_xtlF
119+
// CHECK: [[FLAGS:%.*]] = apply
120+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.none
121+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.some!enumelt, %0 : $Builtin.Executor
122+
// CHECK: [[CLOSURE:%.*]] = partial_apply
123+
// CHECK-NEXT: [[CONVERTED_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> (@out T, @error any Error) to $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>
124+
// CHECK-NEXT: builtin "createAsyncTask"<T>([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CONVERTED_CLOSURE]] : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>) : $(Builtin.NativeObject, Builtin.RawPointer)
125+
func testCreateTask<T>(executor: Builtin.Executor, value: T) {
126+
_ = Builtin.createTask(flags: 0, initialTaskExecutor: executor) {
127+
value
128+
}
129+
}
130+
131+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A10CreateTask5group8executor5valueyBp_BextlF
132+
// CHECK: [[FLAGS:%.*]] = apply
133+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.some!enumelt, %0 : $Builtin.RawPointer
134+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.some!enumelt, %1 : $Builtin.Executor
135+
// CHECK: [[CLOSURE:%.*]] = partial_apply
136+
// CHECK-NEXT: [[CONVERTED_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> (@out T, @error any Error) to $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>
137+
// CHECK-NEXT: builtin "createAsyncTask"<T>([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CONVERTED_CLOSURE]] : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>) : $(Builtin.NativeObject, Builtin.RawPointer)
138+
func testCreateTask<T>(group: Builtin.RawPointer, executor: Builtin.Executor, value: T) {
139+
_ = Builtin.createTask(flags: 0, taskGroup: group, initialTaskExecutor: executor) {
140+
value
141+
}
142+
}
143+
144+
// A discarding task without a group is not currently a legal
145+
// combination; if we start enforcing that, feel free to change this
146+
// as needed.
147+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A20CreateDiscardingTask5valueyx_tlF
148+
// CHECK: [[FLAGS:%.*]] = apply
149+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.none
150+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
151+
// CHECK: [[CLOSURE:%.*]] = partial_apply
152+
// CHECK-NEXT: builtin "createAsyncTask"([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> @error any Error) : $(Builtin.NativeObject, Builtin.RawPointer)
153+
func testCreateDiscardingTask<T>(value: T) {
154+
_ = Builtin.createDiscardingTask(flags: 0) {
155+
_ = value
156+
}
157+
}
158+
159+
// A discarding task without a group is not currently a legal
160+
// combination; if we start enforcing that, feel free to change this
161+
// as needed.
162+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A20CreateDiscardingTask5group8executor5valueyBp_BextlF
163+
// CHECK: [[FLAGS:%.*]] = apply
164+
// CHECK-NEXT: [[OPT_GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.some!enumelt, %0 : $Builtin.RawPointer
165+
// CHECK-NEXT: [[OPT_TASK_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.some!enumelt, %1 : $Builtin.Executor
166+
// CHECK: [[CLOSURE:%.*]] = partial_apply
167+
// CHECK-NEXT: builtin "createAsyncTask"([[FLAGS]] : $Int, [[OPT_GROUP]] : $Optional<Builtin.RawPointer>, [[OPT_TASK_EXECUTOR]] : $Optional<Builtin.Executor>, [[CLOSURE]] : $@Sendable @async @callee_guaranteed () -> @error any Error) : $(Builtin.NativeObject, Builtin.RawPointer)
168+
func testCreateDiscardingTask<T>(group: Builtin.RawPointer, executor: Builtin.Executor, value: T) {
169+
_ = Builtin.createDiscardingTask(flags: 0, taskGroup: group, initialTaskExecutor: executor) {
170+
_ = value
171+
}
172+
}
92173
// CHECK-LABEL: sil [ossa] @$s4test26usesWithUnsafeContinuationyyYaF : $@convention(thin) @async () -> () {
93174
public func usesWithUnsafeContinuation() async {
94175
// trivial resume type

0 commit comments

Comments
 (0)