Skip to content

Commit 51e2fdf

Browse files
authored
Merge pull request #37866 from aschwaighofer/change_async_task_wait_abi_5.5
[5.5] Change _wait(_throwing) ABIs to reduce code size
2 parents 7a8dfa9 + 02cfda9 commit 51e2fdf

27 files changed

+350
-295
lines changed

include/swift/ABI/Executor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ using TaskContinuationFunction =
128128
SWIFT_CC(swiftasync)
129129
void (SWIFT_ASYNC_CONTEXT AsyncContext *);
130130

131+
using ThrowingTaskFutureWaitContinuationFunction =
132+
SWIFT_CC(swiftasync)
133+
void (SWIFT_ASYNC_CONTEXT AsyncContext *, SWIFT_CONTEXT void *);
134+
135+
131136
template <class AsyncSignature>
132137
class AsyncFunctionPointer;
133138
template <class AsyncSignature>

include/swift/ABI/Task.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,13 @@ class AsyncTask : public Job {
481481
/// \c Executing, then \c waitingTask has been added to the
482482
/// wait queue and will be scheduled when the future completes. Otherwise,
483483
/// the future has completed and can be queried.
484-
FutureFragment::Status waitFuture(AsyncTask *waitingTask);
484+
/// The waiting task's async context will be intialized with the parameters if
485+
/// the current's task state is executing.
486+
FutureFragment::Status waitFuture(AsyncTask *waitingTask,
487+
AsyncContext *waitingTaskContext,
488+
TaskContinuationFunction *resumeFn,
489+
AsyncContext *callerContext,
490+
OpaqueValue *result);
485491

486492
/// Complete this future.
487493
///

include/swift/Runtime/Concurrency.h

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,6 @@ swift_task_escalate(AsyncTask *task, JobPriority newPriority);
125125
// TODO: "async let wait" and "async let destroy" would be expressed
126126
// similar to like TaskFutureWait;
127127

128-
/// This matches the ABI of a closure `<T>(Builtin.NativeObject) async -> T`
129-
using TaskFutureWaitSignature =
130-
SWIFT_CC(swiftasync)
131-
void(OpaqueValue *,
132-
SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *, Metadata *);
133-
134128
/// Wait for a non-throwing future task to complete.
135129
///
136130
/// This can be called from any thread. Its Swift signature is
@@ -141,12 +135,9 @@ using TaskFutureWaitSignature =
141135
/// \endcode
142136
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swiftasync)
143137
void swift_task_future_wait(OpaqueValue *,
144-
SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *, Metadata *);
145-
146-
using TaskFutureWaitThrowingSignature =
147-
SWIFT_CC(swiftasync)
148-
void(OpaqueValue *,
149-
SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *, Metadata *);
138+
SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *,
139+
TaskContinuationFunction *,
140+
AsyncContext *);
150141

151142
/// Wait for a potentially-throwing future task to complete.
152143
///
@@ -157,15 +148,12 @@ using TaskFutureWaitThrowingSignature =
157148
/// async throws -> Success
158149
/// \endcode
159150
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swiftasync)
160-
void swift_task_future_wait_throwing(OpaqueValue *,
161-
SWIFT_ASYNC_CONTEXT AsyncContext *,
162-
AsyncTask *, Metadata *);
163-
164-
using TaskGroupFutureWaitThrowingSignature =
165-
SWIFT_CC(swiftasync)
166-
void(OpaqueValue *,
167-
SWIFT_ASYNC_CONTEXT AsyncContext *, AsyncTask *, TaskGroup *,
168-
const Metadata *successType);
151+
void swift_task_future_wait_throwing(
152+
OpaqueValue *,
153+
SWIFT_ASYNC_CONTEXT AsyncContext *,
154+
AsyncTask *,
155+
ThrowingTaskFutureWaitContinuationFunction *,
156+
AsyncContext *);
169157

170158
/// Wait for a readyQueue of a Channel to become non empty.
171159
///
@@ -180,8 +168,9 @@ SWIFT_CC(swiftasync)
180168
SWIFT_EXPORT_FROM(swift_Concurrency)
181169
SWIFT_CC(swiftasync)
182170
void swift_taskGroup_wait_next_throwing(
183-
OpaqueValue *resultPointer, SWIFT_ASYNC_CONTEXT AsyncContext *rawContext,
184-
TaskGroup *group, const Metadata *successType);
171+
OpaqueValue *resultPointer, SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
172+
TaskGroup *group, ThrowingTaskFutureWaitContinuationFunction *resumeFn,
173+
AsyncContext *callContext);
185174

186175
/// Initialize a `TaskGroup` in the passed `group` memory location.
187176
/// The caller is responsible for retaining and managing the group's lifecycle.
@@ -192,7 +181,7 @@ void swift_taskGroup_wait_next_throwing(
192181
/// func swift_taskGroup_initialize(group: Builtin.RawPointer)
193182
/// \endcode
194183
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
195-
void swift_taskGroup_initialize(TaskGroup *group);
184+
void swift_taskGroup_initialize(TaskGroup *group, const Metadata *T);
196185

197186
/// Attach a child task to the parent task's task group record.
198187
///
@@ -310,7 +299,8 @@ using AsyncLetWaitSignature =
310299
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swiftasync)
311300
void swift_asyncLet_wait(OpaqueValue *,
312301
SWIFT_ASYNC_CONTEXT AsyncContext *,
313-
AsyncLet *, Metadata *);
302+
AsyncLet *, TaskContinuationFunction *,
303+
AsyncContext *);
314304

