Skip to content

Commit 6f58233

Browse files
committed
[TypeLowering] Record whether a type is lexical.
Used RecursiveProperties to keep track of whether a type is lexical. This is done in the usual way by OR'ing together whether components are lexicial. The the values to be OR'd together come from primitives: everything is non-lexical except reference types and resilient types (because they could become reference types). Those values can however be affected by user annotations: marking a class @_lexical makes the value for that primitive lexical; markinig an enum or struct @_eagerMove overrides the value obtained by OR'ing together its components and makes it be non-lexical.
1 parent b3ae13d commit 6f58233

File tree

2 files changed

+107
-13
lines changed

2 files changed

+107
-13
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ enum IsInfiniteType_t : bool {
169169
IsInfiniteType = true,
170170
};
171171

172+
/// Does this type contain at least one non-trivial, non-eager-move type?
173+
enum IsLexical_t : bool {
174+
IsNotLexical = false,
175+
IsLexical = true,
176+
};
177+
172178
/// Extended type information used by SIL.
173179
class TypeLowering {
174180
public:
@@ -184,6 +190,7 @@ class TypeLowering {
184190
TypeExpansionSensitiveFlag = 1 << 4,
185191
InfiniteFlag = 1 << 5,
186192
HasRawPointerFlag = 1 << 6,
193+
LexicalFlag = 1 << 7,
187194
};
188195
// clang-format on
189196

@@ -198,13 +205,15 @@ class TypeLowering {
198205
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
199206
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
200207
IsNotTypeExpansionSensitive,
201-
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer)
208+
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer,
209+
IsLexical_t isLexical = IsNotLexical)
202210
: Flags((isTrivial ? 0U : NonTrivialFlag) |
203211
(isFixedABI ? 0U : NonFixedABIFlag) |
204212
(isAddressOnly ? AddressOnlyFlag : 0U) |
205213
(isResilient ? ResilientFlag : 0U) |
206214
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) |
207-
(hasRawPointer ? HasRawPointerFlag : 0U)) {}
215+
(hasRawPointer ? HasRawPointerFlag : 0U) |
216+
(isLexical ? LexicalFlag : 0U)) {}
208217

209218
constexpr bool operator==(RecursiveProperties p) const {
210219
return Flags == p.Flags;
@@ -220,11 +229,13 @@ class TypeLowering {
220229
}
221230

222231
static constexpr RecursiveProperties forReference() {
223-
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
232+
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient,
233+
IsNotTypeExpansionSensitive, DoesNotHaveRawPointer, IsLexical};
224234
}
225235

226236
static constexpr RecursiveProperties forOpaque() {
227-
return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsNotResilient};
237+
return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsNotResilient,
238+
IsNotTypeExpansionSensitive, DoesNotHaveRawPointer, IsLexical};
228239
}
229240

230241
static constexpr RecursiveProperties forResilient() {
@@ -257,6 +268,9 @@ class TypeLowering {
257268
IsInfiniteType_t isInfinite() const {
258269
return IsInfiniteType_t((Flags & InfiniteFlag) != 0);
259270
}
271+
IsLexical_t isLexical() const {
272+
return IsLexical_t((Flags & LexicalFlag) != 0);
273+
}
260274

261275
void setNonTrivial() { Flags |= NonTrivialFlag; }
262276
void setNonFixedABI() { Flags |= NonFixedABIFlag; }
@@ -267,6 +281,9 @@ class TypeLowering {
267281
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0);
268282
}
269283
void setInfinite() { Flags |= InfiniteFlag; }
284+
void setLexical(IsLexical_t isLexical) {
285+
Flags = (Flags & ~LexicalFlag) | (isLexical ? LexicalFlag : 0);
286+
}
270287
};
271288

272289
private:
@@ -368,6 +385,11 @@ class TypeLowering {
368385
return Properties.isTypeExpansionSensitive();
369386
}
370387

388+
/// Should a value of this type have its lifetime tied to its lexical scope?
389+
bool isLexical() const {
390+
return Properties.isLexical();
391+
}
392+
371393
ResilienceExpansion getResilienceExpansion() const {
372394
return expansionContext.getResilienceExpansion();
373395
}

