@@ -364,11 +364,7 @@ class SILFunction
364
364
unsigned Transparent : 1 ;
365
365
366
366
// / 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 ;
372
368
373
369
// / Specifies if this function is a thunk or a reabstraction thunk.
374
370
// /
@@ -508,7 +504,7 @@ class SILFunction
508
504
SILFunction (SILModule &module, SILLinkage linkage, StringRef mangledName,
509
505
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
510
506
IsBare_t isBareSILFunction, IsTransparent_t isTrans,
511
- IsSerialized_t isSerialized , ProfileCounter entryCount,
507
+ SerializedKind_t serializedKind , ProfileCounter entryCount,
512
508
IsThunk_t isThunk, SubclassScope classSubclassScope,
513
509
Inline_t inlineStrategy, EffectsKind E,
514
510
const SILDebugScope *debugScope,
@@ -521,7 +517,7 @@ class SILFunction
521
517
create (SILModule &M, SILLinkage linkage, StringRef name,
522
518
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
523
519
std::optional<SILLocation> loc, IsBare_t isBareSILFunction,
524
- IsTransparent_t isTrans, IsSerialized_t isSerialized ,
520
+ IsTransparent_t isTrans, SerializedKind_t serializedKind ,
525
521
ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
526
522
IsDistributed_t isDistributed,
527
523
IsRuntimeAccessible_t isRuntimeAccessible,
@@ -534,7 +530,7 @@ class SILFunction
534
530
535
531
void init (SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
536
532
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,
537
- IsTransparent_t isTrans, IsSerialized_t isSerialized ,
533
+ IsTransparent_t isTrans, SerializedKind_t serializedKind ,
538
534
ProfileCounter entryCount, IsThunk_t isThunk,
539
535
SubclassScope classSubclassScope, Inline_t inlineStrategy,
540
536
EffectsKind E, const SILDebugScope *DebugScope,
@@ -877,13 +873,42 @@ class SILFunction
877
873
// / Set the function's linkage attribute.
878
874
void setLinkage (SILLinkage linkage) { Linkage = unsigned (linkage); }
879
875
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 ;
883
902
884
903
// / Returns true if this function can be referenced from a fragile function
885
904
// / 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 ;
887
912
888
913
// / Get's the effective linkage which is used to derive the llvm linkage.
889
914
// / Usually this is the same as getLinkage(), except in one case: if this
@@ -1137,28 +1162,24 @@ class SILFunction
1137
1162
assert (!Transparent || !IsDynamicReplaceable);
1138
1163
}
1139
1164
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;
1146
1173
}
1147
1174
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);
1158
1178
}
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" );
1162
1183
}
1163
1184
1164
1185
// / Get this function's thunk attribute.
0 commit comments