315305
/// Wait for a potentially-throwing async-let to complete.
316306
///
@@ -324,7 +314,9 @@ void swift_asyncLet_wait(OpaqueValue *,
324314
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swiftasync)
325315
void swift_asyncLet_wait_throwing(OpaqueValue *,
326316
SWIFT_ASYNC_CONTEXT AsyncContext *,
327-
AsyncLet *, Metadata *);
317+
AsyncLet *,
318+
ThrowingTaskFutureWaitContinuationFunction *,
319+
AsyncContext *);
328320

329321
/// Its Swift signature is
330322
///

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1728,7 +1728,7 @@ FUNCTION(TaskGroupInitialize,
17281728
swift_taskGroup_initialize, SwiftCC,
17291729
ConcurrencyAvailability,
17301730
RETURNS(VoidTy),
1731-
ARGS(Int8PtrTy),
1731+
ARGS(Int8PtrTy, TypeMetadataPtrTy),
17321732
ATTRS(NoUnwind))
17331733

17341734
// void swift_taskGroup_destroy(TaskGroup *group);

lib/AST/Builtins.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,8 @@ static ValueDecl *getEndAsyncLet(ASTContext &ctx, Identifier id) {
15151515

15161516
static ValueDecl *getCreateTaskGroup(ASTContext &ctx, Identifier id) {
15171517
return getBuiltinFunction(ctx, id, _thin,
1518-
_parameters(),
1518+
_generics(_unrestricted),
1519+
_parameters(_metatype(_typeparam(0))),
15191520
_rawPointer);
15201521
}
15211522

lib/IRGen/CallEmission.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ class CallEmission {
119119

120120
return result;
121121
}
122+
123+
virtual llvm::Value *getResumeFunctionPointer() = 0;
124+
virtual llvm::Value *getAsyncContext() = 0;
122125
};
123126

124127
std::unique_ptr<CallEmission>

lib/IRGen/Callee.h

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -209,24 +209,16 @@ namespace irgen {
209209
///
210210
/// This is a micro-optimization we apply to certain special functions
211211
/// that we know don't need generics.
212-
bool suppressGenerics() const {
212+
bool useSpecialConvention() const {
213213
if (!isSpecial()) return false;
214214

215215
switch (getSpecialKind()) {
216-
case SpecialKind::TaskFutureWait:
216+
case SpecialKind::AsyncLetWaitThrowing:
217217
case SpecialKind::TaskFutureWaitThrowing:
218+
case SpecialKind::TaskFutureWait:
218219
case SpecialKind::AsyncLetWait:
219-
case SpecialKind::AsyncLetWaitThrowing:
220220
case SpecialKind::TaskGroupWaitNext:
221-
// FIXME: I have disabled this optimization, if we bring it back we
222-
// need to debug why it currently does not work (call emission
223-
// computes an undef return pointer) and change the runtime entries to
224-
// remove the extra type parameter.
225-
//
226-
// We suppress generics from these as a code-size optimization
227-
// because the runtime can recover the success type from the
228-
// future.
229-
return false;
221+
return true;
230222
}
231223
}
232224

@@ -371,9 +363,7 @@ namespace irgen {
371363
return !kind.isAsyncFunctionPointer();
372364
}
373365

374-
bool suppressGenerics() const {
375-
return kind.suppressGenerics();
376-
}
366+
bool useSpecialConvention() const { return kind.useSpecialConvention(); }
377367
};
378368

379369
class Callee {
@@ -437,9 +427,7 @@ namespace irgen {
437427
return Fn.getSignature();
438428
}
439429

440-
bool suppressGenerics() const {
441-
return Fn.suppressGenerics();
442-
}
430+
bool useSpecialConvention() const { return Fn.useSpecialConvention(); }
443431

444432
/// If this callee has a value for the Swift context slot, return
445433
/// it; otherwise return non-null.
@@ -457,6 +445,7 @@ namespace irgen {
457445
llvm::Value *getObjCMethodSelector() const;
458446
};
459447

448+
FunctionPointer::Kind classifyFunctionPointerKind(SILFunction *fn);
460449
} // end namespace irgen
461450
} // end namespace swift
462451

lib/IRGen/GenBuiltin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
250250
}
251251

252252
if (Builtin.ID == BuiltinValueKind::CreateTaskGroup) {
253-
out.add(emitCreateTaskGroup(IGF));
253+
// Claim metadata pointer.
254+
(void)args.claimAll();
255+
out.add(emitCreateTaskGroup(IGF, substitutions));
254256
return;
255257
}
256258

0 commit comments

Comments
 (0)