@@ -203,21 +203,9 @@ class RecordTypeInfoImpl : public Base,
203
203
}
204
204
205
205
if (auto rawLayout = T.getRawLayout ()) {
206
- // Because we have a rawlayout attribute, we know this has to be a struct.
207
- auto structDecl = T.getStructOrBoundGenericStruct ();
208
-
209
- if (auto likeType = rawLayout->getResolvedScalarLikeType (structDecl)) {
210
- if (rawLayout->shouldMoveAsLikeType ()) {
211
- auto astT = T.getASTType ();
212
- auto subs = astT->getContextSubstitutionMap ();
213
- auto loweredLikeType = IGF.IGM .getLoweredType (likeType->subst (subs));
214
- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
215
-
216
- likeTypeInfo.assignWithTake (IGF, dest, src, loweredLikeType,
217
- isOutlined);
218
- return ;
219
- }
220
- }
206
+ return takeRawLayout (IGF, dest, src, T, isOutlined,
207
+ /* zeroizeIfSensitive */ false , rawLayout,
208
+ /* isInit */ false );
221
209
}
222
210
223
211
if (isOutlined || T.hasParameterizedExistential ()) {
@@ -280,20 +268,8 @@ class RecordTypeInfoImpl : public Base,
280
268
// If the fields are not ABI-accessible, use the value witness table.
281
269
return emitInitializeWithTakeCall (IGF, T, dest, src);
282
270
} else if (auto rawLayout = T.getRawLayout ()) {
283
- // Because we have a rawlayout attribute, we know this has to be a struct.
284
- auto structDecl = T.getStructOrBoundGenericStruct ();
285
-
286
- if (auto likeType = rawLayout->getResolvedScalarLikeType (structDecl)) {
287
- if (rawLayout->shouldMoveAsLikeType ()) {
288
- auto astT = T.getASTType ();
289
- auto subs = astT->getContextSubstitutionMap ();
290
- auto loweredLikeType = IGF.IGM .getLoweredType (likeType->subst (subs));
291
- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
292
-
293
- likeTypeInfo.initializeWithTake (IGF, dest, src, loweredLikeType,
294
- isOutlined, zeroizeIfSensitive);
295
- }
296
- }
271
+ return takeRawLayout (IGF, dest, src, T, isOutlined, zeroizeIfSensitive,
272
+ rawLayout, /* isInit */ true );
297
273
} else if (isOutlined || T.hasParameterizedExistential ()) {
298
274
auto offsets = asImpl ().getNonFixedOffsets (IGF, T);
299
275
for (auto &field : getFields ()) {
@@ -313,6 +289,90 @@ class RecordTypeInfoImpl : public Base,
313
289
fillWithZerosIfSensitive (IGF, src, T);
314
290
}
315
291
292
+ void takeRawLayout (IRGenFunction &IGF, Address dest, Address src, SILType T,
293
+ bool isOutlined, bool zeroizeIfSensitive,
294
+ RawLayoutAttr *rawLayout, bool isInit) const {
295
+ if (rawLayout->shouldMoveAsLikeType ()) {
296
+ // Because we have a rawlayout attribute, we know this has to be a struct.
297
+ auto structDecl = T.getStructOrBoundGenericStruct ();
298
+
299
+ if (auto likeType = rawLayout->getResolvedScalarLikeType (structDecl)) {
300
+ auto astT = T.getASTType ();
301
+ auto subs = astT->getContextSubstitutionMap ();
302
+ auto loweredLikeType = IGF.IGM .getLoweredType (likeType->subst (subs));
303
+ auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
304
+
305
+ if (isInit) {
306
+ likeTypeInfo.initializeWithTake (IGF, dest, src, loweredLikeType,
307
+ isOutlined, zeroizeIfSensitive);
308
+ } else {
309
+ likeTypeInfo.assignWithTake (IGF, dest, src, loweredLikeType,
310
+ isOutlined);
311
+ }
312
+ }
313
+
314
+ if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount (structDecl)) {
315
+ auto likeType = likeArray->first ;
316
+ unsigned count = likeArray->second ;
317
+
318
+ auto astT = T.getASTType ();
319
+ auto subs = astT->getContextSubstitutionMap ();
320
+ auto loweredLikeType = IGF.IGM .getLoweredType (likeType.subst (subs));
321
+ auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
322
+
323
+ for (unsigned i = 0 ; i != count; i += 1 ) {
324
+ auto index = llvm::ConstantInt::get (IGF.IGM .SizeTy , i);
325
+
326
+ Address srcEltAddr;
327
+ Address destEltAddr;
328
+
329
+ // If we have a fixed type, we can use a typed GEP to index into the
330
+ // array raw layout. Otherwise, we need to advance by bytes given the
331
+ // stride from the VWT of the like type.
332
+ if (auto fixedLikeType = dyn_cast<FixedTypeInfo>(&likeTypeInfo)) {
333
+ srcEltAddr = Address (IGF.Builder .CreateInBoundsGEP (
334
+ fixedLikeType->getStorageType (),
335
+ src.getAddress (),
336
+ index),
337
+ fixedLikeType->getStorageType (),
338
+ src.getAlignment ());
339
+ destEltAddr = Address (IGF.Builder .CreateInBoundsGEP (
340
+ fixedLikeType->getStorageType (),
341
+ dest.getAddress (),
342
+ index),
343
+ fixedLikeType->getStorageType (),
344
+ dest.getAlignment ());
345
+ } else {
346
+ auto eltSize = likeTypeInfo.getStride (IGF, loweredLikeType);
347
+ auto offset = IGF.Builder .CreateMul (index, eltSize);
348
+
349
+ srcEltAddr = Address (IGF.Builder .CreateInBoundsGEP (
350
+ IGF.IGM .Int8Ty ,
351
+ src.getAddress (),
352
+ offset),
353
+ IGF.IGM .Int8Ty ,
354
+ src.getAlignment ());
355
+ destEltAddr = Address (IGF.Builder .CreateInBoundsGEP (
356
+ IGF.IGM .Int8Ty ,
357
+ dest.getAddress (),
358
+ offset),
359
+ IGF.IGM .Int8Ty ,
360
+ dest.getAlignment ());
361
+ }
362
+
363
+ if (isInit) {
364
+ likeTypeInfo.initializeWithTake (IGF, destEltAddr, srcEltAddr,
365
+ loweredLikeType, isOutlined,
366
+ zeroizeIfSensitive);
367
+ } else {
368
+ likeTypeInfo.assignWithTake (IGF, destEltAddr, srcEltAddr,
369
+ loweredLikeType, isOutlined);
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+
316
376
void destroy (IRGenFunction &IGF, Address addr, SILType T,
317
377
bool isOutlined) const override {
318
378
// If the fields are not ABI-accessible, use the value witness table.
0 commit comments