@@ -144,14 +144,58 @@ class FunctionTypeIsolation {
144144// / are significantly reduced compared to AST function types.
145145// / Isolation is not part of the SIL function model after the
146146// / early portion of the pipeline.
147- enum class SILFunctionTypeIsolation {
148- // / We don't normally record isolation in SIL function types,
149- // / so the empty case here is "unknown".
150- Unknown,
151-
152- // / The isolation of the function has been statically erased.
153- // / This corresponds to @isolated(any).
154- Erased,
147+ class SILFunctionTypeIsolation {
148+ public:
149+ enum Kind : uint8_t {
150+ // / We don't normally record isolation in SIL function types,
151+ // / so the empty case here is "unknown".
152+ Unknown,
153+
154+ // / The isolation of the function has been statically erased.
155+ // / This corresponds to @isolated(any).
156+ Erased,
157+ };
158+
159+ static constexpr size_t NumBits = 3 ; // future-proof this slightly
160+ static constexpr uintptr_t Mask = (uintptr_t (1 ) << NumBits) - 1 ;
161+
162+ private:
163+ // We do not use a pointer int pair, since it is not a literal type.
164+ llvm::PointerIntPair<CanType, NumBits, Kind> value;
165+
166+ SILFunctionTypeIsolation (Kind kind, CanType type = CanType())
167+ : value(type, kind) {}
168+
169+ public:
170+ static SILFunctionTypeIsolation forUnknown () { return {Kind::Unknown}; }
171+
172+ static SILFunctionTypeIsolation forErased () { return {Kind::Erased}; }
173+
174+ bool operator ==(const SILFunctionTypeIsolation &other) const {
175+ if (getKind () != other.getKind ())
176+ return false ;
177+
178+ switch (getKind ()) {
179+ case Kind::Unknown:
180+ case Kind::Erased:
181+ return true ;
182+ }
183+ }
184+
185+ Kind getKind () const { return value.getInt (); }
186+
187+ bool isUnknown () const { return getKind () == Kind::Unknown; }
188+ bool isErased () const { return getKind () == Kind::Erased; }
189+
190+ // The opaque accessors below are just for the benefit of SILExtInfoBuilder,
191+ // which finds it convenient to break down the type separately. Normal
192+ // clients should use the accessors above.
193+
194+ CanType getOpaqueType () const { return value.getPointer (); }
195+
196+ static SILFunctionTypeIsolation fromOpaqueValues (Kind kind, CanType type) {
197+ return SILFunctionTypeIsolation (kind, type);
198+ }
155199};
156200
157201// MARK: - ClangTypeInfo
@@ -967,17 +1011,16 @@ class SILExtInfoBuilder {
9671011 : bits(bits), clangTypeInfo(clangTypeInfo.getCanonical()),
9681012 lifetimeDependencies (lifetimeDependencies) {}
9691013
970- static constexpr unsigned makeBits (Representation rep, bool isPseudogeneric,
971- bool isNoEscape, bool isSendable,
972- bool isAsync, bool isUnimplementable,
973- SILFunctionTypeIsolation isolation,
974- DifferentiabilityKind diffKind) {
1014+ static unsigned makeBits (Representation rep, bool isPseudogeneric,
1015+ bool isNoEscape, bool isSendable, bool isAsync ,
1016+ bool isUnimplementable,
1017+ SILFunctionTypeIsolation isolation,
1018+ DifferentiabilityKind diffKind) {
9751019 return ((unsigned )rep) | (isPseudogeneric ? PseudogenericMask : 0 ) |
9761020 (isNoEscape ? NoEscapeMask : 0 ) | (isSendable ? SendableMask : 0 ) |
9771021 (isAsync ? AsyncMask : 0 ) |
9781022 (isUnimplementable ? UnimplementableMask : 0 ) |
979- (isolation == SILFunctionTypeIsolation::Erased ? ErasedIsolationMask
980- : 0 ) |
1023+ (isolation.isErased () ? ErasedIsolationMask : 0 ) |
9811024 (((unsigned )diffKind << DifferentiabilityMaskOffset) &
9821025 DifferentiabilityMask);
9831026 }
@@ -988,7 +1031,7 @@ class SILExtInfoBuilder {
9881031 SILExtInfoBuilder ()
9891032 : SILExtInfoBuilder(
9901033 makeBits (SILFunctionTypeRepresentation::Thick, false , false , false ,
991- false , false , SILFunctionTypeIsolation::Unknown ,
1034+ false , false , SILFunctionTypeIsolation::forUnknown() ,
9921035 DifferentiabilityKind::NonDifferentiable),
9931036 ClangTypeInfo(nullptr ), /* LifetimeDependenceInfo*/ std::nullopt) {}
9941037
@@ -1008,8 +1051,8 @@ class SILExtInfoBuilder {
10081051 info.isNoEscape(), info.isSendable(),
10091052 info.isAsync(), /* unimplementable*/ false,
10101053 info.getIsolation().isErased()
1011- ? SILFunctionTypeIsolation::Erased
1012- : SILFunctionTypeIsolation::Unknown ,
1054+ ? SILFunctionTypeIsolation::forErased()
1055+ : SILFunctionTypeIsolation::forUnknown() ,
10131056 info.getDifferentiabilityKind()),
10141057 info.getClangTypeInfo(),
10151058 info.getLifetimeDependencies()) {}
@@ -1059,10 +1102,9 @@ class SILExtInfoBuilder {
10591102 return bits & ErasedIsolationMask;
10601103 }
10611104
1062- constexpr SILFunctionTypeIsolation getIsolation () const {
1063- return hasErasedIsolation ()
1064- ? SILFunctionTypeIsolation::Erased
1065- : SILFunctionTypeIsolation::Unknown;
1105+ SILFunctionTypeIsolation getIsolation () const {
1106+ return hasErasedIsolation () ? SILFunctionTypeIsolation::forErased ()
1107+ : SILFunctionTypeIsolation::forUnknown ();
10661108 }
10671109
10681110 // / Get the underlying ClangTypeInfo value.
@@ -1157,7 +1199,7 @@ class SILExtInfoBuilder {
11571199 }
11581200 [[nodiscard]]
11591201 SILExtInfoBuilder withIsolation (SILFunctionTypeIsolation isolation) const {
1160- switch (isolation) {
1202+ switch (isolation. getKind () ) {
11611203 case SILFunctionTypeIsolation::Unknown:
11621204 return *this ;
11631205 case SILFunctionTypeIsolation::Erased:
@@ -1241,7 +1283,7 @@ class SILExtInfo {
12411283 static SILExtInfo getThin () {
12421284 return SILExtInfoBuilder (
12431285 SILExtInfoBuilder::Representation::Thin, false , false , false ,
1244- false , false , SILFunctionTypeIsolation::Unknown ,
1286+ false , false , SILFunctionTypeIsolation::forUnknown () ,
12451287 DifferentiabilityKind::NonDifferentiable, nullptr , {})
12461288 .build ();
12471289 }
@@ -1276,7 +1318,7 @@ class SILExtInfo {
12761318 constexpr bool hasErasedIsolation () const {
12771319 return builder.hasErasedIsolation ();
12781320 }
1279- constexpr SILFunctionTypeIsolation getIsolation () const {
1321+ SILFunctionTypeIsolation getIsolation () const {
12801322 return builder.getIsolation ();
12811323 }
12821324
0 commit comments