@@ -297,31 +297,31 @@ class RecordTypeInfoImpl : public Base,
297
297
std::function<void
298
298
(const TypeInfo &, SILType, Address, Address)> body) const {
299
299
if (rawLayout->shouldMoveAsLikeType ()) {
300
- // Because we have a rawlayout attribute, we know this has to be a struct.
301
- auto structDecl = T.getStructOrBoundGenericStruct ();
302
-
303
- if (auto likeType = rawLayout->getResolvedScalarLikeType (structDecl)) {
304
- auto astT = T.getASTType ();
305
- auto subs = astT->getContextSubstitutionMap ();
306
- auto loweredLikeType = IGF.IGM .getLoweredType (likeType->subst (subs));
307
- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
308
-
300
+ auto likeType = T.getRawLayoutSubstitutedLikeType ();
301
+ auto loweredLikeType = IGF.IGM .getLoweredType (likeType);
302
+ auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
303
+
304
+ // Fixup src/dest address element types because currently they are in
305
+ // terms of the raw layout type's [n x i8] where we're at a point to use
306
+ // the like type's concrete storage type.
307
+ src = Address (src.getAddress (), likeTypeInfo.getStorageType (),
308
+ src.getAlignment ());
309
+ dest = Address (dest.getAddress (), likeTypeInfo.getStorageType (),
310
+ dest.getAlignment ());
311
+
312
+ // If we're a scalar, then we only need to run the body once.
313
+ if (rawLayout->getScalarLikeType ()) {
309
314
body (likeTypeInfo, loweredLikeType, dest, src);
310
315
}
311
316
312
- if (auto likeArray = rawLayout->getResolvedArrayLikeTypeAndCount (structDecl)) {
313
- auto likeType = likeArray->first ;
314
- auto countType = likeArray->second ;
315
-
316
- auto astT = T.getASTType ();
317
- auto subs = astT->getContextSubstitutionMap ();
318
- auto loweredLikeType = IGF.IGM .getLoweredType (likeType.subst (subs));
319
- auto &likeTypeInfo = IGF.IGM .getTypeInfo (loweredLikeType);
320
- countType = countType.subst (subs);
317
+ // Otherwise, emit a loop that calls body N times where N is the count
318
+ // of the array variant. This could be generic in which case we need to
319
+ // pull the value out of metadata or it could be a constant integer.
320
+ if (rawLayout->getArrayLikeTypeAndCount ()) {
321
+ auto countType = T.getRawLayoutSubstitutedCountType ()->getCanonicalType ();
321
322
322
- IGF.emitLoopOverElements (likeTypeInfo, loweredLikeType,
323
- countType->getCanonicalType (), dest, src,
324
- [&](Address dest, Address src) {
323
+ IGF.emitLoopOverElements (likeTypeInfo, loweredLikeType, countType,
324
+ dest, src, [&](Address dest, Address src) {
325
325
body (likeTypeInfo, loweredLikeType, dest, src);
326
326
});
327
327
}
@@ -555,6 +555,23 @@ class RecordTypeInfoImpl : public Base,
555
555
auto fType = field.getType (collector.IGF .IGM , T);
556
556
field.getTypeInfo ().collectMetadataForOutlining (collector, fType );
557
557
}
558
+
559
+ // If we're a raw layout type, collect metadata from our like type and count
560
+ // as well.
561
+ if (auto likeType = T.getRawLayoutSubstitutedLikeType ()) {
562
+ auto loweredLikeType = collector.IGF .IGM .getLoweredType (likeType);
563
+ collector.IGF .IGM .getTypeInfo (loweredLikeType)
564
+ .collectMetadataForOutlining (collector, loweredLikeType);
565
+
566
+ if (auto countType = T.getRawLayoutSubstitutedCountType ()) {
567
+ if (countType->isValueParameter ()) {
568
+ auto loweredCountType = collector.IGF .IGM .getLoweredType (countType);
569
+ collector.IGF .IGM .getTypeInfo (loweredCountType)
570
+ .collectMetadataForOutlining (collector, loweredCountType);
571
+ }
572
+ }
573
+ }
574
+
558
575
collector.collectTypeMetadata (T);
559
576
}
560
577
};
0 commit comments