@@ -364,11 +364,7 @@ class SILFunction
364364 unsigned Transparent : 1 ;
365365
366366 // / The function's serialized attribute.
367- bool Serialized : 1 ;
368-
369- // / [serialized_for_package] attribute if package serialization
370- // / is enabled.
371- bool SerializedForPackage : 1 ;
367+ unsigned SerializedKind : 2 ;
372368
373369 // / Specifies if this function is a thunk or a reabstraction thunk.
374370 // /
@@ -508,7 +504,7 @@ class SILFunction
508504 SILFunction (SILModule &module , SILLinkage linkage, StringRef mangledName,
509505 CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
510506 IsBare_t isBareSILFunction, IsTransparent_t isTrans,
511- IsSerialized_t isSerialized , ProfileCounter entryCount,
507+ SerializedKind_t serializedKind , ProfileCounter entryCount,
512508 IsThunk_t isThunk, SubclassScope classSubclassScope,
513509 Inline_t inlineStrategy, EffectsKind E,
514510 const SILDebugScope *debugScope,
@@ -521,7 +517,7 @@ class SILFunction
521517 create (SILModule &M, SILLinkage linkage, StringRef name,
522518 CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
523519 std::optional<SILLocation> loc, IsBare_t isBareSILFunction,
524- IsTransparent_t isTrans, IsSerialized_t isSerialized ,
520+ IsTransparent_t isTrans, SerializedKind_t serializedKind ,
525521 ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
526522 IsDistributed_t isDistributed,
527523 IsRuntimeAccessible_t isRuntimeAccessible,
@@ -534,7 +530,7 @@ class SILFunction
534530
535531 void init (SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
536532 GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,
537- IsTransparent_t isTrans, IsSerialized_t isSerialized ,
533+ IsTransparent_t isTrans, SerializedKind_t serializedKind ,
538534 ProfileCounter entryCount, IsThunk_t isThunk,
539535 SubclassScope classSubclassScope, Inline_t inlineStrategy,
540536 EffectsKind E, const SILDebugScope *DebugScope,
@@ -877,13 +873,42 @@ class SILFunction
877873 // / Set the function's linkage attribute.
878874 void setLinkage (SILLinkage linkage) { Linkage = unsigned (linkage); }
879875
880- // / Returns true if this function can be inlined into a fragile function
881- // / body.
882- bool hasValidLinkageForFragileInline () const { return isSerialized (); }
876+ // / Checks if this (callee) function body can be inlined into the caller
877+ // / by comparing their SerializedKind_t values.
878+ // /
879+ // / If the \p assumeFragileCaller is true, the caller must be serialized,
880+ // / in which case the callee needs to be serialized also to be inlined.
881+ // / If both callee and caller are `not_serialized`, the callee can be inlined
882+ // / into the caller during SIL inlining passes even if it (and the caller)
883+ // / might contain private symbols. If this callee is `serialized_for_pkg`,
884+ // / it can only be referenced by a serialized caller but not inlined into
885+ // / it.
886+ // /
887+ // / ```
888+ // / canInlineInto: Caller
889+ // / | not_serialized | serialized_for_pkg | serialized
890+ // / not_serialized | ok | no | no
891+ // / Callee serialized_for_pkg | ok | ok | no
892+ // / serialized | ok | ok | ok
893+ // /
894+ // / ```
895+ // /
896+ // / \p callerSerializedKind The caller's SerializedKind.
897+ // / \p assumeFragileCaller True if the call site of this function already
898+ // / knows that the caller is serialized.
899+ bool canBeInlinedIntoCaller (
900+ std::optional<SerializedKind_t> callerSerializedKind = std::nullopt ,
901+ bool assumeFragileCaller = true ) const ;
883902
884903 // / Returns true if this function can be referenced from a fragile function
885904 // / body.
886- bool hasValidLinkageForFragileRef () const ;
905+ // / \p callerSerializedKind The caller's SerializedKind. Used to be passed to
906+ // / \c canBeInlinedIntoCaller.
907+ // / \p assumeFragileCaller Default to true since this function must be called
908+ // if the caller is [serialized].
909+ bool hasValidLinkageForFragileRef (
910+ std::optional<SerializedKind_t> callerSerializedKind = std::nullopt ,
911+ bool assumeFragileCaller = true ) const ;
887912
888913 // / Get's the effective linkage which is used to derive the llvm linkage.
889914 // / Usually this is the same as getLinkage(), except in one case: if this
@@ -1137,28 +1162,24 @@ class SILFunction
11371162 assert (!Transparent || !IsDynamicReplaceable);
11381163 }
11391164
1140- // / Get this function's serialized attribute.
1141- IsSerialized_t isSerialized () const { return IsSerialized_t (Serialized); }
1142- void setSerialized (IsSerialized_t isSerialized) {
1143- Serialized = isSerialized;
1144- assert (this ->isSerialized () == isSerialized &&
1145- " too few bits for Serialized storage" );
1165+ bool isSerialized () const {
1166+ return SerializedKind_t (SerializedKind) == IsSerialized;
1167+ }
1168+ bool isSerializedForPackage () const {
1169+ return SerializedKind_t (SerializedKind) == IsSerializedForPackage;
1170+ }
1171+ bool isNotSerialized () const {
1172+ return SerializedKind_t (SerializedKind) == IsNotSerialized;
11461173 }
11471174
1148- // / A [serialized_for_package] attribute is used to indicate that a function
1149- // / is [serialized] because of package-cmo optimization.
1150- // / Package-cmo allows serializing a function containing a loadable type in
1151- // / a resiliently built module, which is normally illegal. During SIL deserialization,
1152- // / this attribute can be used to check whether a loaded function that was serialized
1153- // / can be allowed to have loadable types. This attribute is also used to determine
1154- // / if a callee can be inlined into a caller that's serialized without package-cmo, for
1155- // / example, by explicitly annotating the caller decl with `@inlinable`.
1156- IsSerializedForPackage_t isSerializedForPackage () const {
1157- return IsSerializedForPackage_t (SerializedForPackage);
1175+ // / Get this function's serialized attribute.
1176+ SerializedKind_t getSerializedKind () const {
1177+ return SerializedKind_t (SerializedKind);
11581178 }
1159- void
1160- setSerializedForPackage (IsSerializedForPackage_t isSerializedForPackage) {
1161- SerializedForPackage = isSerializedForPackage;
1179+ void setSerializedKind (SerializedKind_t serializedKind) {
1180+ SerializedKind = serializedKind;
1181+ assert (this ->getSerializedKind () == serializedKind &&
1182+ " too few bits for Serialized storage" );
11621183 }
11631184
11641185 // / Get this function's thunk attribute.
0 commit comments