@@ -203,21 +203,9 @@ class RecordTypeInfoImpl : public Base,
203203 }
204204
205205 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 );
221209 }
222210
223211 if (isOutlined || T.hasParameterizedExistential ()) {
@@ -280,20 +268,8 @@ class RecordTypeInfoImpl : public Base,
280268 // If the fields are not ABI-accessible, use the value witness table.
281269 return emitInitializeWithTakeCall (IGF, T, dest, src);
282270 } 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 );
297273 } else if (isOutlined || T.hasParameterizedExistential ()) {
298274 auto offsets = asImpl ().getNonFixedOffsets (IGF, T);
299275 for (auto &field : getFields ()) {
@@ -313,6 +289,90 @@ class RecordTypeInfoImpl : public Base,
313289 fillWithZerosIfSensitive (IGF, src, T);
314290 }
315291
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+
316376 void destroy (IRGenFunction &IGF, Address addr, SILType T,
317377 bool isOutlined) const override {
318378 // If the fields are not ABI-accessible, use the value witness table.
0 commit comments