lib/SIL/IR/TypeLowering.cpp

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,21 @@ namespace {
232232
return props;
233233
}
234234

235+
RecursiveProperties applyLifetimeAnnotation(LifetimeAnnotation annotation,
236+
RecursiveProperties props) {
237+
switch (annotation) {
238+
case LifetimeAnnotation::None:
239+
break;
240+
case LifetimeAnnotation::Lexical:
241+
props.setLexical(IsLexical);
242+
break;
243+
case LifetimeAnnotation::EagerMove:
244+
props.setLexical(IsNotLexical);
245+
break;
246+
}
247+
return props;
248+
}
249+
235250
RecursiveProperties
236251
getTrivialRecursiveProperties(IsTypeExpansionSensitive_t isSensitive) {
237252
return mergeIsTypeExpansionSensitive(isSensitive,
@@ -267,8 +282,6 @@ namespace {
267282
IMPL(BuiltinBridgeObject, Reference)
268283
IMPL(BuiltinVector, Trivial)
269284
IMPL(SILToken, Trivial)
270-
IMPL(Class, Reference)
271-
IMPL(BoundGenericClass, Reference)
272285
IMPL(AnyMetatype, Trivial)
273286
IMPL(Module, Trivial)
274287

@@ -288,7 +301,9 @@ namespace {
288301
IsTypeExpansionSensitive_t isSensitive) {
289302
return asImpl().handleAddressOnly(type, {IsNotTrivial, IsFixedABI,
290303
IsAddressOnly, IsNotResilient,
291-
isSensitive});
304+
isSensitive,
305+
DoesNotHaveRawPointer,
306+
IsLexical});
292307
}
293308

294309
RetTy visitBuiltinDefaultActorStorageType(
@@ -297,7 +312,9 @@ namespace {
297312
IsTypeExpansionSensitive_t isSensitive) {
298313
return asImpl().handleAddressOnly(type, {IsNotTrivial, IsFixedABI,
299314
IsAddressOnly, IsNotResilient,
300-
isSensitive});
315+
isSensitive,
316+
DoesNotHaveRawPointer,
317+
IsLexical});
301318
}
302319

303320
RetTy visitAnyFunctionType(CanAnyFunctionType type,
@@ -479,7 +496,9 @@ namespace {
479496
IsFixedABI, \
480497
IsAddressOnly, \
481498
IsNotResilient, \
482-
isSensitive}); \
499+
isSensitive, \
500+
DoesNotHaveRawPointer, \
501+
IsLexical}); \
483502
}
484503
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
485504
RetTy visit##Name##StorageType(Can##Name##StorageType type, \
@@ -502,7 +521,9 @@ namespace {
502521
IsFixedABI, \
503522
IsAddressOnly, \
504523
IsNotResilient, \
505-
isSensitive}); \
524+
isSensitive, \
525+
DoesNotHaveRawPointer, \
526+
IsLexical}); \
506527
} \
507528
RetTy visit##Name##StorageType(Can##Name##StorageType type, \
508529
AbstractionPattern origType, \
@@ -579,7 +600,9 @@ namespace {
579600
IsFixedABI,
580601
IsAddressOnly,
581602
IsNotResilient,
582-
isSensitive});
603+
isSensitive,
604+
DoesNotHaveRawPointer,
605+
IsLexical});
583606
// Class-constrained and boxed existentials are refcounted.
584607
case ExistentialRepresentation::Class:
585608
case ExistentialRepresentation::Boxed:
@@ -608,6 +631,20 @@ namespace {
608631
return visitExistentialType(type, origType, isSensitive);
609632
}
610633

