Skip to content

Commit 00246a2

Browse files
committed
[IRGen] Metadata collector collects generic params
When collecting the metadata required for an outlined value function, if the type on behalf of which metadata is being collected is a value type with a deinit, include the generic arguments for that value type. They will be needed by deinit which will be called within.
1 parent 42edf00 commit 00246a2

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

lib/IRGen/Outlining.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType type) {
4545
auto formalType = type.getASTType();
4646
auto &ti = IGF.IGM.getTypeInfoForLowered(formalType);
4747

48+
auto *nominal = type.getASTType()->getAnyNominal();
49+
if (nominal && nominal->getValueTypeDestructor()) {
50+
assert(type.isMoveOnly());
51+
collectTypeMetadataForEnvironment(type);
52+
}
53+
4854
// We don't need the metadata for fixed size types or types that are not ABI
4955
// accessible. Outlining will call the value witness of the enclosing type of
5056
// non ABI accessible field/element types.
@@ -67,18 +73,24 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType type) {
6773
Values.insert({key, metadata});
6874
}
6975

70-
void OutliningMetadataCollector::collectFormalTypeMetadata(CanType type) {
71-
// If the type has no archetypes, we can emit it from scratch in the callee.
72-
assert(type->hasArchetype());
76+
void OutliningMetadataCollector::collectTypeMetadataForEnvironment(SILType ty) {
77+
auto bgt = dyn_cast<BoundGenericType>(ty.getASTType());
78+
if (!bgt) {
79+
return;
80+
}
81+
for (auto arg : bgt.getGenericArgs()) {
82+
collectFormalTypeMetadata(arg);
83+
}
84+
}
7385

86+
void OutliningMetadataCollector::collectFormalTypeMetadata(CanType type) {
7487
auto key = LocalTypeDataKey(type, LocalTypeDataKind::forFormalTypeMetadata());
7588
if (Values.count(key)) return;
7689

7790
auto metadata = IGF.emitTypeMetadataRef(type);
7891
Values.insert({key, metadata});
7992
}
8093

81-
8294
void OutliningMetadataCollector::addMetadataArguments(
8395
SmallVectorImpl<llvm::Value*> &args) const {
8496
for (auto &pair : Values) {

lib/IRGen/Outlining.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class OutliningMetadataCollector {
6060

6161
void collectFormalTypeMetadata(CanType type);
6262
void collectTypeMetadataForLayout(SILType type);
63+
void collectTypeMetadataForEnvironment(SILType ty);
6364

6465
void emitCallToOutlinedCopy(Address dest, Address src,
6566
SILType T, const TypeInfo &ti,

test/IRGen/moveonly_enum_deinits.swift

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,49 @@
1-
// RUN: %target-swift-emit-irgen \
1+
// RUN: %target-swift-emit-irgen \
22
// RUN: -enable-experimental-feature NoncopyableGenerics \
3-
// RUN: %s \
4-
// RUN: | \
3+
// RUN: -disable-type-layout \
4+
// RUN: %s \
5+
// RUN: | \
56
// RUN: %FileCheck %s
67

8+
struct FIFO<T>: ~Copyable {
9+
private var data: UnsafeManualArray<T>
10+
11+
private(set) public var count: Int
12+
13+
private var head: Int
14+
15+
init(withCapacity: Int) {
16+
self.head = 0
17+
self.count = 0
18+
self.data = .init(capacity: withCapacity)
19+
}
20+
21+
deinit {
22+
}
23+
}
24+
25+
// Check that the outlined retain function has a parameter for the type's
26+
// generic parameter and that it's passed along to the deinit.
27+
// CHECK-LABEL: define{{.*}} ptr @"$s21moveonly_enum_deinits17UnsafeManualArrayVyxGlWOs"(
28+
// CHECK-SAME: ptr %0,
29+
// CHECK-SAME: ptr %T)
30+
// CHECK-SAME: {
31+
// CHECK: call swiftcc void @"$s21moveonly_enum_deinits17UnsafeManualArrayVfD"(
32+
// CHECK-SAME: ptr %T)
33+
// CHECK: }
34+
struct UnsafeManualArray<T>: ~Copyable {
35+
init(capacity: Int) {
36+
self.data = .allocate(capacity: capacity)
37+
}
38+
39+
deinit {
40+
}
41+
42+
private let data: UnsafeMutableBufferPointer<T>
43+
44+
var elementAllocated: [Bool] = []
45+
}
46+
747
// CHECK-LABEL: define{{.*}} void @"$s21moveonly_enum_deinits4ListOwxx"(
848
// CHECK-SAME: ptr noalias %object,
949
// CHECK-SAME: ptr %List)

0 commit comments

Comments
 (0)