Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb9a1e3

Browse files
committed
Fix IRGen to pass complete metadata to various concurrency builtins
Fixes rdar://146155888
1 parent f244c8f commit fb9a1e3

File tree

4 files changed

+88
-4
lines changed

4 files changed

+88
-4
lines changed

lib/IRGen/GenConcurrency.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF,
249249
llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
250250
if (!IGF.IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
251251
futureResultTypeMetadata =
252-
IGF.emitAbstractTypeMetadataRef(futureResultType);
252+
IGF.emitTypeMetadataRef(futureResultType);
253253
}
254254

255255
// The concurrency runtime for older Apple OSes has a bug in task formation
@@ -352,7 +352,7 @@ llvm::Value *irgen::emitCreateTaskGroup(IRGenFunction &IGF,
352352
return group;
353353
}
354354

355-
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
355+
auto resultTypeMetadata = IGF.emitTypeMetadataRef(resultType);
356356

357357
llvm::CallInst *call;
358358
if (groupFlags) {
@@ -416,7 +416,7 @@ void irgen::emitTaskRunInline(IRGenFunction &IGF, SubstitutionMap subs,
416416
assert(subs.getReplacementTypes().size() == 1 &&
417417
"taskRunInline should have a type substitution");
418418
auto resultType = subs.getReplacementTypes()[0]->getCanonicalType();
419-
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
419+
auto resultTypeMetadata = IGF.emitTypeMetadataRef(resultType);
420420

421421
auto *call = IGF.Builder.CreateCall(
422422
IGF.IGM.getTaskRunInlineFunctionPointer(),

lib/IRGen/GenMeta.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6775,7 +6775,8 @@ namespace {
67756775
return;
67766776
}
67776777

6778-
// Emit a reference to the superclass.
6778+
// Emit a reference to the superclass. This should be abstract for now,
6779+
// but transitively completing the class will complete it.
67796780
auto superclass = IGF.emitAbstractTypeMetadataRef(
67806781
getSuperclassForMetadata(IGM, Target));
67816782

lib/IRGen/GenProto.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,9 @@ static llvm::Value *emitWitnessTableAccessorCall(
12801280

12811281
// Emit the source metadata if we haven't yet.
12821282
if (!*srcMetadataCache) {
1283+
// Witness table accesses only require abstract type metadata; this
1284+
// is so that we can create the witness tables without introducing
1285+
// cycle problems.
12831286
*srcMetadataCache = IGF.emitAbstractTypeMetadataRef(conformingType);
12841287
}
12851288

@@ -3444,6 +3447,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
34443447
return MetadataResponse::forComplete(associatedWTable);
34453448
}
34463449

3450+
// Witness table lookups only require abstract metadata.
34473451
auto *sourceMetadata =
34483452
IGF.emitAbstractTypeMetadataRef(sourceType);
34493453

@@ -3511,6 +3515,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
35113515
associatedMetadata = response.getMetadata();
35123516
} else {
35133517
// Ok, fall back to realizing the (possibly concrete) type.
3518+
// Witness table lookups only require abstract metadata.
35143519
associatedMetadata =
35153520
IGF.emitAbstractTypeMetadataRef(sourceKey.Type);
35163521
}

test/IRGen/async/builtins.sil

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import Builtin
1010
import Swift
1111
import _Concurrency
1212

13+
struct Pair<T> {
14+
var value: (T, T)
15+
}
16+
1317
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @get_task(ptr swiftasync %0)
1418
sil hidden [ossa] @get_task : $@async @convention(thin) () -> @owned Builtin.NativeObject {
1519
bb0:
@@ -241,6 +245,33 @@ bb0(%0 : @owned $Error, %1 : $Builtin.RawUnsafeContinuation):
241245
return %21 : $()
242246
}
243247

248+
// CHECK-LABEL: define {{.*}} void @async_let_generic(
249+
sil public @async_let_generic : $@convention(thin) @async <T> () -> @out Pair<T> {
250+
bb0(%out : $*Pair<T>):
251+
%1 = function_ref @async_let_generic_helper : $@convention(thin) @Sendable @async <τ_0_0> () -> (@out Pair<τ_0_0>, @error any Error)
252+
%2 = thin_to_thick_function %1 to $@Sendable @async <τ_0_0> () -> (@out Pair<τ_0_0>, @error any Error)
253+
%fn = convert_function %2 to $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Pair<T>>
254+
%outPtr = address_to_pointer %out to $Builtin.RawPointer
255+
%scratch = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
256+
257+
// We've set up a function that has no reason to request type metadata
258+
// for Pair<T> except to pass it to swift_asyncLet_begin. Make sure that we
259+
// request complete metadata.
260+
261+
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
262+
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
263+
// CHECK-NEXT: call swiftcc void @swift_asyncLet_begin({{.*}}, ptr [[METADATA]], {{.*}})
264+
%asyncLet = builtin "startAsyncLetWithLocalBuffer"<Pair<T>>(%scratch, %fn, %outPtr) : $Builtin.RawPointer
265+
%t1 = builtin "endAsyncLetLifetime"(%asyncLet, %fn) : $()
266+
%result = tuple ()
267+
return %result
268+
}
269+
270+
sil private @async_let_generic_helper : $@convention(thin) @Sendable @async <T> () -> (@out Pair<T>, @error any Error) {
271+
bb0(%out : $*Pair<T>):
272+
unreachable
273+
}
274+
244275
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @task_group_create_destroy
245276
sil hidden [ossa] @task_group_create_destroy : $@async () -> () {
246277
bb0:
@@ -258,6 +289,31 @@ bb0:
258289
return %21 : $()
259290
}
260291

292+
// CHECK-LABEL: define hidden swift{{(tail)?}}cc void @task_group_create_destroy_generic
293+
sil hidden [ossa] @task_group_create_destroy_generic : $@async <T> () -> () {
294+
bb0:
295+
// CHECK: [[TASKGROUP:%.*]] = alloca [32 x ptr], align 16
296+
// CHECK: call void @llvm.lifetime.start.p0(i64 -1, ptr [[TASKGROUP]])
297+
298+
// We've set up a function that has no reason to request type metadata
299+
// for Pair<T> except to pass it to swift_taskGroup_initialize. Make sure
300+
// that we request complete metadata.
301+
302+
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
303+
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
304+
305+
// CHECK-NEXT: call swiftcc void @swift_taskGroup_initialize(ptr [[TASKGROUP]], ptr [[METADATA]])
306+
307+
%0 = metatype $@thin Pair<T>.Type
308+
%1 = builtin "createTaskGroup"<Pair<T>>(%0: $@thin Pair<T>.Type) : $Builtin.RawPointer
309+
310+
// CHECK-NEXT: call swiftcc void @swift_taskGroup_destroy(ptr [[TASKGROUP]])
311+
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[TASKGROUP]])
312+
builtin "destroyTaskGroup"(%1 : $Builtin.RawPointer) : $()
313+
314+
%21 = tuple ()
315+
return %21 : $()
316+
}
261317