634+
// Classes depend on their attributes.
635+
RetTy visitClassType(CanClassType type, AbstractionPattern origType,
636+
IsTypeExpansionSensitive_t isSensitive) {
637+
return asImpl().visitAnyClassType(type, origType, type->getDecl(),
638+
isSensitive);
639+
}
640+
641+
RetTy visitBoundGenericClassType(CanBoundGenericClassType type,
642+
AbstractionPattern origType,
643+
IsTypeExpansionSensitive_t isSensitive) {
644+
return asImpl().visitAnyClassType(type, origType, type->getDecl(),
645+
isSensitive);
646+
}
647+
611648
// Enums depend on their enumerators.
612649
RetTy visitEnumType(CanEnumType type, AbstractionPattern origType,
613650
IsTypeExpansionSensitive_t isSensitive) {
@@ -671,7 +708,9 @@ namespace {
671708
IsFixedABI,
672709
IsAddressOnly,
673710
IsNotResilient,
674-
isSensitive});
711+
isSensitive,
712+
DoesNotHaveRawPointer,
713+
IsLexical});
675714
}
676715

677716
RetTy visitSILBoxType(CanSILBoxType type,
@@ -723,6 +762,14 @@ namespace {
723762
return properties;
724763
}
725764

765+
RecursiveProperties
766+
visitAnyClassType(CanType type, AbstractionPattern origType, ClassDecl *D,
767+
IsTypeExpansionSensitive_t isSensitive) {
768+
// Consult the type lowering.
769+
auto &lowering = TC.getTypeLowering(origType, type, Expansion);
770+
return handleClassificationFromLowering(type, lowering, isSensitive);
771+
}
772+
726773
RecursiveProperties visitAnyEnumType(CanType type,
727774
AbstractionPattern origType,
728775
EnumDecl *D,
@@ -1743,7 +1790,8 @@ namespace {
17431790
IsTypeExpansionSensitive_t isSensitive)
17441791
: AddressOnlyTypeLowering(type,
17451792
{IsNotTrivial, IsFixedABI,
1746-
IsAddressOnly, IsNotResilient, isSensitive},
1793+
IsAddressOnly, IsNotResilient, isSensitive,
1794+
DoesNotHaveRawPointer, IsLexical},
17471795
forExpansion) {}
17481796

17491797
void emitCopyInto(SILBuilder &B, SILLocation loc,
@@ -2019,6 +2067,18 @@ namespace {
20192067
return false;
20202068
}
20212069

2070+
TypeLowering *visitAnyClassType(CanType classType,
2071+
AbstractionPattern origType, ClassDecl *C,
2072+
IsTypeExpansionSensitive_t isSensitive) {
2073+
RecursiveProperties properties =
2074+
getReferenceRecursiveProperties(isSensitive);
2075+
2076+
if (C->getLifetimeAnnotation() == LifetimeAnnotation::EagerMove)
2077+
properties.setLexical(IsNotLexical);
2078+
2079+
return handleReference(classType, properties);
2080+
}
2081+
20222082
TypeLowering *visitAnyStructType(CanType structType,
20232083
AbstractionPattern origType,
20242084
StructDecl *D,
@@ -2061,8 +2121,14 @@ namespace {
20612121

20622122
properties.addSubobject(classifyType(origFieldType, substFieldType,
20632123
TC, Expansion));
2124+
properties =
2125+
applyLifetimeAnnotation(field->getLifetimeAnnotation(), properties);
20642126
}
20652127

2128+
// Type-level annotations override inferred behavior.
2129+
properties =
2130+
applyLifetimeAnnotation(D->getLifetimeAnnotation(), properties);
2131+
20662132
return handleAggregateByProperties<LoadableStructTypeLowering>(structType,
20672133
properties);
20682134
}
@@ -2119,8 +2185,14 @@ namespace {
21192185
->getReducedType(D->getGenericSignature()));
21202186
properties.addSubobject(classifyType(origEltType, substEltType,
21212187
TC, Expansion));
2188+
properties =
2189+
applyLifetimeAnnotation(elt->getLifetimeAnnotation(), properties);
21222190
}
21232191

2192+
// Type-level annotations override inferred behavior.
2193+
properties =
2194+
applyLifetimeAnnotation(D->getLifetimeAnnotation(), properties);
2195+
21242196
return handleAggregateByProperties<LoadableEnumTypeLowering>(enumType,
21252197
properties);
21262198
}

0 commit comments

Comments
 (0)