16
16
17
17
#include " Outlining.h"
18
18
19
- #include " swift/AST/GenericEnvironment.h"
20
19
#include " Explosion.h"
20
+ #include " GenOpaque.h"
21
21
#include " GenProto.h"
22
22
#include " IRGenFunction.h"
23
23
#include " IRGenMangler.h"
24
24
#include " IRGenModule.h"
25
25
#include " LoadableTypeInfo.h"
26
26
#include " LocalTypeDataKind.h"
27
27
#include " MetadataRequest.h"
28
+ #include " swift/AST/GenericEnvironment.h"
29
+ #include " swift/AST/IRGenOptions.h"
30
+ #include " swift/SIL/SILModule.h"
28
31
29
32
using namespace swift ;
30
33
using namespace irgen ;
@@ -132,15 +135,36 @@ irgen::getTypeAndGenericSignatureForManglingOutlineFunction(SILType type) {
132
135
return {loweredType, nullptr };
133
136
}
134
137
135
- void TypeInfo::callOutlinedCopy (IRGenFunction &IGF,
136
- Address dest, Address src, SILType T,
137
- IsInitialization_t isInit,
138
+ void TypeInfo::callOutlinedCopy (IRGenFunction &IGF, Address dest, Address src,
139
+ SILType T, IsInitialization_t isInit,
138
140
IsTake_t isTake) const {
139
- OutliningMetadataCollector collector (IGF);
140
- if (T.hasArchetype ()) {
141
- collectMetadataForOutlining (collector, T);
141
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ) {
142
+ OutliningMetadataCollector collector (IGF);
143
+ if (T.hasArchetype ()) {
144
+ collectMetadataForOutlining (collector, T);
145
+ }
146
+ collector.emitCallToOutlinedCopy (dest, src, T, *this , isInit, isTake);
147
+ return ;
148
+ }
149
+
150
+ if (!T.hasArchetype ()) {
151
+ // Call the outlined copy function (the implementation will call vwt in this
152
+ // case).
153
+ OutliningMetadataCollector collector (IGF);
154
+ collector.emitCallToOutlinedCopy (dest, src, T, *this , isInit, isTake);
155
+ return ;
156
+ }
157
+
158
+ if (isInit == IsInitialization && isTake == IsTake) {
159
+ return emitInitializeWithTakeCall (IGF, T, dest, src);
160
+ } else if (isInit == IsInitialization && isTake == IsNotTake) {
161
+ return emitInitializeWithCopyCall (IGF, T, dest, src);
162
+ } else if (isInit == IsNotInitialization && isTake == IsTake) {
163
+ return emitAssignWithTakeCall (IGF, T, dest, src);
164
+ } else if (isInit == IsNotInitialization && isTake == IsNotTake) {
165
+ return emitAssignWithCopyCall (IGF, T, dest, src);
142
166
}
143
- collector. emitCallToOutlinedCopy (dest, src, T, * this , isInit, isTake );
167
+ llvm_unreachable ( " unknown case " );
144
168
}
145
169
146
170
void OutliningMetadataCollector::emitCallToOutlinedCopy (
@@ -173,6 +197,28 @@ void OutliningMetadataCollector::emitCallToOutlinedCopy(
173
197
call->setCallingConv (IGF.IGM .DefaultCC );
174
198
}
175
199
200
+ static bool needsSpecialOwnershipHandling (SILType t) {
201
+ auto astType = t.getASTType ();
202
+ auto ref = dyn_cast<ReferenceStorageType>(astType);
203
+ if (!ref) {
204
+ return false ;
205
+ }
206
+ return ref->getOwnership () != ReferenceOwnership::Strong;
207
+ }
208
+
209
+ bool isTypeMetadataForLayoutAccessible (SILModule &M, SILType type);
210
+
211
+ static bool canUseValueWitnessForValueOp (IRGenModule &IGM, SILType T) {
212
+ if (!IGM.getSILModule ().isTypeMetadataForLayoutAccessible (T))
213
+ return false ;
214
+
215
+ if (needsSpecialOwnershipHandling (T))
216
+ return false ;
217
+ if (T.getASTType ()->hasDynamicSelfType ())
218
+ return false ;
219
+ return true ;
220
+ }
221
+
176
222
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction (
177
223
SILType T, const TypeInfo &ti,
178
224
const OutliningMetadataCollector &collector) {
@@ -181,10 +227,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
181
227
IRGenMangler ().mangleOutlinedInitializeWithTakeFunction (manglingBits.first ,
182
228
manglingBits.second );
183
229
184
- return getOrCreateOutlinedCopyAddrHelperFunction (T, ti, collector, funcName,
185
- [](IRGenFunction &IGF, Address dest, Address src,
186
- SILType T, const TypeInfo &ti) {
187
- ti.initializeWithTake (IGF, dest, src, T, true );
230
+ return getOrCreateOutlinedCopyAddrHelperFunction (
231
+ T, ti, collector, funcName,
232
+ [this ](IRGenFunction &IGF, Address dest, Address src, SILType T,
233
+ const TypeInfo &ti) {
234
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ||
235
+ T.hasArchetype () || !canUseValueWitnessForValueOp (*this , T)) {
236
+ ti.initializeWithTake (IGF, dest, src, T, true );
237
+ } else {
238
+ emitInitializeWithTakeCall (IGF, T, dest, src);
239
+ }
188
240
});
189
241
}
190
242
@@ -196,10 +248,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction(
196
248
IRGenMangler ().mangleOutlinedInitializeWithCopyFunction (manglingBits.first ,
197
249
manglingBits.second );
198
250
199
- return getOrCreateOutlinedCopyAddrHelperFunction (T, ti, collector, funcName,
200
- [](IRGenFunction &IGF, Address dest, Address src,
201
- SILType T, const TypeInfo &ti) {
202
- ti.initializeWithCopy (IGF, dest, src, T, true );
251
+ return getOrCreateOutlinedCopyAddrHelperFunction (
252
+ T, ti, collector, funcName,
253
+ [this ](IRGenFunction &IGF, Address dest, Address src, SILType T,
254
+ const TypeInfo &ti) {
255
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ||
256
+ T.hasArchetype () || !canUseValueWitnessForValueOp (*this , T)) {
257
+ ti.initializeWithCopy (IGF, dest, src, T, true );
258
+ } else {
259
+ emitInitializeWithCopyCall (IGF, T, dest, src);
260
+ }
203
261
});
204
262
}
205
263
@@ -211,10 +269,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithTakeFunction(
211
269
IRGenMangler ().mangleOutlinedAssignWithTakeFunction (manglingBits.first ,
212
270
manglingBits.second );
213
271
214
- return getOrCreateOutlinedCopyAddrHelperFunction (T, ti, collector, funcName,
215
- [](IRGenFunction &IGF, Address dest, Address src,
216
- SILType T, const TypeInfo &ti) {
217
- ti.assignWithTake (IGF, dest, src, T, true );
272
+ return getOrCreateOutlinedCopyAddrHelperFunction (
273
+ T, ti, collector, funcName,
274
+ [this ](IRGenFunction &IGF, Address dest, Address src, SILType T,
275
+ const TypeInfo &ti) {
276
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ||
277
+ T.hasArchetype () || !canUseValueWitnessForValueOp (*this , T)) {
278
+ ti.assignWithTake (IGF, dest, src, T, true );
279
+ } else {
280
+ emitAssignWithTakeCall (IGF, T, dest, src);
281
+ }
218
282
});
219
283
}
220
284
@@ -226,10 +290,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithCopyFunction(
226
290
IRGenMangler ().mangleOutlinedAssignWithCopyFunction (manglingBits.first ,
227
291
manglingBits.second );
228
292
229
- return getOrCreateOutlinedCopyAddrHelperFunction (T, ti, collector, funcName,
230
- [](IRGenFunction &IGF, Address dest, Address src,
231
- SILType T, const TypeInfo &ti) {
232
- ti.assignWithCopy (IGF, dest, src, T, true );
293
+ return getOrCreateOutlinedCopyAddrHelperFunction (
294
+ T, ti, collector, funcName,
295
+ [this ](IRGenFunction &IGF, Address dest, Address src, SILType T,
296
+ const TypeInfo &ti) {
297
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ||
298
+ T.hasArchetype () || !canUseValueWitnessForValueOp (*this , T)) {
299
+ ti.assignWithCopy (IGF, dest, src, T, true );
300
+ } else {
301
+ emitAssignWithCopyCall (IGF, T, dest, src);
302
+ }
233
303
});
234
304
}
235
305
@@ -259,11 +329,28 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
259
329
260
330
void TypeInfo::callOutlinedDestroy (IRGenFunction &IGF,
261
331
Address addr, SILType T) const {
262
- OutliningMetadataCollector collector (IGF);
263
- if (T.hasArchetype ()) {
264
- collectMetadataForOutlining (collector, T);
332
+ // Short-cut destruction of trivial values.
333
+ if (IGF.IGM .getTypeLowering (T).isTrivial ())
334
+ return ;
335
+
336
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ) {
337
+ OutliningMetadataCollector collector (IGF);
338
+ if (T.hasArchetype ()) {
339
+ collectMetadataForOutlining (collector, T);
340
+ }
341
+ collector.emitCallToOutlinedDestroy (addr, T, *this );
342
+ return ;
343
+ }
344
+
345
+ if (!T.hasArchetype ()) {
346
+ // Call the outlined copy function (the implementation will call vwt in this
347
+ // case).
348
+ OutliningMetadataCollector collector (IGF);
349
+ collector.emitCallToOutlinedDestroy (addr, T, *this );
350
+ return ;
265
351
}
266
- collector.emitCallToOutlinedDestroy (addr, T, *this );
352
+
353
+ return emitDestroyCall (IGF, T, addr);
267
354
}
268
355
269
356
void OutliningMetadataCollector::emitCallToOutlinedDestroy (
@@ -298,9 +385,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
298
385
Explosion params = IGF.collectParameters ();
299
386
Address addr = ti.getAddressForPointer (params.claimNext ());
300
387
collector.bindMetadataParameters (IGF, params);
388
+ if (!IGF.IGM .getOptions ().UseTypeLayoutValueHandling ||
389
+ T.hasArchetype () || !canUseValueWitnessForValueOp (*this , T)) {
390
+ ti.destroy (IGF, addr, T, true );
391
+ } else {
392
+ emitDestroyCall (IGF, T, addr);
393
+ }
301
394
302
- ti.destroy (IGF, addr, T, true );
303
-
304
395
IGF.Builder .CreateRet (addr.getAddress ());
305
396
},
306
397
true /* setIsNoInline*/ );
0 commit comments