@@ -162,6 +162,21 @@ struct SILDeclRef {
162162 AsyncEntryPoint,
163163 };
164164
165+ // / Represents the variants of a back deployable function.
166+ enum class BackDeploymentKind : unsigned {
167+ // / Default value. If a SILDecRef references a function that has been back
168+ // / deployed and has this back deployment kind, then it references the
169+ // / original ABI stable function.
170+ None,
171+ // / The thunk variant of a function that calls either the original function
172+ // / or the fallback variant if the original is unavailable. This thunk will
173+ // / be emitted with PublicNonABI linkage.
174+ Thunk,
175+ // / The fallback variant of the function. This function will be emitted with
176+ // / PublicNonABI linkage.
177+ Fallback,
178+ };
179+
165180 // / The AST node represented by this SILDeclRef.
166181 Loc loc;
167182 // / The Kind of this SILDeclRef.
@@ -170,6 +185,8 @@ struct SILDeclRef {
170185 unsigned isForeign : 1 ;
171186 // / True if this references a distributed function.
172187 unsigned isDistributed : 1 ;
188+ // / The BackDeploymentKind of this SILDeclRef.
189+ BackDeploymentKind backDeploymentKind : 2 ;
173190 // / The default argument index for a default argument getter.
174191 unsigned defaultArgIndex : 10 ;
175192
@@ -204,13 +221,15 @@ struct SILDeclRef {
204221
205222 // / Produces a null SILDeclRef.
206223 SILDeclRef ()
207- : loc(), kind(Kind::Func), isForeign(0 ), isDistributed(0 ), defaultArgIndex(0 ) {}
224+ : loc(), kind(Kind::Func), isForeign(0 ), isDistributed(0 ),
225+ backDeploymentKind (BackDeploymentKind::None), defaultArgIndex(0 ) {}
208226
209227 // / Produces a SILDeclRef of the given kind for the given decl.
210228 explicit SILDeclRef (
211229 ValueDecl *decl, Kind kind,
212230 bool isForeign = false ,
213231 bool isDistributed = false ,
232+ BackDeploymentKind backDeploymentKind = BackDeploymentKind::None,
214233 AutoDiffDerivativeFunctionIdentifier *derivativeId = nullptr );
215234
216235 // / Produces a SILDeclRef for the given ValueDecl or
@@ -224,7 +243,10 @@ struct SILDeclRef {
224243 // / for the containing ClassDecl.
225244 // / - If 'loc' is a global VarDecl, this returns its GlobalAccessor
226245 // / SILDeclRef.
227- explicit SILDeclRef (Loc loc, bool isForeign = false , bool isDistributed = false );
246+ explicit SILDeclRef (
247+ Loc loc,
248+ bool isForeign = false ,
249+ bool isDistributed = false );
228250
229251 // / See above put produces a prespecialization according to the signature.
230252 explicit SILDeclRef (Loc loc, GenericSignature prespecializationSig);
@@ -360,6 +382,7 @@ struct SILDeclRef {
360382 return loc.getOpaqueValue () == rhs.loc .getOpaqueValue () &&
361383 kind == rhs.kind && isForeign == rhs.isForeign &&
362384 isDistributed == rhs.isDistributed &&
385+ backDeploymentKind == rhs.backDeploymentKind &&
363386 defaultArgIndex == rhs.defaultArgIndex &&
364387 pointer == rhs.pointer ;
365388 }
@@ -378,6 +401,7 @@ struct SILDeclRef {
378401 return SILDeclRef (loc.getOpaqueValue (), kind,
379402 /* foreign=*/ foreign,
380403 /* distributed=*/ false ,
404+ backDeploymentKind,
381405 defaultArgIndex,
382406 pointer.get <AutoDiffDerivativeFunctionIdentifier *>());
383407 }
@@ -387,6 +411,16 @@ struct SILDeclRef {
387411 return SILDeclRef (loc.getOpaqueValue (), kind,
388412 /* foreign=*/ false ,
389413 /* distributed=*/ distributed,
414+ backDeploymentKind,
415+ defaultArgIndex,
416+ pointer.get <AutoDiffDerivativeFunctionIdentifier *>());
417+ }
418+ // / Returns a copy of the decl with the given back deployment kind.
419+ SILDeclRef asBackDeploymentKind (BackDeploymentKind backDeploymentKind) const {
420+ return SILDeclRef (loc.getOpaqueValue (), kind,
421+ isForeign,
422+ isDistributed,
423+ backDeploymentKind,
390424 defaultArgIndex,
391425 pointer.get <AutoDiffDerivativeFunctionIdentifier *>());
392426 }
@@ -431,6 +465,14 @@ struct SILDeclRef {
431465 // / True if the decl ref references a thunk handling potentially distributed actor functions
432466 bool isDistributedThunk () const ;
433467
468+ // / True if the decl ref references a thunk handling a call to a function that
469+ // / supports back deployment.
470+ bool isBackDeploymentThunk () const ;
471+
472+ // / True if the decl ref references a function that is the back deployment
473+ // / fallback for an original function which may be unavailable at runtime.
474+ bool isBackDeploymentFallback () const ;
475+
434476 // / True if the decl ref references a method which introduces a new vtable
435477 // / entry.
436478 bool requiresNewVTableEntry () const ;
@@ -508,10 +550,12 @@ struct SILDeclRef {
508550 explicit SILDeclRef (void *opaqueLoc, Kind kind,
509551 bool isForeign,
510552 bool isDistributed,
553+ BackDeploymentKind backDeploymentKind,
511554 unsigned defaultArgIndex,
512555 AutoDiffDerivativeFunctionIdentifier *derivativeId)
513556 : loc(Loc::getFromOpaqueValue(opaqueLoc)), kind(kind),
514557 isForeign(isForeign), isDistributed(isDistributed),
558+ backDeploymentKind(backDeploymentKind),
515559 defaultArgIndex(defaultArgIndex),
516560 pointer(derivativeId) {}
517561};
@@ -529,17 +573,18 @@ namespace llvm {
529573template <> struct DenseMapInfo <swift::SILDeclRef> {
530574 using SILDeclRef = swift::SILDeclRef;
531575 using Kind = SILDeclRef::Kind;
576+ using BackDeploymentKind = SILDeclRef::BackDeploymentKind;
532577 using Loc = SILDeclRef::Loc;
533578 using PointerInfo = DenseMapInfo<void *>;
534579 using UnsignedInfo = DenseMapInfo<unsigned >;
535580
536581 static SILDeclRef getEmptyKey () {
537- return SILDeclRef (PointerInfo::getEmptyKey (), Kind::Func, false , false , 0 ,
538- nullptr );
582+ return SILDeclRef (PointerInfo::getEmptyKey (), Kind::Func, false , false ,
583+ BackDeploymentKind::None, 0 , nullptr );
539584 }
540585 static SILDeclRef getTombstoneKey () {
541586 return SILDeclRef (PointerInfo::getTombstoneKey (), Kind::Func, false , false ,
542- 0 , nullptr );
587+ BackDeploymentKind::None, 0 , nullptr );
543588 }
544589 static unsigned getHashValue (swift::SILDeclRef Val) {
545590 unsigned h1 = PointerInfo::getHashValue (Val.loc .getOpaqueValue ());
@@ -550,7 +595,9 @@ template<> struct DenseMapInfo<swift::SILDeclRef> {
550595 unsigned h4 = UnsignedInfo::getHashValue (Val.isForeign );
551596 unsigned h5 = PointerInfo::getHashValue (Val.pointer .getOpaqueValue ());
552597 unsigned h6 = UnsignedInfo::getHashValue (Val.isDistributed );
553- return h1 ^ (h2 << 4 ) ^ (h3 << 9 ) ^ (h4 << 7 ) ^ (h5 << 11 ) ^ (h6 << 8 );
598+ unsigned h7 = UnsignedInfo::getHashValue (unsigned (Val.backDeploymentKind ));
599+ return h1 ^ (h2 << 4 ) ^ (h3 << 9 ) ^ (h4 << 7 ) ^ (h5 << 11 ) ^ (h6 << 8 ) ^
600+ (h7 << 10 );
554601 }
555602 static bool isEqual (swift::SILDeclRef const &LHS,
556603 swift::SILDeclRef const &RHS) {
0 commit comments