@@ -280,14 +280,39 @@ class ClassArchetypeTypeInfo
280
280
}
281
281
};
282
282
283
+ class FixedSizeArchetypeTypeInfo
284
+ : public PODSingleScalarTypeInfo<FixedSizeArchetypeTypeInfo, LoadableTypeInfo>,
285
+ public ArchetypeTypeInfoBase
286
+ {
287
+ FixedSizeArchetypeTypeInfo (llvm::Type *type, Size size, Alignment align,
288
+ const SpareBitVector &spareBits,
289
+ ArrayRef<ProtocolEntry> protocols)
290
+ : PODSingleScalarTypeInfo(type, size, spareBits, align),
291
+ ArchetypeTypeInfoBase (this + 1 , protocols) {}
292
+
293
+ public:
294
+ static const FixedSizeArchetypeTypeInfo *
295
+ create (llvm::Type *type, Size size, Alignment align,
296
+ const SpareBitVector &spareBits, ArrayRef<ProtocolEntry> protocols) {
297
+ void *buffer = operator new (sizeof (FixedSizeArchetypeTypeInfo) +
298
+ protocols.size () * sizeof (ProtocolEntry));
299
+ return ::new (buffer)
300
+ FixedSizeArchetypeTypeInfo (type, size, align, spareBits, protocols);
301
+ }
302
+ };
303
+
283
304
} // end anonymous namespace
284
305
285
306
// / Return the ArchetypeTypeInfoBase information from the TypeInfo for any
286
307
// / archetype.
287
308
static const ArchetypeTypeInfoBase &
288
309
getArchetypeInfo (IRGenFunction &IGF, CanArchetypeType t, const TypeInfo &ti) {
289
- if (t->requiresClass ())
310
+ LayoutConstraint LayoutInfo = t->getLayoutConstraint ();
311
+ if (t->requiresClass () || (LayoutInfo && LayoutInfo->isRefCountedObject ()))
290
312
return ti.as <ClassArchetypeTypeInfo>();
313
+ if (LayoutInfo && LayoutInfo->isFixedSizeTrivial ())
314
+ return ti.as <FixedSizeArchetypeTypeInfo>();
315
+ // TODO: Handle LayoutConstraintInfo::Trivial
291
316
return ti.as <OpaqueArchetypeTypeInfo>();
292
317
}
293
318
@@ -374,9 +399,12 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
374
399
protocols.push_back (ProtocolEntry (protocol, impl));
375
400
}
376
401
402
+ LayoutConstraint LayoutInfo = archetype->getLayoutConstraint ();
403
+
377
404
// If the archetype is class-constrained, use a class pointer
378
405
// representation.
379
- if (archetype->requiresClass ()) {
406
+ if (archetype->requiresClass () ||
407
+ (LayoutInfo && LayoutInfo->isRefCountedObject ())) {
380
408
ReferenceCounting refcount;
381
409
llvm::PointerType *reprTy;
382
410
@@ -412,6 +440,28 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
412
440
protocols, refcount);
413
441
}
414
442
443
+ // If the archetype is trivial fixed-size layout-constrained, use a fixed size
444
+ // representation.
445
+ if (LayoutInfo && LayoutInfo->isFixedSizeTrivial ()) {
446
+ Size size (LayoutInfo->getTrivialSizeInBytes ());
447
+ Alignment align (LayoutInfo->getTrivialSizeInBytes ());
448
+ auto spareBits =
449
+ SpareBitVector::getConstant (size.getValueInBits (), false );
450
+ // Get an integer type of the required size.
451
+ auto ProperlySizedIntTy = SILType::getBuiltinIntegerType (
452
+ size.getValueInBits (), IGM.getSwiftModule ()->getASTContext ());
453
+ auto storageType = IGM.getStorageType (ProperlySizedIntTy);
454
+ return FixedSizeArchetypeTypeInfo::create (storageType, size, align,
455
+ spareBits, protocols);
456
+ }
457
+
458
+ // If the archetype is a trivial layout-constrained, use a POD
459
+ // representation. This type is not loadable, but it is known
460
+ // to be a POD.
461
+ if (LayoutInfo && LayoutInfo->isAddressOnlyTrivial ()) {
462
+ // TODO: Create NonFixedSizeArchetypeTypeInfo and return it.
463
+ }
464
+
415
465
// Otherwise, for now, always use an opaque indirect type.
416
466
llvm::Type *storageType = IGM.OpaquePtrTy ->getElementType ();
417
467
return OpaqueArchetypeTypeInfo::create (storageType, protocols);
0 commit comments