32
32
using namespace swift ;
33
33
using namespace irgen ;
34
34
35
- void OutliningMetadataCollector::collectTypeMetadataForLayout (SILType type ) {
35
+ void OutliningMetadataCollector::collectTypeMetadataForLayout (SILType ty ) {
36
36
// If the type has no archetypes, we can emit it from scratch in the callee.
37
- if (!type .hasArchetype ()) {
37
+ if (!ty .hasArchetype ()) {
38
38
return ;
39
39
}
40
40
41
41
// Substitute opaque types if allowed.
42
- type =
43
- IGF.IGM .substOpaqueTypesWithUnderlyingTypes (type, CanGenericSignature ());
42
+ ty = IGF.IGM .substOpaqueTypesWithUnderlyingTypes (ty, CanGenericSignature ());
44
43
45
- auto formalType = type.getASTType ();
46
- auto &ti = IGF.IGM .getTypeInfoForLowered (formalType);
44
+ auto astType = ty.getASTType ();
45
+ auto &ti = IGF.IGM .getTypeInfoForLowered (astType);
46
+
47
+ if (needsDeinit) {
48
+ auto *nominal = ty.getASTType ()->getAnyNominal ();
49
+ if (nominal && nominal->getValueTypeDestructor ()) {
50
+ assert (ty.isMoveOnly ());
51
+ collectFormalTypeMetadata (ty.getASTType ());
52
+ }
53
+ }
54
+
55
+ if (!needsLayout) {
56
+ return ;
57
+ }
47
58
48
59
// We don't need the metadata for fixed size types or types that are not ABI
49
60
// accessible. Outlining will call the value witness of the enclosing type of
@@ -55,16 +66,11 @@ void OutliningMetadataCollector::collectTypeMetadataForLayout(SILType type) {
55
66
// If the type is a legal formal type, add it as a formal type.
56
67
// FIXME: does this force us to emit a more expensive metadata than we need
57
68
// to?
58
- if (formalType ->isLegalFormalType ()) {
59
- return collectFormalTypeMetadata (formalType );
69
+ if (astType ->isLegalFormalType ()) {
70
+ return collectFormalTypeMetadata (astType );
60
71
}
61
72
62
- auto key = LocalTypeDataKey (type.getASTType (),
63
- LocalTypeDataKind::forRepresentationTypeMetadata ());
64
- if (Values.count (key)) return ;
65
-
66
- auto metadata = IGF.emitTypeMetadataRefForLayout (type);
67
- Values.insert ({key, metadata});
73
+ collectRepresentationTypeMetadata (ty);
68
74
}
69
75
70
76
void OutliningMetadataCollector::collectFormalTypeMetadata (CanType type) {
@@ -78,6 +84,15 @@ void OutliningMetadataCollector::collectFormalTypeMetadata(CanType type) {
78
84
Values.insert ({key, metadata});
79
85
}
80
86
87
+ void OutliningMetadataCollector::collectRepresentationTypeMetadata (SILType ty) {
88
+ auto key = LocalTypeDataKey (
89
+ ty.getASTType (), LocalTypeDataKind::forRepresentationTypeMetadata ());
90
+ if (Values.count (key))
91
+ return ;
92
+
93
+ auto metadata = IGF.emitTypeMetadataRefForLayout (ty);
94
+ Values.insert ({key, metadata});
95
+ }
81
96
82
97
void OutliningMetadataCollector::addMetadataArguments (
83
98
SmallVectorImpl<llvm::Value*> &args) const {
@@ -136,11 +151,12 @@ irgen::getTypeAndGenericSignatureForManglingOutlineFunction(SILType type) {
136
151
}
137
152
138
153
bool TypeInfo::withMetadataCollector (
139
- IRGenFunction &IGF, SILType T,
154
+ IRGenFunction &IGF, SILType T, LayoutIsNeeded_t needsLayout,
155
+ DeinitIsNeeded_t needsDeinit,
140
156
llvm::function_ref<void (OutliningMetadataCollector &)> invocation) const {
141
157
if (!T.hasLocalArchetype () &&
142
158
!IGF.outliningCanCallValueWitnesses ()) {
143
- OutliningMetadataCollector collector (IGF);
159
+ OutliningMetadataCollector collector (IGF, needsLayout, needsDeinit );
144
160
if (T.hasArchetype ()) {
145
161
collectMetadataForOutlining (collector, T);
146
162
}
@@ -150,7 +166,7 @@ bool TypeInfo::withMetadataCollector(
150
166
151
167
if (!T.hasArchetype ()) {
152
168
// The implementation will call vwt in this case.
153
- OutliningMetadataCollector collector (IGF);
169
+ OutliningMetadataCollector collector (IGF, needsLayout, needsDeinit );
154
170
invocation (collector);
155
171
return true ;
156
172
}
@@ -161,9 +177,11 @@ bool TypeInfo::withMetadataCollector(
161
177
void TypeInfo::callOutlinedCopy (IRGenFunction &IGF, Address dest, Address src,
162
178
SILType T, IsInitialization_t isInit,
163
179
IsTake_t isTake) const {
164
- if (withMetadataCollector (IGF, T, [&](auto collector) {
165
- collector.emitCallToOutlinedCopy (dest, src, T, *this , isInit, isTake);
166
- })) {
180
+ if (withMetadataCollector (IGF, T, LayoutIsNeeded, DeinitIsNotNeeded,
181
+ [&](auto collector) {
182
+ collector.emitCallToOutlinedCopy (
183
+ dest, src, T, *this , isInit, isTake);
184
+ })) {
167
185
return ;
168
186
}
169
187
@@ -183,6 +201,8 @@ void OutliningMetadataCollector::emitCallToOutlinedCopy(
183
201
Address dest, Address src,
184
202
SILType T, const TypeInfo &ti,
185
203
IsInitialization_t isInit, IsTake_t isTake) const {
204
+ assert (needsLayout);
205
+ assert (!needsDeinit);
186
206
llvm::SmallVector<llvm::Value *, 4 > args;
187
207
args.push_back (IGF.Builder .CreateElementBitCast (src, ti.getStorageType ())
188
208
.getAddress ());
@@ -356,9 +376,10 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
356
376
if (IGF.IGM .getTypeLowering (T).isTrivial ())
357
377
return ;
358
378
359
- if (withMetadataCollector (IGF, T, [&](auto collector) {
360
- collector.emitCallToOutlinedDestroy (addr, T, *this );
361
- })) {
379
+ if (withMetadataCollector (
380
+ IGF, T, LayoutIsNeeded, DeinitIsNeeded, [&](auto collector) {
381
+ collector.emitCallToOutlinedDestroy (addr, T, *this );
382
+ })) {
362
383
return ;
363
384
}
364
385
@@ -367,6 +388,8 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
367
388
368
389
void OutliningMetadataCollector::emitCallToOutlinedDestroy (
369
390
Address addr, SILType T, const TypeInfo &ti) const {
391
+ assert (needsLayout);
392
+ assert (needsDeinit);
370
393
llvm::SmallVector<llvm::Value *, 4 > args;
371
394
args.push_back (IGF.Builder .CreateElementBitCast (addr, ti.getStorageType ())
372
395
.getAddress ());
@@ -439,24 +462,46 @@ llvm::Constant *IRGenModule::getOrCreateRetainFunction(const TypeInfo &ti,
439
462
true /* setIsNoInline*/ );
440
463
}
441
464
442
- llvm::Constant *
443
- IRGenModule::getOrCreateReleaseFunction (const TypeInfo &ti,
444
- SILType t,
445
- llvm::Type *llvmType,
446
- Atomicity atomicity) {
465
+ void TypeInfo::callOutlinedRelease (IRGenFunction &IGF, Address addr, SILType T,
466
+ Atomicity atomicity) const {
467
+ OutliningMetadataCollector collector (IGF, LayoutIsNotNeeded, DeinitIsNeeded);
468
+ collectMetadataForOutlining (collector, T);
469
+ collector.emitCallToOutlinedRelease (addr, T, *this , atomicity);
470
+ }
471
+
472
+ void OutliningMetadataCollector::emitCallToOutlinedRelease (
473
+ Address addr, SILType T, const TypeInfo &ti, Atomicity atomicity) const {
474
+ assert (!needsLayout);
475
+ assert (needsDeinit);
476
+ llvm::SmallVector<llvm::Value *, 4 > args;
477
+ args.push_back (addr.getAddress ());
478
+ addMetadataArguments (args);
479
+ auto *outlinedF = cast<llvm::Function>(IGF.IGM .getOrCreateReleaseFunction (
480
+ ti, T, addr.getAddress ()->getType (), atomicity, *this ));
481
+ llvm::CallInst *call =
482
+ IGF.Builder .CreateCall (outlinedF->getFunctionType (), outlinedF, args);
483
+ call->setCallingConv (IGF.IGM .DefaultCC );
484
+ }
485
+
486
+ llvm::Constant *IRGenModule::getOrCreateReleaseFunction (
487
+ const TypeInfo &ti, SILType t, llvm::Type *ptrTy, Atomicity atomicity,
488
+ const OutliningMetadataCollector &collector) {
447
489
auto *loadableTI = cast<LoadableTypeInfo>(&ti);
448
490
IRGenMangler mangler;
449
491
auto manglingBits =
450
492
getTypeAndGenericSignatureForManglingOutlineFunction (t);
451
493
auto funcName = mangler.mangleOutlinedReleaseFunction (manglingBits.first ,
452
494
manglingBits.second );
453
- llvm::Type *argTys[] = {llvmType};
495
+ llvm::SmallVector<llvm::Type *, 4 > argTys;
496
+ argTys.push_back (ptrTy);
497
+ collector.addMetadataParameterTypes (argTys);
454
498
return getOrCreateHelperFunction (
455
- funcName, llvmType , argTys,
499
+ funcName, ptrTy , argTys,
456
500
[&](IRGenFunction &IGF) {
457
- auto it = IGF.CurFn -> arg_begin ();
458
- Address addr (&*it++ , loadableTI->getStorageType (),
501
+ Explosion params = IGF.collectParameters ();
502
+ Address addr (params. claimNext () , loadableTI->getStorageType (),
459
503
loadableTI->getFixedAlignment ());
504
+ collector.bindMetadataParameters (IGF, params);
460
505
Explosion loaded;
461
506
loadableTI->loadAsTake (IGF, addr, loaded);
462
507
loadableTI->consume (IGF, loaded, atomicity, t);
0 commit comments