@@ -154,24 +154,21 @@ namespace {
154
154
// The subclass should implement:
155
155
// // Trivial, fixed-layout, and non-address-only.
156
156
// RetTy handleTrivial(CanType);
157
+ // RetTy handleTrivial(CanType. RecursiveProperties properties);
157
158
// // A reference type.
158
159
// RetTy handleReference(CanType);
159
160
// // Non-trivial and address-only.
160
161
// RetTy handleAddressOnly(CanType, RecursiveProperties properties);
161
162
// and, if it doesn't override handleTupleType,
162
163
// // An aggregate type that's non-trivial.
163
- // RetTy handleNonTrivialAggregate(CanType, IsFixedABI_t fixed );
164
+ // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties properties );
164
165
//
165
166
// Alternatively, it can just implement:
166
167
// RetTy handle(CanType, RecursiveProperties properties);
167
168
168
169
// / Handle a trivial, fixed-size, loadable type.
169
- RetTy handleTrivial (CanType type) {
170
- return asImpl ().handle (type, RecursiveProperties ());
171
- }
172
-
173
- RetTy handleReference (CanType type) {
174
- return asImpl ().handle (type, RecursiveProperties::forReference ());
170
+ RetTy handleTrivial (CanType type, RecursiveProperties properties) {
171
+ return asImpl ().handle (type, properties);
175
172
}
176
173
177
174
RetTy handleAddressOnly (CanType type, RecursiveProperties properties) {
@@ -183,6 +180,13 @@ namespace {
183
180
return asImpl ().handle (type, properties);
184
181
}
185
182
183
+ RetTy handleTrivial (CanType type) {
184
+ return asImpl ().handleTrivial (type, RecursiveProperties::forTrivial ());
185
+ }
186
+ RetTy handleReference (CanType type) {
187
+ return asImpl ().handle (type, RecursiveProperties::forReference ());
188
+ }
189
+
186
190
#define IMPL (TYPE, LOWERING ) \
187
191
RetTy visit##TYPE##Type(Can##TYPE##Type type) { \
188
192
return asImpl ().handle ##LOWERING (type); \
@@ -207,7 +211,7 @@ namespace {
207
211
RetTy visitBuiltinUnsafeValueBufferType (
208
212
CanBuiltinUnsafeValueBufferType type) {
209
213
return asImpl ().handleAddressOnly (type, {IsNotTrivial, IsFixedABI,
210
- IsAddressOnly});
214
+ IsAddressOnly, IsNotResilient });
211
215
}
212
216
213
217
RetTy visitAnyFunctionType (CanAnyFunctionType type) {
@@ -305,7 +309,8 @@ namespace {
305
309
RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
306
310
return asImpl ().handleAddressOnly (type, {IsNotTrivial, \
307
311
IsFixedABI, \
308
- IsAddressOnly}); \
312
+ IsAddressOnly, \
313
+ IsNotResilient}); \
309
314
}
310
315
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
311
316
RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
@@ -318,7 +323,8 @@ namespace {
318
323
RetTy visitAddressOnly##Name##StorageType(Can##Name##StorageType type) { \
319
324
return asImpl ().handleAddressOnly (type, {IsNotTrivial, \
320
325
IsFixedABI, \
321
- IsAddressOnly}); \
326
+ IsAddressOnly, \
327
+ IsNotResilient}); \
322
328
} \
323
329
RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
324
330
auto referentType = type->getReferentType (); \
@@ -349,8 +355,9 @@ namespace {
349
355
}
350
356
351
357
if (LayoutInfo->isAddressOnlyTrivial ()) {
352
- return asImpl ().handleAddressOnly (type,
353
- {IsTrivial, IsNotFixedABI, IsAddressOnly});
358
+ auto properties = RecursiveProperties::forTrivial ();
359
+ properties.setAddressOnly ();
360
+ return asImpl ().handleAddressOnly (type, properties);
354
361
}
355
362
356
363
if (LayoutInfo->isRefCounted ())
@@ -368,7 +375,8 @@ namespace {
368
375
case ExistentialRepresentation::Opaque:
369
376
return asImpl ().handleAddressOnly (type, {IsNotTrivial,
370
377
IsFixedABI,
371
- IsAddressOnly});
378
+ IsAddressOnly,
379
+ IsNotResilient});
372
380
// Class-constrained and boxed existentials are refcounted.
373
381
case ExistentialRepresentation::Class:
374
382
case ExistentialRepresentation::Boxed:
@@ -418,8 +426,10 @@ namespace {
418
426
419
427
RetTy visitSILBlockStorageType (CanSILBlockStorageType type) {
420
428
// Should not be loaded.
421
- return asImpl ().handleAddressOnly (type, {IsNotTrivial, IsFixedABI,
422
- IsAddressOnly});
429
+ return asImpl ().handleAddressOnly (type, {IsNotTrivial,
430
+ IsFixedABI,
431
+ IsAddressOnly,
432
+ IsNotResilient});
423
433
}
424
434
425
435
RetTy visitSILBoxType (CanSILBoxType type) {
@@ -547,9 +557,14 @@ namespace {
547
557
// / A class for trivial, fixed-layout, loadable types.
548
558
class TrivialTypeLowering final : public LoadableTypeLowering {
549
559
public:
550
- TrivialTypeLowering (SILType type, ResilienceExpansion forExpansion)
551
- : LoadableTypeLowering(type, {IsTrivial, IsFixedABI, IsNotAddressOnly},
552
- IsNotReferenceCounted, forExpansion) {}
560
+ TrivialTypeLowering (SILType type, RecursiveProperties properties,
561
+ ResilienceExpansion forExpansion)
562
+ : LoadableTypeLowering(type, properties, IsNotReferenceCounted,
563
+ forExpansion) {
564
+ assert (properties.isFixedABI ());
565
+ assert (properties.isTrivial ());
566
+ assert (!properties.isAddressOnly ());
567
+ }
553
568
554
569
SILValue emitLoadOfCopy (SILBuilder &B, SILLocation loc, SILValue addr,
555
570
IsTake_t isTake) const override {
@@ -610,14 +625,6 @@ namespace {
610
625
611
626
class NonTrivialLoadableTypeLowering : public LoadableTypeLowering {
612
627
public:
613
- NonTrivialLoadableTypeLowering (SILType type,
614
- IsReferenceCounted_t isRefCounted,
615
- ResilienceExpansion forExpansion)
616
- : NonTrivialLoadableTypeLowering(type,
617
- {IsNotTrivial, IsFixedABI, IsNotAddressOnly},
618
- isRefCounted, forExpansion) {}
619
-
620
- // / This constructor is necessary because of opaque-values.
621
628
NonTrivialLoadableTypeLowering (SILType type,
622
629
RecursiveProperties properties,
623
630
IsReferenceCounted_t isRefCounted,
@@ -713,9 +720,11 @@ namespace {
713
720
const = 0;
714
721
715
722
public:
716
- LoadableAggTypeLowering (CanType type, ResilienceExpansion forExpansion)
723
+ LoadableAggTypeLowering (CanType type, RecursiveProperties properties,
724
+ ResilienceExpansion forExpansion)
717
725
: NonTrivialLoadableTypeLowering(SILType::getPrimitiveObjectType(type),
718
- IsNotReferenceCounted, forExpansion) {
726
+ properties, IsNotReferenceCounted,
727
+ forExpansion) {
719
728
}
720
729
721
730
virtual SILValue rebuildAggregate (SILBuilder &B, SILLocation loc,
@@ -830,8 +839,9 @@ namespace {
830
839
class LoadableTupleTypeLowering final
831
840
: public LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned > {
832
841
public:
833
- LoadableTupleTypeLowering (CanType type, ResilienceExpansion forExpansion)
834
- : LoadableAggTypeLowering(type, forExpansion) {}
842
+ LoadableTupleTypeLowering (CanType type, RecursiveProperties properties,
843
+ ResilienceExpansion forExpansion)
844
+ : LoadableAggTypeLowering(type, properties, forExpansion) {}
835
845
836
846
SILValue emitRValueProject (SILBuilder &B, SILLocation loc,
837
847
SILValue tupleValue, unsigned index,
@@ -866,8 +876,9 @@ namespace {
866
876
class LoadableStructTypeLowering final
867
877
: public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl*> {
868
878
public:
869
- LoadableStructTypeLowering (CanType type, ResilienceExpansion forExpansion)
870
- : LoadableAggTypeLowering(type, forExpansion) {}
879
+ LoadableStructTypeLowering (CanType type, RecursiveProperties properties,
880
+ ResilienceExpansion forExpansion)
881
+ : LoadableAggTypeLowering(type, properties, forExpansion) {}
871
882
872
883
SILValue emitRValueProject (SILBuilder &B, SILLocation loc,
873
884
SILValue structValue, VarDecl *field,
@@ -899,8 +910,10 @@ namespace {
899
910
// / A lowering for loadable but non-trivial enum types.
900
911
class LoadableEnumTypeLowering final : public NonTrivialLoadableTypeLowering {
901
912
public:
902
- LoadableEnumTypeLowering (CanType type, ResilienceExpansion forExpansion)
913
+ LoadableEnumTypeLowering (CanType type, RecursiveProperties properties,
914
+ ResilienceExpansion forExpansion)
903
915
: NonTrivialLoadableTypeLowering(SILType::getPrimitiveObjectType(type),
916
+ properties,
904
917
IsNotReferenceCounted,
905
918
forExpansion) {}
906
919
@@ -1021,8 +1034,9 @@ namespace {
1021
1034
AddressOnlyTypeLowering (SILType type, RecursiveProperties properties,
1022
1035
ResilienceExpansion forExpansion)
1023
1036
: TypeLowering(type, properties, IsNotReferenceCounted,
1024
- forExpansion)
1025
- {}
1037
+ forExpansion) {
1038
+ assert (properties.isAddressOnly ());
1039
+ }
1026
1040
1027
1041
void emitCopyInto (SILBuilder &B, SILLocation loc,
1028
1042
SILValue src, SILValue dest, IsTake_t isTake,
@@ -1092,7 +1106,8 @@ namespace {
1092
1106
UnsafeValueBufferTypeLowering (SILType type,
1093
1107
ResilienceExpansion forExpansion)
1094
1108
: AddressOnlyTypeLowering(type,
1095
- {IsNotTrivial, IsFixedABI, IsAddressOnly},
1109
+ {IsNotTrivial, IsFixedABI,
1110
+ IsAddressOnly, IsNotResilient},
1096
1111
forExpansion) {}
1097
1112
1098
1113
void emitCopyInto (SILBuilder &B, SILLocation loc,
@@ -1168,8 +1183,14 @@ namespace {
1168
1183
TC (TC), Dependent(Dependent) {}
1169
1184
1170
1185
TypeLowering *handleTrivial (CanType type) {
1186
+ return handleTrivial (type, RecursiveProperties::forTrivial ());
1187
+ }
1188
+
1189
+ TypeLowering *handleTrivial (CanType type,
1190
+ RecursiveProperties properties) {
1171
1191
auto silType = SILType::getPrimitiveObjectType (type);
1172
- return new (TC, Dependent) TrivialTypeLowering (silType, Expansion);
1192
+ return new (TC, Dependent) TrivialTypeLowering (silType, properties,
1193
+ Expansion);
1173
1194
}
1174
1195
1175
1196
TypeLowering *handleReference (CanType type) {
@@ -1223,16 +1244,37 @@ namespace {
1223
1244
properties);
1224
1245
}
1225
1246
1247
+ bool handleResilience (CanType type, NominalTypeDecl *D,
1248
+ RecursiveProperties &properties) {
1249
+ if (D->isResilient ()) {
1250
+ // If the type is resilient and defined in our module, make a note of
1251
+ // that, since our lowering now depends on the resilience expansion.
1252
+ bool sameModule = (D->getModuleContext () == M.getSwiftModule ());
1253
+ if (sameModule)
1254
+ properties.addSubobject (RecursiveProperties::forResilient ());
1255
+
1256
+ // If the type is in a different module, or if we're using a minimal
1257
+ // expansion, the type is address only and completely opaque to us.
1258
+ //
1259
+ // Note: if the type is in a different module, the lowering does
1260
+ // not depend on the resilience expansion, so we do not need to set
1261
+ // the isResilent() flag above.
1262
+ if (!sameModule || Expansion == ResilienceExpansion::Minimal) {
1263
+ properties.addSubobject (RecursiveProperties::forOpaque ());
1264
+ return true ;
1265
+ }
1266
+ }
1267
+
1268
+ return false ;
1269
+ }
1270
+
1226
1271
TypeLowering *visitAnyStructType (CanType structType, StructDecl *D) {
1272
+ RecursiveProperties properties;
1227
1273
1228
- // For now, if the type does not have a fixed layout in all resilience
1229
- // domains, we will treat it as address-only in SIL.
1230
- if (D->isResilient (M.getSwiftModule (), Expansion))
1231
- return handleAddressOnly (structType,
1232
- RecursiveProperties::forResilient ());
1274
+ if (handleResilience (structType, D, properties))
1275
+ return handleAddressOnly (structType, properties);
1233
1276
1234
1277
// Classify the type according to its stored properties.
1235
- RecursiveProperties properties;
1236
1278
for (auto field : D->getStoredProperties ()) {
1237
1279
auto substFieldType =
1238
1280
structType->getTypeOfMember (D->getModuleContext (), field, nullptr );
@@ -1245,22 +1287,24 @@ namespace {
1245
1287
}
1246
1288
1247
1289
TypeLowering *visitAnyEnumType (CanType enumType, EnumDecl *D) {
1248
- // For now, if the type does not have a fixed layout in all resilience
1249
- // domains, we will treat it as address-only in SIL.
1250
- if (D-> isResilient (M. getSwiftModule (), Expansion ))
1251
- return handleAddressOnly (enumType, RecursiveProperties::forResilient () );
1290
+ RecursiveProperties properties;
1291
+
1292
+ if (handleResilience (enumType, D, properties ))
1293
+ return handleAddressOnly (enumType, properties );
1252
1294
1253
1295
// If the whole enum is indirect, we lower it as if all payload
1254
1296
// cases were indirect. This means a fixed-layout indirect enum
1255
1297
// is always loadable and nontrivial. A resilient indirect enum
1256
1298
// is still address only, because we don't know how many bits
1257
- // are used for the discriminator.
1299
+ // are used for the discriminator, and new non-indirect cases
1300
+ // may be added resiliently later.
1258
1301
if (D->isIndirect ()) {
1259
- return new (TC, Dependent) LoadableEnumTypeLowering (enumType, Expansion);
1302
+ properties.setNonTrivial ();
1303
+ return new (TC, Dependent) LoadableEnumTypeLowering (enumType, properties,
1304
+ Expansion);
1260
1305
}
1261
1306
1262
1307
// Accumulate the properties of all direct payloads.
1263
- RecursiveProperties properties;
1264
1308
for (auto elt : D->getAllElements ()) {
1265
1309
// No-payload elements do not affect any recursive properties.
1266
1310
if (!elt->hasAssociatedValues ())
@@ -1292,9 +1336,9 @@ namespace {
1292
1336
}
1293
1337
assert (props.isFixedABI ());
1294
1338
if (props.isTrivial ()) {
1295
- return handleTrivial (type);
1339
+ return handleTrivial (type, props );
1296
1340
}
1297
- return new (TC, Dependent) LoadableLoweringClass (type, Expansion);
1341
+ return new (TC, Dependent) LoadableLoweringClass (type, props, Expansion);
1298
1342
}
1299
1343
};
1300
1344
} // end anonymous namespace
@@ -1664,6 +1708,9 @@ getTypeLoweringForExpansion(TypeKey key,
1664
1708
if (!lowering->isResilient ()) {
1665
1709
// Don't try to refine the lowering for other resilience expansions if
1666
1710
// we don't expect to get a different lowering anyway.
1711
+ //
1712
+ // See LowerType::handleResilience() for the gory details; we only
1713
+ // set this flag if the type is resilient *and* inside our module.
1667
1714
return lowering;
1668
1715
}
1669
1716
0 commit comments