@@ -212,6 +212,17 @@ class SILFunction
212212 // / @_dynamicReplacement(for:) function.
213213 SILFunction *ReplacedFunction = nullptr ;
214214
215+ // / This SILFunction REFerences an ad-hoc protocol requirement witness in
216+ // / order to keep it alive, such that it main be obtained in IRGen. Without
217+ // / this explicit reference, the witness would seem not-used, and not be
218+ // / accessible for IRGen.
219+ // /
220+ // / Specifically, one such case is the DistributedTargetInvocationDecoder's
221+ // / 'decodeNextArgument' which must be retained, as it is only used from IRGen
222+ // / and such, appears as-if unused in SIL and would get optimized away.
223+ // TODO: Consider making this a general "references adhoc functions" and make it an array?
224+ SILFunction *RefAdHocRequirementFunction = nullptr ;
225+
215226 Identifier ObjCReplacementFor;
216227
217228 // / The head of a single-linked list of currently alive BasicBlockBitfield.
@@ -298,7 +309,7 @@ class SILFunction
298309
299310 // / Whether the implementation can be dynamically replaced.
300311 unsigned IsDynamicReplaceable : 1 ;
301-
312+
302313 // / If true, this indicates that a class method implementation will always be
303314 // / invoked with a `self` argument of the exact base class type.
304315 unsigned ExactSelfClass : 1 ;
@@ -466,16 +477,6 @@ class SILFunction
466477 ReplacedFunction = f;
467478 ReplacedFunction->incrementRefCount ();
468479 }
469-
470- SILFunction *getDistributedRecordArgumentFunction () const {
471- return ReplacedFunction;
472- }
473- void setDistributedRecordArgumentFunction (SILFunction *f) {
474- if (f == nullptr )
475- return ;
476- f->incrementRefCount ();
477- }
478-
479480 // / This function should only be called when SILFunctions are bulk deleted.
480481 void dropDynamicallyReplacedFunction () {
481482 if (!ReplacedFunction)
@@ -484,6 +485,27 @@ class SILFunction
484485 ReplacedFunction = nullptr ;
485486 }
486487
488+ SILFunction *getReferencedAdHocRequirementWitnessFunction () const {
489+ return RefAdHocRequirementFunction;
490+ }
491+ // Marks that this `SILFunction` uses the passed in ad-hoc protocol
492+ // requirement witness `f` and therefore must retain it explicitly,
493+ // otherwise we might not be able to get a reference to it.
494+ void setReferencedAdHocRequirementWitnessFunction (SILFunction *f) {
495+ assert (RefAdHocRequirementFunction == nullptr && " already set" );
496+
497+ if (f == nullptr )
498+ return ;
499+ RefAdHocRequirementFunction = f;
500+ RefAdHocRequirementFunction->incrementRefCount ();
501+ }
502+ void dropReferencedAdHocRequirementWitnessFunction () {
503+ if (!RefAdHocRequirementFunction)
504+ return ;
505+ RefAdHocRequirementFunction->decrementRefCount ();
506+ RefAdHocRequirementFunction = nullptr ;
507+ }
508+
487509 bool hasObjCReplacement () const {
488510 return !ObjCReplacementFor.empty ();
489511 }
@@ -758,7 +780,7 @@ class SILFunction
758780 IsDynamicReplaceable = value;
759781 assert (!Transparent || !IsDynamicReplaceable);
760782 }
761-
783+
762784 IsExactSelfClass_t isExactSelfClass () const {
763785 return IsExactSelfClass_t (ExactSelfClass);
764786 }
0 commit comments