@@ -1139,7 +1139,7 @@ namespace {
1139
1139
// / Build the appropriate TypeLowering subclass for the given type,
1140
1140
// / which is assumed to already have been lowered.
1141
1141
class LowerType
1142
- : public TypeClassifierBase<LowerType, const TypeLowering *>
1142
+ : public TypeClassifierBase<LowerType, TypeLowering *>
1143
1143
{
1144
1144
TypeConverter &TC;
1145
1145
IsDependent_t Dependent;
@@ -1149,18 +1149,18 @@ namespace {
1149
1149
: TypeClassifierBase(TC.M, Sig, Expansion),
1150
1150
TC (TC), Dependent(Dependent) {}
1151
1151
1152
- const TypeLowering *
1152
+ TypeLowering *
1153
1153
handleTrivial (CanType type) {
1154
1154
auto silType = SILType::getPrimitiveObjectType (type);
1155
1155
return new (TC, Dependent) TrivialTypeLowering (silType);
1156
1156
}
1157
1157
1158
- const TypeLowering *handleReference (CanType type) {
1158
+ TypeLowering *handleReference (CanType type) {
1159
1159
auto silType = SILType::getPrimitiveObjectType (type);
1160
1160
return new (TC, Dependent) ReferenceTypeLowering (silType);
1161
1161
}
1162
1162
1163
- const TypeLowering *handleAddressOnly (CanType type,
1163
+ TypeLowering *handleAddressOnly (CanType type,
1164
1164
RecursiveProperties properties) {
1165
1165
if (SILModuleConventions (M).useLoweredAddresses ()) {
1166
1166
auto silType = SILType::getPrimitiveAddressType (type);
@@ -1171,20 +1171,20 @@ namespace {
1171
1171
}
1172
1172
1173
1173
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
1174
- const TypeLowering * \
1174
+ TypeLowering * \
1175
1175
visitLoadable##Name##StorageType(Can##Name##StorageType type) { \
1176
1176
return new (TC, Dependent) Loadable##Name##TypeLowering ( \
1177
1177
SILType::getPrimitiveObjectType (type)); \
1178
1178
}
1179
1179
#include " swift/AST/ReferenceStorage.def"
1180
1180
1181
- const TypeLowering *
1181
+ TypeLowering *
1182
1182
visitBuiltinUnsafeValueBufferType (CanBuiltinUnsafeValueBufferType type) {
1183
1183
auto silType = SILType::getPrimitiveAddressType (type);
1184
1184
return new (TC, Dependent) UnsafeValueBufferTypeLowering (silType);
1185
1185
}
1186
1186
1187
- const TypeLowering *visitTupleType (CanTupleType tupleType) {
1187
+ TypeLowering *visitTupleType (CanTupleType tupleType) {
1188
1188
RecursiveProperties properties;
1189
1189
for (auto eltType : tupleType.getElementTypes ()) {
1190
1190
auto &lowering = TC.getTypeLowering (eltType);
@@ -1195,13 +1195,13 @@ namespace {
1195
1195
properties);
1196
1196
}
1197
1197
1198
- const TypeLowering *visitAnyStructType (CanType structType, StructDecl *D) {
1198
+ TypeLowering *visitAnyStructType (CanType structType, StructDecl *D) {
1199
1199
1200
1200
// For now, if the type does not have a fixed layout in all resilience
1201
1201
// domains, we will treat it as address-only in SIL.
1202
1202
if (D->isResilient (M.getSwiftModule (), Expansion))
1203
1203
return handleAddressOnly (structType,
1204
- RecursiveProperties::forOpaque ());
1204
+ RecursiveProperties::forResilient ());
1205
1205
1206
1206
// Classify the type according to its stored properties.
1207
1207
RecursiveProperties properties;
@@ -1216,11 +1216,11 @@ namespace {
1216
1216
properties);
1217
1217
}
1218
1218
1219
- const TypeLowering *visitAnyEnumType (CanType enumType, EnumDecl *D) {
1219
+ TypeLowering *visitAnyEnumType (CanType enumType, EnumDecl *D) {
1220
1220
// For now, if the type does not have a fixed layout in all resilience
1221
1221
// domains, we will treat it as address-only in SIL.
1222
1222
if (D->isResilient (M.getSwiftModule (), Expansion))
1223
- return handleAddressOnly (enumType, RecursiveProperties::forOpaque ());
1223
+ return handleAddressOnly (enumType, RecursiveProperties::forResilient ());
1224
1224
1225
1225
// If the whole enum is indirect, we lower it as if all payload
1226
1226
// cases were indirect. This means a fixed-layout indirect enum
@@ -1257,7 +1257,7 @@ namespace {
1257
1257
}
1258
1258
1259
1259
template <class LoadableLoweringClass >
1260
- const TypeLowering *handleAggregateByProperties (CanType type,
1260
+ TypeLowering *handleAggregateByProperties (CanType type,
1261
1261
RecursiveProperties props) {
1262
1262
if (props.isAddressOnly ()) {
1263
1263
return handleAddressOnly (type, props);
@@ -1451,7 +1451,8 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
1451
1451
AbstractionPattern (getCurGenericContext (), loweredSubstType);
1452
1452
auto loweredKey = getTypeKey (origTypeForCaching, loweredSubstType);
1453
1453
1454
- auto &lowering = getTypeLoweringForLoweredType (loweredKey);
1454
+ auto &lowering = getTypeLoweringForLoweredType (loweredKey,
1455
+ ResilienceExpansion::Minimal);
1455
1456
insert (key, &lowering);
1456
1457
return lowering;
1457
1458
}
@@ -1565,27 +1566,58 @@ CanType TypeConverter::getLoweredRValueType(AbstractionPattern origType,
1565
1566
return substType;
1566
1567
}
1567
1568
1568
- const TypeLowering &TypeConverter::getTypeLowering (SILType type) {
1569
+ const TypeLowering &
1570
+ TypeConverter::getTypeLowering (SILType type, ResilienceExpansion forExpansion) {
1569
1571
auto loweredType = type.getASTType ();
1570
1572
auto key = getTypeKey (AbstractionPattern (getCurGenericContext (), loweredType),
1571
1573
loweredType);
1572
1574
1573
- return getTypeLoweringForLoweredType (key);
1575
+ return getTypeLoweringForLoweredType (key, forExpansion );
1574
1576
}
1575
1577
1576
1578
const TypeLowering &
1577
- TypeConverter::getTypeLoweringForLoweredType (TypeKey key) {
1579
+ TypeConverter::getTypeLoweringForLoweredType (TypeKey key,
1580
+ ResilienceExpansion forExpansion) {
1578
1581
auto type = key.SubstType ;
1579
1582
assert (type->isLegalSILType () && " type is not lowered!" );
1580
1583
(void )type;
1581
1584
1582
1585
// Re-using uncurry level 0 is reasonable because our uncurrying
1583
1586
// transforms are idempotent at this level. This means we don't
1584
1587
// need a ton of redundant entries in the map.
1585
- if (auto existing = find (key))
1586
- return *existing;
1588
+ const TypeLowering *lowering = find (key);
1589
+ if (!lowering) {
1590
+ lowering = &getTypeLoweringForUncachedLoweredType (key);
1591
+ }
1592
+ assert (lowering->forExpansion == ResilienceExpansion::Minimal &&
1593
+ " the first lowering in the list must be for minimal expansion" );
1587
1594
1588
- return getTypeLoweringForUncachedLoweredType (key);
1595
+ if (key.isDependent () || !lowering->isResilient ()) {
1596
+ // Don't try to refine the lowering for other resilience expansions if
1597
+ // we don't expect to get a different lowering anyway.
1598
+ return *lowering;
1599
+ }
1600
+
1601
+ // Search for a matching lowering in the linked list of lowerings.
1602
+ while (true ) {
1603
+ if (lowering->forExpansion == forExpansion)
1604
+ return *lowering;
1605
+ if (lowering->nextExpansion ) {
1606
+ // Continue searching.
1607
+ lowering = lowering->nextExpansion ;
1608
+ continue ;
1609
+ }
1610
+
1611
+ // Create a new lowering for the resilience expansion.
1612
+ TypeLowering *theInfo = LowerType (*this ,
1613
+ CanGenericSignature (),
1614
+ forExpansion,
1615
+ key.isDependent ()).visit (key.SubstType );
1616
+
1617
+ lowering->nextExpansion = theInfo;
1618
+ theInfo->forExpansion = forExpansion;
1619
+ return *theInfo;
1620
+ }
1589
1621
}
1590
1622
1591
1623
// / Do type-lowering for a lowered type which is not already in the cache,
0 commit comments