262318
// CHECK-LABEL: define{{.*}} swiftcc void @testRunInline(
263319
// CHECK-SAME: ptr noalias sret(%swift.opaque) [[RESULT:%[^,]+]],
@@ -276,3 +332,25 @@ entry(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substitute
276332
%void = builtin "taskRunInline"<T>(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <T>) : $()
277333
return %void : $()
278334
}
335+
336+
// CHECK-LABEL: define{{.*}} swiftcc void @testRunInlineGeneric(
337+
// CHECK-SAME: ptr noalias sret(%swift.opaque) [[RESULT:%[^,]+]],
338+
// CHECK-SAME: ptr [[CLOSURE:%[^,]+]],
339+
// CHECK-SAME: ptr [[CLOSURE_CONTEXT:%[^,]+]],
340+
// CHECK-SAME: ptr %T
341+
// CHECK-SAME: {
342+
343+
// Make sure we request complete metadata.
344+
// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8builtins4PairVMa"([[INT]] 0, ptr %T)
345+
// CHECK-NEXT: [[FUTURE_RESULT_TYPE:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
346+
// CHECK: call swiftcc void @swift_task_run_inline(
347+
// CHECK-SAME: ptr [[RESULT]],
348+
// CHECK-SAME: ptr [[CLOSURE]],
349+
// CHECK-SAME: ptr [[CLOSURE_CONTEXT]],
350+
// CHECK-SAME: ptr [[FUTURE_RESULT_TYPE]])
351+
// CHECK: }
352+
sil hidden @testRunInlineGeneric : $@convention(thin) <T> (@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>) -> @out T {
353+
entry(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>):
354+
%void = builtin "taskRunInline"<Pair<T>>(%result : $*T, %closure : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Pair<T>>) : $()
355+
return %void : $()
356+
}

0 commit comments

Comments
 (0)