mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[embedded] Introduce a new swift_taskGroup_initializeWithOptions runtime entrypoint
This commit is contained in:
@@ -2792,10 +2792,6 @@ public:
|
||||
/// Request the TaskGroup to immediately release completed tasks,
|
||||
/// and not store their results. This also effectively disables `next()`.
|
||||
TaskGroup_DiscardResults = 8,
|
||||
/// The `Metadata *T` in swift_taskGroup_initialize and in
|
||||
/// swift_taskGroup_initializeWithFlags pointer is actually a
|
||||
/// TaskOptionRecord pointer. Used only in Embedded Swift.
|
||||
TaskGroup_MetadataAsOptionRecord = 9,
|
||||
};
|
||||
|
||||
explicit TaskGroupFlags(uint32_t bits) : FlagSet(bits) {}
|
||||
@@ -2804,10 +2800,6 @@ public:
|
||||
FLAGSET_DEFINE_FLAG_ACCESSORS(TaskGroup_DiscardResults,
|
||||
isDiscardResults,
|
||||
setIsDiscardResults)
|
||||
|
||||
FLAGSET_DEFINE_FLAG_ACCESSORS(TaskGroup_MetadataAsOptionRecord,
|
||||
isMetadataAsOptionRecord,
|
||||
setIsMetadataAsOptionRecord)
|
||||
};
|
||||
|
||||
/// Flags for cancellation records.
|
||||
|
||||
@@ -215,6 +215,17 @@ void swift_taskGroup_initialize(TaskGroup *group, const Metadata *T);
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||
void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group, const Metadata *T);
|
||||
|
||||
/// Initialize a `TaskGroup` in the passed `group` memory location.
|
||||
/// The caller is responsible for retaining and managing the group's lifecycle.
|
||||
///
|
||||
/// Its Swift signature is
|
||||
///
|
||||
/// \code
|
||||
/// func swift_taskGroup_initialize(flags: Int, group: Builtin.RawPointer)
|
||||
/// \endcode
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||
void swift_taskGroup_initializeWithOptions(size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options);
|
||||
|
||||
/// Attach a child task to the parent task's task group record.
|
||||
///
|
||||
/// This function MUST be called from the AsyncTask running the task group.
|
||||
|
||||
@@ -2555,7 +2555,7 @@ FUNCTION(TaskRunInline,
|
||||
EFFECT(NoEffect),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void swift_taskGroup_initialize(TaskGroup *group);
|
||||
// void swift_taskGroup_initialize(TaskGroup *group, const Metadata *T);
|
||||
FUNCTION(TaskGroupInitialize,
|
||||
swift_taskGroup_initialize, SwiftCC,
|
||||
ConcurrencyAvailability,
|
||||
@@ -2565,7 +2565,7 @@ FUNCTION(TaskGroupInitialize,
|
||||
EFFECT(Concurrency),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group);
|
||||
// void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group, const Metadata *T);
|
||||
FUNCTION(TaskGroupInitializeWithFlags,
|
||||
swift_taskGroup_initializeWithFlags, SwiftCC,
|
||||
ConcurrencyDiscardingTaskGroupAvailability,
|
||||
@@ -2578,6 +2578,20 @@ FUNCTION(TaskGroupInitializeWithFlags,
|
||||
EFFECT(Concurrency),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void swift_taskGroup_initializeWithTaskOptions(size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options);
|
||||
FUNCTION(TaskGroupInitializeWithOptions,
|
||||
swift_taskGroup_initializeWithOptions, SwiftCC,
|
||||
ConcurrencyDiscardingTaskGroupAvailability,
|
||||
RETURNS(VoidTy),
|
||||
ARGS(SizeTy, // flags
|
||||
Int8PtrTy, // group
|
||||
TypeMetadataPtrTy, // T.Type
|
||||
SwiftTaskOptionRecordPtrTy // options
|
||||
),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Concurrency),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void swift_taskGroup_destroy(TaskGroup *group);
|
||||
FUNCTION(TaskGroupDestroy,
|
||||
swift_taskGroup_destroy, SwiftCC,
|
||||
|
||||
@@ -336,38 +336,30 @@ llvm::Value *irgen::emitCreateTaskGroup(IRGenFunction &IGF,
|
||||
"createTaskGroup should have a type substitution");
|
||||
auto resultType = subs.getReplacementTypes()[0]->getCanonicalType();
|
||||
|
||||
// In desktop Swift, we pass a Metadata pointer as the last argument. In
|
||||
// Embedded Swift, we pass a TaskOptionRecord list, and mark a bit in
|
||||
// groupFlags.
|
||||
llvm::Value *metadataOrTypeOptionRecord;
|
||||
if (IGF.IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
|
||||
metadataOrTypeOptionRecord =
|
||||
llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||
metadataOrTypeOptionRecord = maybeAddEmbeddedSwiftResultTypeInfo(
|
||||
IGF, metadataOrTypeOptionRecord, resultType);
|
||||
llvm::IntegerType *IntPtrTy = IGF.IGM.IntPtrTy;
|
||||
TaskGroupFlags taskgroupFlags(0);
|
||||
taskgroupFlags.setIsMetadataAsOptionRecord(true);
|
||||
auto flagValue = llvm::ConstantInt::get(IGF.IGM.IntPtrTy,
|
||||
taskgroupFlags.getOpaqueValue());
|
||||
if (!groupFlags) {
|
||||
groupFlags = flagValue;
|
||||
} else {
|
||||
groupFlags = IGF.Builder.CreateOr(groupFlags, flagValue);
|
||||
}
|
||||
} else {
|
||||
metadataOrTypeOptionRecord = IGF.emitAbstractTypeMetadataRef(resultType);
|
||||
// In Embedded Swift, call swift_taskGroup_initializeWithOptions instead, to
|
||||
// avoid needing a Metadata argument.
|
||||
llvm::Value *options = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||
llvm::Value *resultTypeMetadata = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||
options = maybeAddEmbeddedSwiftResultTypeInfo(IGF, options, resultType);
|
||||
if (!groupFlags) groupFlags = llvm::ConstantInt::get(IGF.IGM.SizeTy, 0);
|
||||
llvm::CallInst *call = IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeWithOptionsFunctionPointer(),
|
||||
{groupFlags, group, resultTypeMetadata, options});
|
||||
call->setDoesNotThrow();
|
||||
call->setCallingConv(IGF.IGM.SwiftCC);
|
||||
return group;
|
||||
}
|
||||
|
||||
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
|
||||
|
||||
llvm::CallInst *call;
|
||||
if (groupFlags) {
|
||||
call = IGF.Builder.CreateCall(
|
||||
IGF.IGM.getTaskGroupInitializeWithFlagsFunctionPointer(),
|
||||
{groupFlags, group, metadataOrTypeOptionRecord});
|
||||
call = IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeWithFlagsFunctionPointer(),
|
||||
{groupFlags, group, resultTypeMetadata});
|
||||
} else {
|
||||
call =
|
||||
IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeFunctionPointer(),
|
||||
{group, metadataOrTypeOptionRecord});
|
||||
{group, resultTypeMetadata});
|
||||
}
|
||||
call->setDoesNotThrow();
|
||||
call->setCallingConv(IGF.IGM.SwiftCC);
|
||||
|
||||
@@ -300,6 +300,10 @@ OVERRIDE_TASK_GROUP(taskGroup_initializeWithFlags, void,
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||
swift::, (size_t flags, TaskGroup *group, const Metadata *T), (flags, group, T))
|
||||
|
||||
OVERRIDE_TASK_GROUP(taskGroup_initializeWithOptions, void,
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||
swift::, (size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options), (flags, group, T, options))
|
||||
|
||||
OVERRIDE_TASK_STATUS(taskGroup_attachChild, void,
|
||||
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||
swift::, (TaskGroup *group, AsyncTask *child),
|
||||
|
||||
@@ -955,6 +955,8 @@ TaskGroup* TaskGroupTaskStatusRecord::getGroup() {
|
||||
// =============================================================================
|
||||
// ==== initialize -------------------------------------------------------------
|
||||
|
||||
static void _swift_taskGroup_initialize(ResultTypeInfo resultType, size_t rawGroupFlags, TaskGroup *group);
|
||||
|
||||
// Initializes into the preallocated _group an actual TaskGroupBase.
|
||||
SWIFT_CC(swift)
|
||||
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
|
||||
@@ -965,21 +967,27 @@ static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T)
|
||||
SWIFT_CC(swift)
|
||||
static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
|
||||
TaskGroup *group, const Metadata *T) {
|
||||
TaskGroupFlags groupFlags(rawGroupFlags);
|
||||
SWIFT_TASK_GROUP_DEBUG_LOG_0(group, "create group, from task:%p; flags: isDiscardingResults=%d",
|
||||
swift_task_getCurrent(),
|
||||
groupFlags.isDiscardResults());
|
||||
|
||||
ResultTypeInfo resultType;
|
||||
#if !SWIFT_CONCURRENCY_EMBEDDED
|
||||
resultType.metadata = T;
|
||||
assert(!groupFlags.isMetadataAsOptionRecord());
|
||||
#else
|
||||
assert(groupFlags.isMetadataAsOptionRecord());
|
||||
TaskOptionRecord *options = (TaskOptionRecord *)T;
|
||||
swift_unreachable("swift_taskGroup_initializeWithFlags in embedded");
|
||||
#endif
|
||||
_swift_taskGroup_initialize(resultType, rawGroupFlags, group);
|
||||
}
|
||||
|
||||
// Initializes into the preallocated _group an actual instance.
|
||||
SWIFT_CC(swift)
|
||||
static void swift_taskGroup_initializeWithOptionsImpl(size_t rawGroupFlags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options) {
|
||||
ResultTypeInfo resultType;
|
||||
#if !SWIFT_CONCURRENCY_EMBEDDED
|
||||
resultType.metadata = T;
|
||||
#endif
|
||||
|
||||
for (auto option = options; option; option = option->getParent()) {
|
||||
switch (option->getKind()) {
|
||||
case TaskOptionRecordKind::ResultTypeInfo: {
|
||||
#if SWIFT_CONCURRENCY_EMBEDDED
|
||||
auto *typeInfo = cast<ResultTypeInfoTaskOptionRecord>(option);
|
||||
resultType = {
|
||||
.size = typeInfo->size,
|
||||
@@ -988,13 +996,26 @@ static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
|
||||
.storeEnumTagSinglePayload = typeInfo->storeEnumTagSinglePayload,
|
||||
.destroy = typeInfo->destroy,
|
||||
};
|
||||
#else
|
||||
swift_unreachable("ResultTypeInfo in non embedded");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
swift_unreachable("only ResultTypeInfo expected");
|
||||
break; // ignore unknown records
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(!resultType.isNull());
|
||||
|
||||
_swift_taskGroup_initialize(resultType, rawGroupFlags, group);
|
||||
}
|
||||
|
||||
static void _swift_taskGroup_initialize(ResultTypeInfo resultType, size_t rawGroupFlags, TaskGroup *group) {
|
||||
TaskGroupFlags groupFlags(rawGroupFlags);
|
||||
SWIFT_TASK_GROUP_DEBUG_LOG_0(group, "create group, from task:%p; flags: isDiscardingResults=%d",
|
||||
swift_task_getCurrent(),
|
||||
groupFlags.isDiscardResults());
|
||||
|
||||
TaskGroupBase *impl;
|
||||
if (groupFlags.isDiscardResults()) {
|
||||
|
||||
Reference in New Issue
Block a user