Skip to content

Commit 6f76726

Browse files
committed
Teach SIL type lowering about trivial, but address only types.
1 parent ec4f28e commit 6f76726

File tree

1 file changed

+106
-6
lines changed

1 file changed

+106
-6
lines changed

lib/SIL/TypeLowering.cpp

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ enum class LoweredTypeKind {
152152
AggWithReference,
153153

154154
/// Non-trivial and not loadable.
155-
AddressOnly
155+
AddressOnly,
156+
157+
/// Trivial and not loadable.
158+
TrivialAddressOnly
156159
};
157160

158161
static LoweredTypeKind classifyType(CanType type, SILModule &M,
@@ -178,6 +181,7 @@ namespace {
178181
// RetTy handleAddressOnly(CanType);
179182
// RetTy handleReference(CanType);
180183
// RetTy handleTrivial(CanType);
184+
// RetTy handleTrivialAddressOnly(CanType);
181185
// In addition, if it does not override visitTupleType
182186
// and visitAnyStructType, it should also implement:
183187
// RetTy handleAggWithReference(CanType);
@@ -317,9 +321,22 @@ namespace {
317321
RetTy visitArchetypeType(CanArchetypeType type) {
318322
if (type->requiresClass()) {
319323
return asImpl().handleReference(type);
320-
} else {
321-
return asImpl().handleAddressOnly(type);
322324
}
325+
326+
auto LayoutInfo = type->getLayoutConstraint();
327+
if (LayoutInfo) {
328+
if (LayoutInfo->isFixedSizeTrivial()) {
329+
return asImpl().handleTrivial(type);
330+
}
331+
332+
if (LayoutInfo->isAddressOnlyTrivial()) {
333+
return asImpl().handleTrivialAddressOnly(type);
334+
}
335+
336+
if (LayoutInfo->isRefCountedObject())
337+
return asImpl().handleReference(type);
338+
}
339+
return asImpl().handleAddressOnly(type);
323340
}
324341

325342
RetTy visitExistentialType(CanType type) {
@@ -371,6 +388,8 @@ namespace {
371388
switch (classifyType(eltType, M, Sig, Expansion)) {
372389
case LoweredTypeKind::Trivial:
373390
continue;
391+
case LoweredTypeKind::TrivialAddressOnly:
392+
return asImpl().handleTrivialAddressOnly(type);
374393
case LoweredTypeKind::AddressOnly:
375394
return asImpl().handleAddressOnly(type);
376395
case LoweredTypeKind::Reference:
@@ -414,9 +433,16 @@ namespace {
414433
LoweredTypeKind handleAggWithReference(CanType type) {
415434
return LoweredTypeKind::AggWithReference;
416435
}
417-
LoweredTypeKind handleTrivial(CanType type) {
436+
LoweredTypeKind
437+
handleTrivial(CanType type) {
418438
return LoweredTypeKind::Trivial;
419439
}
440+
441+
LoweredTypeKind
442+
handleTrivialAddressOnly(CanType type) {
443+
return LoweredTypeKind::TrivialAddressOnly;
444+
}
445+
420446
LoweredTypeKind handleAddressOnly(CanType type) {
421447
return LoweredTypeKind::AddressOnly;
422448
}
@@ -1134,6 +1160,71 @@ namespace {
11341160
}
11351161
};
11361162

1163+
/// A class for trivial, address-only types.
1164+
class AddressOnlyTrivialTypeLowering : public TypeLowering {
1165+
public:
1166+
AddressOnlyTrivialTypeLowering(SILType type)
1167+
: TypeLowering(type, IsTrivial, IsAddressOnly, IsNotReferenceCounted)
1168+
{}
1169+
1170+
void emitCopyInto(SILBuilder &B, SILLocation loc,
1171+
SILValue src, SILValue dest, IsTake_t isTake,
1172+
IsInitialization_t isInit) const override {
1173+
B.createCopyAddr(loc, src, dest, isTake, isInit);
1174+
}
1175+
1176+
SILValue emitLoadOfCopy(SILBuilder &B, SILLocation loc,
1177+
SILValue addr, IsTake_t isTake) const override {
1178+
llvm_unreachable("calling emitLoadOfCopy on non-loadable type");
1179+
}
1180+
1181+
void emitStoreOfCopy(SILBuilder &B, SILLocation loc,
1182+
SILValue newValue, SILValue addr,
1183+
IsInitialization_t isInit) const override {
1184+
llvm_unreachable("calling emitStoreOfCopy on non-loadable type");
1185+
}
1186+
1187+
void emitStore(SILBuilder &B, SILLocation loc, SILValue value,
1188+
SILValue addr, StoreOwnershipQualifier qual) const override {
1189+
llvm_unreachable("calling emitStore on non-loadable type");
1190+
}
1191+
1192+
SILValue emitLoad(SILBuilder &B, SILLocation loc, SILValue addr,
1193+
LoadOwnershipQualifier qual) const override {
1194+
llvm_unreachable("calling emitLoad on non-loadable type");
1195+
}
1196+
1197+
void emitDestroyAddress(SILBuilder &B, SILLocation loc,
1198+
SILValue addr) const override {
1199+
}
1200+
1201+
void emitDestroyRValue(SILBuilder &B, SILLocation loc,
1202+
SILValue value) const override {
1203+
}
1204+
1205+
SILValue emitCopyValue(SILBuilder &B, SILLocation loc,
1206+
SILValue value) const override {
1207+
llvm_unreachable("type is not loadable!");
1208+
}
1209+
1210+
SILValue emitLoweredCopyValue(SILBuilder &B, SILLocation loc,
1211+
SILValue value,
1212+
LoweringStyle style) const override {
1213+
llvm_unreachable("type is not loadable!");
1214+
}
1215+
1216+
void emitDestroyValue(SILBuilder &B, SILLocation loc,
1217+
SILValue value) const override {
1218+
llvm_unreachable("type is not loadable!");
1219+
}
1220+
1221+
void emitLoweredDestroyValue(SILBuilder &B, SILLocation loc, SILValue value,
1222+
LoweringStyle style) const override {
1223+
llvm_unreachable("type is not loadable!");
1224+
}
1225+
};
1226+
1227+
11371228
/// Build the appropriate TypeLowering subclass for the given type,
11381229
/// which is assumed to already have been lowered.
11391230
class LowerType
@@ -1147,11 +1238,18 @@ namespace {
11471238
: TypeClassifierBase(TC.M, Sig, Expansion),
11481239
TC(TC), Dependent(Dependent) {}
11491240

1150-
const TypeLowering *handleTrivial(CanType type) {
1241+
const TypeLowering *
1242+
handleTrivial(CanType type) {
11511243
auto silType = SILType::getPrimitiveObjectType(type);
11521244
return new (TC, Dependent) TrivialTypeLowering(silType);
11531245
}
1154-
1246+
1247+
const TypeLowering *
1248+
handleTrivialAddressOnly(CanType type) {
1249+
auto silType = SILType::getPrimitiveObjectType(type);
1250+
return new (TC, Dependent) AddressOnlyTrivialTypeLowering(silType);
1251+
}
1252+
11551253
const TypeLowering *handleReference(CanType type) {
11561254
auto silType = SILType::getPrimitiveObjectType(type);
11571255
return new (TC, Dependent) ReferenceTypeLowering(silType);
@@ -1208,6 +1306,7 @@ namespace {
12081306
structType->getTypeOfMember(D->getModuleContext(), field, nullptr);
12091307
switch (classifyType(substFieldType->getCanonicalType(),
12101308
M, Sig, Expansion)) {
1309+
case LoweredTypeKind::TrivialAddressOnly:
12111310
case LoweredTypeKind::AddressOnly:
12121311
return handleAddressOnly(structType);
12131312
case LoweredTypeKind::AggWithReference:
@@ -1260,6 +1359,7 @@ namespace {
12601359
->getCanonicalType();
12611360

12621361
switch (classifyType(substEltType, M, Sig, Expansion)) {
1362+
case LoweredTypeKind::TrivialAddressOnly:
12631363
case LoweredTypeKind::AddressOnly:
12641364
return handleAddressOnly(enumType);
12651365
case LoweredTypeKind::AggWithReference:

0 commit comments

Comments
 (0)