mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #84248 from rjmccall/complete-metadata-for-concurrency-builtins-6.2.1
[6.2.1] Fix IRGen to pass complete metadata to various concurrency builtins
This commit is contained in:
@@ -249,7 +249,7 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF,
|
||||
llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||
if (!IGF.IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
|
||||
futureResultTypeMetadata =
|
||||
IGF.emitAbstractTypeMetadataRef(futureResultType);
|
||||
IGF.emitTypeMetadataRef(futureResultType);
|
||||
}
|
||||
|
||||
// The concurrency runtime for older Apple OSes has a bug in task formation
|
||||
@@ -352,7 +352,7 @@ llvm::Value *irgen::emitCreateTaskGroup(IRGenFunction &IGF,
|
||||
return group;
|
||||
}
|
||||
|
||||
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
|
||||
auto resultTypeMetadata = IGF.emitTypeMetadataRef(resultType);
|
||||
|
||||
llvm::CallInst *call;
|
||||
if (groupFlags) {
|
||||
@@ -416,7 +416,7 @@ void irgen::emitTaskRunInline(IRGenFunction &IGF, SubstitutionMap subs,
|
||||
assert(subs.getReplacementTypes().size() == 1 &&
|
||||
"taskRunInline should have a type substitution");
|
||||
auto resultType = subs.getReplacementTypes()[0]->getCanonicalType();
|
||||
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
|
||||
auto resultTypeMetadata = IGF.emitTypeMetadataRef(resultType);
|
||||
|
||||
auto *call = IGF.Builder.CreateCall(
|
||||
IGF.IGM.getTaskRunInlineFunctionPointer(),
|
||||
|
||||
@@ -6771,7 +6771,8 @@ namespace {
|
||||
return;
|
||||
}
|
||||
|
||||
// Emit a reference to the superclass.
|
||||
// Emit a reference to the superclass. This should be abstract for now,
|
||||
// but transitively completing the class will complete it.
|
||||
auto superclass = IGF.emitAbstractTypeMetadataRef(
|
||||
getSuperclassForMetadata(IGM, Target));
|
||||
|
||||
|
||||
@@ -1281,6 +1281,9 @@ static llvm::Value *emitWitnessTableAccessorCall(
|
||||
|
||||
// Emit the source metadata if we haven't yet.
|
||||
if (!*srcMetadataCache) {
|
||||
// Witness table accesses only require abstract type metadata; this
|
||||
// is so that we can create the witness tables without introducing
|
||||
// cycle problems.
|
||||
*srcMetadataCache = IGF.emitAbstractTypeMetadataRef(conformingType);
|
||||
}
|
||||
|
||||
@@ -3460,6 +3463,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
|
||||
return MetadataResponse::forComplete(associatedWTable);
|
||||
}
|
||||
|
||||
// Witness table lookups only require abstract metadata.
|
||||
auto *sourceMetadata =
|
||||
IGF.emitAbstractTypeMetadataRef(sourceType);
|
||||
|
||||
@@ -3526,6 +3530,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
|
||||
associatedMetadata = response.getMetadata();
|
||||
} else {
|
||||
// Ok, fall back to realizing the (possibly concrete) type.
|
||||
// Witness table lookups only require abstract metadata.
|
||||
associatedMetadata =
|
||||
IGF.emitAbstractTypeMetadataRef(sourceKey.Type);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ import Builtin
|
||||
import Swift
|
||||
import _Concurrency
|
||||
|
||||
struct Pair<T> {
|
||||
var value: (T, T)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @get_task(ptr swiftasync %0)
|
||||
sil hidden [ossa] @get_task : $@async @convention(thin) () -> @owned Builtin.NativeObject {
|
||||
bb0:
|
||||
@@ -241,6 +245,33 @@ bb0(%0 : @owned $Error, %1 : $Builtin.RawUnsafeContinuation):
|
||||
return %21 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}} void @async_let_generic(
|
||||
sil public @async_let_generic : $@convention(thin) @async <T> () -> @out Pair<T> {
|
||||
bb0(%out : $*Pair<T>):
|
||||
%1 = function_ref @async_let_generic_helper : $@convention(thin) @Sendable @async <τ_0_0> () -> (@out Pair<τ_0_0>, @error any Error)
|
||||
%2 = thin_to_thick_function %1 to $@Sendable @async <τ_0_0> () -> (@out Pair<τ_0_0>, @error any Error)
|
||||
%fn = convert_function %2 to $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Pair<T>>
|
||||
%outPtr = address_to_pointer %out to $Builtin.RawPointer
|
||||
%scratch = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
|
||||
|
||||
// We've set up a function that has no reason to request type metadata
|
||||
// for Pair<T> except to pass it to swift_asyncLet_begin. Make sure that we
|
||||
// request complete metadata.
|
||||
|
||||
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
|
||||
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||
// CHECK-NEXT: call swiftcc void @swift_asyncLet_begin({{.*}}, ptr [[METADATA]], {{.*}})
|
||||
%asyncLet = builtin "startAsyncLetWithLocalBuffer"<Pair<T>>(%scratch, %fn, %outPtr) : $Builtin.RawPointer
|
||||
%t1 = builtin "endAsyncLetLifetime"(%asyncLet, %fn) : $()
|
||||
%result = tuple ()
|
||||
return %result
|
||||
}
|
||||
|
||||
sil private @async_let_generic_helper : $@convention(thin) @Sendable @async <T> () -> (@out Pair<T>, @error any Error) {
|
||||
bb0(%out : $*Pair<T>):
|
||||
unreachable
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @task_group_create_destroy
|
||||
sil hidden [ossa] @task_group_create_destroy : $@async () -> () {
|
||||
bb0:
|
||||
@@ -258,6 +289,31 @@ bb0:
|
||||
return %21 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @task_group_create_destroy_generic
|
||||
sil hidden [ossa] @task_group_create_destroy_generic : $@async <T> () -> () {
|
||||
bb0:
|
||||
// CHECK: [[TASKGROUP:%.*]] = alloca [32 x ptr], align 16
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 -1, ptr [[TASKGROUP]])
|
||||
|
||||
// We've set up a function that has no reason to request type metadata
|
||||
// for Pair<T> except to pass it to swift_taskGroup_initialize. Make sure
|
||||
// that we request complete metadata.
|
||||
|
||||
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
|
||||
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||
|
||||
// CHECK-NEXT: call swiftcc void @swift_taskGroup_initialize(ptr [[TASKGROUP]], ptr [[METADATA]])
|
||||
|
||||
%0 = metatype $@thin Pair<T>.Type
|
||||
%1 = builtin "createTaskGroup"<Pair<T>>(%0: $@thin Pair<T>.Type) : $Builtin.RawPointer
|
||||
|
||||
// CHECK-NEXT: call swiftcc void @swift_taskGroup_destroy(ptr [[TASKGROUP]])
|
||||
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[TASKGROUP]])
|
||||
builtin "destroyTaskGroup"(%1 : $Builtin.RawPointer) : $()
|
||||
|
||||
%21 = tuple ()
|
||||
return %21 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} swiftcc void @testRunInline(
|
||||
// CHECK-SAME: ptr noalias sret(%swift.opaque) [[RESULT:%[^,]+]],
|
||||
@@ -276,3 +332,25 @@ entry(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substitute
|
||||
%void = builtin "taskRunInline"<T>(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <T>) : $()
|
||||
return %void : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} swiftcc void @testRunInlineGeneric(
|
||||
// CHECK-SAME: ptr noalias sret(%swift.opaque) [[RESULT:%[^,]+]],
|
||||
// CHECK-SAME: ptr [[CLOSURE:%[^,]+]],
|
||||
// CHECK-SAME: ptr [[CLOSURE_CONTEXT:%[^,]+]],
|
||||
// CHECK-SAME: ptr %T
|
||||
// CHECK-SAME: {
|
||||
|
||||
// Make sure we request complete metadata.
|
||||
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
|
||||
// CHECK-NEXT: [[FUTURE_RESULT_TYPE:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
|
||||
// CHECK: call swiftcc void @swift_task_run_inline(
|
||||
// CHECK-SAME: ptr [[RESULT]],
|
||||
// CHECK-SAME: ptr [[CLOSURE]],
|
||||
// CHECK-SAME: ptr [[CLOSURE_CONTEXT]],
|
||||
// CHECK-SAME: ptr [[FUTURE_RESULT_TYPE]])
|
||||
// CHECK: }
|
||||
sil hidden @testRunInlineGeneric : $@convention(thin) <T> (@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>) -> @out T {
|
||||
entry(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>):
|
||||
%void = builtin "taskRunInline"<Pair<T>>(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>) : $()
|
||||
return %void : $()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user