-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Support inlinability with [serialized_for_package] #73754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -364,11 +364,7 @@ class SILFunction | |
unsigned Transparent : 1; | ||
|
||
/// The function's serialized attribute. | ||
bool Serialized : 1; | ||
|
||
/// [serialized_for_package] attribute if package serialization | ||
/// is enabled. | ||
bool SerializedForPackage : 1; | ||
unsigned SerializedKind : 2; | ||
|
||
/// Specifies if this function is a thunk or a reabstraction thunk. | ||
/// | ||
|
@@ -508,7 +504,7 @@ class SILFunction | |
SILFunction(SILModule &module, SILLinkage linkage, StringRef mangledName, | ||
CanSILFunctionType loweredType, GenericEnvironment *genericEnv, | ||
IsBare_t isBareSILFunction, IsTransparent_t isTrans, | ||
IsSerialized_t isSerialized, ProfileCounter entryCount, | ||
SerializedKind_t serializedKind, ProfileCounter entryCount, | ||
IsThunk_t isThunk, SubclassScope classSubclassScope, | ||
Inline_t inlineStrategy, EffectsKind E, | ||
const SILDebugScope *debugScope, | ||
|
@@ -521,7 +517,7 @@ class SILFunction | |
create(SILModule &M, SILLinkage linkage, StringRef name, | ||
CanSILFunctionType loweredType, GenericEnvironment *genericEnv, | ||
std::optional<SILLocation> loc, IsBare_t isBareSILFunction, | ||
IsTransparent_t isTrans, IsSerialized_t isSerialized, | ||
IsTransparent_t isTrans, SerializedKind_t serializedKind, | ||
ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic, | ||
IsDistributed_t isDistributed, | ||
IsRuntimeAccessible_t isRuntimeAccessible, | ||
|
@@ -534,7 +530,7 @@ class SILFunction | |
|
||
void init(SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType, | ||
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction, | ||
IsTransparent_t isTrans, IsSerialized_t isSerialized, | ||
IsTransparent_t isTrans, SerializedKind_t serializedKind, | ||
ProfileCounter entryCount, IsThunk_t isThunk, | ||
SubclassScope classSubclassScope, Inline_t inlineStrategy, | ||
EffectsKind E, const SILDebugScope *DebugScope, | ||
|
@@ -877,13 +873,42 @@ class SILFunction | |
/// Set the function's linkage attribute. | ||
void setLinkage(SILLinkage linkage) { Linkage = unsigned(linkage); } | ||
|
||
/// Returns true if this function can be inlined into a fragile function | ||
/// body. | ||
bool hasValidLinkageForFragileInline() const { return isSerialized(); } | ||
/// Checks if this (callee) function body can be inlined into the caller | ||
/// by comparing their SerializedKind_t values. | ||
/// | ||
/// If the \p assumeFragileCaller is true, the caller must be serialized, | ||
/// in which case the callee needs to be serialized also to be inlined. | ||
/// If both callee and caller are `not_serialized`, the callee can be inlined | ||
/// into the caller during SIL inlining passes even if it (and the caller) | ||
/// might contain private symbols. If this callee is `serialized_for_pkg`, | ||
/// it can only be referenced by a serialized caller but not inlined into | ||
/// it. | ||
/// | ||
/// ``` | ||
/// canInlineInto: Caller | ||
/// | not_serialized | serialized_for_pkg | serialized | ||
/// not_serialized | ok | no | no | ||
/// Callee serialized_for_pkg | ok | ok | no | ||
/// serialized | ok | ok | ok | ||
/// | ||
/// ``` | ||
/// | ||
/// \p callerSerializedKind The caller's SerializedKind. | ||
/// \p assumeFragileCaller True if the call site of this function already | ||
/// knows that the caller is serialized. | ||
bool canBeInlinedIntoCaller( | ||
std::optional<SerializedKind_t> callerSerializedKind = std::nullopt, | ||
bool assumeFragileCaller = true) const; | ||
|
||
/// Returns true if this function can be referenced from a fragile function | ||
/// body. | ||
bool hasValidLinkageForFragileRef() const; | ||
/// \p callerSerializedKind The caller's SerializedKind. Used to be passed to | ||
/// \c canBeInlinedIntoCaller. | ||
/// \p assumeFragileCaller Default to true since this function must be called | ||
// if the caller is [serialized]. | ||
bool hasValidLinkageForFragileRef( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should remove the optional here and always pass the referencing entity's SerializationKind_t. It can come from the enclosing/referencing abstraction: function, v-table, witness table, property, movedeinit. |
||
std::optional<SerializedKind_t> callerSerializedKind = std::nullopt, | ||
bool assumeFragileCaller = true) const; | ||
|
||
/// Get's the effective linkage which is used to derive the llvm linkage. | ||
/// Usually this is the same as getLinkage(), except in one case: if this | ||
|
@@ -1137,28 +1162,24 @@ class SILFunction | |
assert(!Transparent || !IsDynamicReplaceable); | ||
} | ||
|
||
/// Get this function's serialized attribute. | ||
IsSerialized_t isSerialized() const { return IsSerialized_t(Serialized); } | ||
void setSerialized(IsSerialized_t isSerialized) { | ||
Serialized = isSerialized; | ||
assert(this->isSerialized() == isSerialized && | ||
"too few bits for Serialized storage"); | ||
bool isSerialized() const { | ||
return SerializedKind_t(SerializedKind) == IsSerialized; | ||
} | ||
bool isSerializedForPackage() const { | ||
return SerializedKind_t(SerializedKind) == IsSerializedForPackage; | ||
} | ||
bool isNotSerialized() const { | ||
return SerializedKind_t(SerializedKind) == IsNotSerialized; | ||
} | ||
|
||
/// A [serialized_for_package] attribute is used to indicate that a function | ||
/// is [serialized] because of package-cmo optimization. | ||
/// Package-cmo allows serializing a function containing a loadable type in | ||
/// a resiliently built module, which is normally illegal. During SIL deserialization, | ||
/// this attribute can be used to check whether a loaded function that was serialized | ||
/// can be allowed to have loadable types. This attribute is also used to determine | ||
/// if a callee can be inlined into a caller that's serialized without package-cmo, for | ||
/// example, by explicitly annotating the caller decl with `@inlinable`. | ||
IsSerializedForPackage_t isSerializedForPackage() const { | ||
return IsSerializedForPackage_t(SerializedForPackage); | ||
/// Get this function's serialized attribute. | ||
SerializedKind_t getSerializedKind() const { | ||
return SerializedKind_t(SerializedKind); | ||
} | ||
void | ||
setSerializedForPackage(IsSerializedForPackage_t isSerializedForPackage) { | ||
SerializedForPackage = isSerializedForPackage; | ||
void setSerializedKind(SerializedKind_t serializedKind) { | ||
SerializedKind = serializedKind; | ||
assert(this->getSerializedKind() == serializedKind && | ||
"too few bits for Serialized storage"); | ||
} | ||
|
||
/// Get this function's thunk attribute. | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a follow-up PR we should also introduce a predicate:
bool isAnySerializedKind()
.The places where we now have to write double negation
!isNotSerialized()
are really hard to read. At least for my senile brains.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already on it in an upcoming PR; I agree it's illegible for me too :)