diff --git a/include/swift/SIL/GenericSpecializationMangler.h b/include/swift/SIL/GenericSpecializationMangler.h index 76e2d82bdee27..84e62f6377fee 100644 --- a/include/swift/SIL/GenericSpecializationMangler.h +++ b/include/swift/SIL/GenericSpecializationMangler.h @@ -37,7 +37,7 @@ class SpecializationMangler : public Mangle::ASTMangler { /// The specialization pass. SpecializationPass Pass; - IsSerialized_t Serialized; + swift::SerializedKind_t Serialized; /// The original function which is specialized. SILFunction *Function; @@ -50,12 +50,12 @@ class SpecializationMangler : public Mangle::ASTMangler { PossibleEffects RemovedEffects; protected: - SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized, + SpecializationMangler(SpecializationPass P, swift::SerializedKind_t Serialized, SILFunction *F) : Pass(P), Serialized(Serialized), Function(F), ArgOpBuffer(ArgOpStorage) {} - SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized, + SpecializationMangler(SpecializationPass P, swift::SerializedKind_t Serialized, std::string functionName) : Pass(P), Serialized(Serialized), Function(nullptr), FunctionName(functionName), ArgOpBuffer(ArgOpStorage) {} @@ -88,7 +88,7 @@ class GenericSpecializationMangler : public SpecializationMangler { SubstitutionMap subs); public: - GenericSpecializationMangler(SILFunction *F, IsSerialized_t Serialized) + GenericSpecializationMangler(SILFunction *F, swift::SerializedKind_t Serialized) : SpecializationMangler(SpecializationPass::GenericSpecializer, Serialized, F) {} diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h index 60619ec108982..3eaef1aebe2db 100644 --- a/include/swift/SIL/SILDeclRef.h +++ b/include/swift/SIL/SILDeclRef.h @@ -46,7 +46,7 @@ namespace swift { class EffectsAttr; class FileUnit; class SILFunctionType; - enum IsSerialized_t : unsigned char; + enum SerializedKind_t : uint8_t; enum class SubclassScope : unsigned char; class SILModule; class SILLocation; @@ -384,7 +384,11 @@ struct SILDeclRef { /// True if the function should be treated as transparent. bool isTransparent() const; /// True if the function should have its body serialized. - IsSerialized_t isSerialized() const; + bool isSerialized() const; + /// True if this function is neither [serialized] or [serialized_for_package]. + bool isNotSerialized() const; + /// Returns IsNotSerialized, IsSerializedForPackage, or IsSerialized. + SerializedKind_t getSerializedKind() const; /// True if the function has noinline attribute. bool isNoinline() const; /// True if the function has __always inline attribute. diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index 9c42fcdfb5ed4..ab1688ff8526d 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -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 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 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( + std::optional 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. diff --git a/include/swift/SIL/SILFunctionBuilder.h b/include/swift/SIL/SILFunctionBuilder.h index 37b75853e9974..a4d28b953d0f0 100644 --- a/include/swift/SIL/SILFunctionBuilder.h +++ b/include/swift/SIL/SILFunctionBuilder.h @@ -60,24 +60,19 @@ class SILFunctionBuilder { /// Return the declaration of a utility function that can, but needn't, be /// shared between different parts of a program. - SILFunction *getOrCreateSharedFunction(SILLocation loc, StringRef name, - CanSILFunctionType type, - IsBare_t isBareSILFunction, - IsTransparent_t isTransparent, - IsSerialized_t isSerialized, - ProfileCounter entryCount, - IsThunk_t isThunk, - IsDynamicallyReplaceable_t isDynamic, - IsDistributed_t isDistributed, - IsRuntimeAccessible_t isRuntimeAccessible); + SILFunction *getOrCreateSharedFunction( + SILLocation loc, StringRef name, CanSILFunctionType type, + IsBare_t isBareSILFunction, IsTransparent_t isTransparent, + SerializedKind_t serializedKind, ProfileCounter entryCount, + IsThunk_t isThunk, IsDynamicallyReplaceable_t isDynamic, + IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible); /// Return the declaration of a function, or create it if it doesn't exist. SILFunction *getOrCreateFunction( SILLocation loc, StringRef name, SILLinkage linkage, CanSILFunctionType type, IsBare_t isBareSILFunction, - IsTransparent_t isTransparent, IsSerialized_t isSerialized, - IsDynamicallyReplaceable_t isDynamic, - IsDistributed_t isDistributed, + IsTransparent_t isTransparent, SerializedKind_t serializedKind, + IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible, ProfileCounter entryCount = ProfileCounter(), IsThunk_t isThunk = IsNotThunk, @@ -104,7 +99,7 @@ class SILFunctionBuilder { SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, GenericEnvironment *genericEnv, std::optional loc, IsBare_t isBareSILFunction, IsTransparent_t isTrans, - IsSerialized_t isSerialized, IsDynamicallyReplaceable_t isDynamic, + SerializedKind_t serializedKind, IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible, ProfileCounter entryCount = ProfileCounter(), IsThunk_t isThunk = IsNotThunk, diff --git a/include/swift/SIL/SILGlobalVariable.h b/include/swift/SIL/SILGlobalVariable.h index f788a40210c97..217ec33840944 100644 --- a/include/swift/SIL/SILGlobalVariable.h +++ b/include/swift/SIL/SILGlobalVariable.h @@ -69,7 +69,7 @@ class SILGlobalVariable /// The global variable's serialized attribute. /// Serialized means that the variable can be "inlined" into another module. /// Currently this flag is set for all global variables in the stdlib. - unsigned Serialized : 1; + unsigned Serialized : 2; /// Whether this is a 'let' property, which can only be initialized /// once (either in its declaration, or once later), making it immutable. @@ -97,7 +97,7 @@ class SILGlobalVariable SILBasicBlock StaticInitializerBlock; SILGlobalVariable(SILModule &M, SILLinkage linkage, - IsSerialized_t IsSerialized, StringRef mangledName, + SerializedKind_t serializedKind, StringRef mangledName, SILType loweredType, std::optional loc, VarDecl *decl); @@ -107,7 +107,7 @@ class SILGlobalVariable } static SILGlobalVariable * - create(SILModule &Module, SILLinkage Linkage, IsSerialized_t IsSerialized, + create(SILModule &Module, SILLinkage Linkage, SerializedKind_t serializedKind, StringRef MangledName, SILType LoweredType, std::optional Loc = std::nullopt, VarDecl *Decl = nullptr); @@ -151,10 +151,18 @@ class SILGlobalVariable /// potentially be inspected by the debugger. bool shouldBePreservedForDebugger() const; + /// Check if this global variable is [serialized]. This does not check + /// if it's [serialized_for_package]. + bool isSerialized() const; + /// Check if this global variable is [serialized_for_package]. + bool isSerializedForPackage() const; + /// Checks whether this global var is neither [serialized] nor + /// [serialized_for_package]. + bool isNotSerialized() const; /// Get this global variable's serialized attribute. - IsSerialized_t isSerialized() const; - void setSerialized(IsSerialized_t isSerialized); - + SerializedKind_t getSerializedKind() const; + void setSerializedKind(SerializedKind_t isSerialized); + /// Is this an immutable 'let' property? bool isLet() const { return IsLet; } void setLet(bool isLet) { IsLet = isLet; } diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h index f3cf4957d6134..ee238d86f8fe4 100644 --- a/include/swift/SIL/SILLinkage.h +++ b/include/swift/SIL/SILLinkage.h @@ -141,7 +141,7 @@ enum { /// After the swiftmodule file is written, the IsSerialized flag is cleared from /// all functions. This means that optimizations after the serialization point /// are not limited anymore regarding serialized functions. -enum IsSerialized_t : unsigned char { +enum SerializedKind_t : uint8_t { /// The function is not inlinable and will not be serialized. IsNotSerialized, @@ -151,19 +151,29 @@ enum IsSerialized_t : unsigned char { /// This flag is only valid for Public, PublicNonABI, PublicExternal, /// HiddenExternal and Shared functions. /// Functions with external linkage (PublicExternal, HiddenExternal) will not - /// be serialized, because they are available in a different module (from which - /// they were de-serialized). + /// be serialized, because they are available in a different module (from + /// which they were de-serialized). /// - /// Functions with Shared linkage will only be serialized if they are referenced - /// from another serialized function (or table). + /// Functions with Shared linkage will only be serialized if they are + /// referenced from another serialized function (or table). /// /// This flag is removed from all functions after the serialization point in /// the optimizer pipeline. - IsSerialized -}; + IsSerialized, -enum IsSerializedForPackage_t : unsigned char { - IsNotSerializedForPackage, + /// This flag is valid for all linkages applicable to IsSerialized as well as + /// Package, PackageNonABI, and PackageExternal, if package-wide + /// serialization is enabled with Package-CMO optimization. + /// + /// The [serialized_for_package] attribute is used to indicate that a function + /// is serialized because of Package CMO, which allows loadable types in a + /// serialized function in a resiliently built module, which is otherwise illegal. + /// It's also used to determine during SIL deserialization whether loadable + /// types in a serialized function can be allowed in the client module that + /// imports the module built with Package CMO. If the client contains a [serialized] + /// function due to `@inlinable`, funtions with [serialized_for_package] from + /// the imported module are not allowed being inlined into the client function, + /// which is the correct behavior. IsSerializedForPackage }; diff --git a/include/swift/SIL/SILMoveOnlyDeinit.h b/include/swift/SIL/SILMoveOnlyDeinit.h index 203045800c13b..d126c67bcd5d1 100644 --- a/include/swift/SIL/SILMoveOnlyDeinit.h +++ b/include/swift/SIL/SILMoveOnlyDeinit.h @@ -29,7 +29,7 @@ namespace swift { -enum IsSerialized_t : unsigned char; +enum SerializedKind_t : uint8_t; class SILFunction; class SILModule; @@ -45,18 +45,18 @@ class SILMoveOnlyDeinit final : public SILAllocated { /// Whether or not this deinit table is serialized. If a deinit is not /// serialized, then other modules can not consume directly a move only type /// since the deinit can not be called directly. - bool serialized : 1; + unsigned serialized : 2; SILMoveOnlyDeinit() - : nominalDecl(nullptr), funcImpl(nullptr), serialized(false) {} + : nominalDecl(nullptr), funcImpl(nullptr), serialized(unsigned(IsNotSerialized)) {} SILMoveOnlyDeinit(NominalTypeDecl *nominaldecl, SILFunction *implementation, - bool serialized); + unsigned serialized); ~SILMoveOnlyDeinit(); public: static SILMoveOnlyDeinit *create(SILModule &mod, NominalTypeDecl *nominalDecl, - IsSerialized_t serialized, + SerializedKind_t serialized, SILFunction *funcImpl); NominalTypeDecl *getNominalDecl() const { return nominalDecl; } @@ -66,11 +66,14 @@ class SILMoveOnlyDeinit final : public SILAllocated { return funcImpl; } - IsSerialized_t isSerialized() const { - return serialized ? IsSerialized : IsNotSerialized; + bool isNotSerialized() const { + return SerializedKind_t(serialized) == IsNotSerialized; } - void setSerialized(IsSerialized_t inputSerialized) { - serialized = inputSerialized ? 1 : 0; + SerializedKind_t getSerializedKind() const { + return SerializedKind_t(serialized); + } + void setSerializedKind(SerializedKind_t inputSerialized) { + serialized = unsigned(inputSerialized); } void print(llvm::raw_ostream &os, bool verbose) const; diff --git a/include/swift/SIL/SILProperty.h b/include/swift/SIL/SILProperty.h index 52b3a89ee5d41..877a95b7d7452 100644 --- a/include/swift/SIL/SILProperty.h +++ b/include/swift/SIL/SILProperty.h @@ -36,7 +36,7 @@ class SILProperty : public llvm::ilist_node, { private: /// True if serialized. - bool Serialized; + unsigned Serialized : 2; /// The declaration the descriptor represents. AbstractStorageDecl *Decl; @@ -44,17 +44,20 @@ class SILProperty : public llvm::ilist_node, /// The key path component that represents its implementation. std::optional Component; - SILProperty(bool Serialized, AbstractStorageDecl *Decl, + SILProperty(unsigned Serialized, AbstractStorageDecl *Decl, std::optional Component) : Serialized(Serialized), Decl(Decl), Component(Component) {} public: - static SILProperty *create(SILModule &M, bool Serialized, + static SILProperty *create(SILModule &M, unsigned Serialized, AbstractStorageDecl *Decl, std::optional Component); - bool isSerialized() const { return Serialized; } - + bool isNotSerialized() const { return SerializedKind_t(Serialized) == IsNotSerialized; } + SerializedKind_t getSerializedKind() const { + return SerializedKind_t(Serialized); + } + AbstractStorageDecl *getDecl() const { return Decl; } bool isTrivial() const { diff --git a/include/swift/SIL/SILVTable.h b/include/swift/SIL/SILVTable.h index cc290c47321bb..8977bd5e95aa7 100644 --- a/include/swift/SIL/SILVTable.h +++ b/include/swift/SIL/SILVTable.h @@ -35,7 +35,7 @@ namespace swift { class ClassDecl; -enum IsSerialized_t : unsigned char; +enum SerializedKind_t : uint8_t; class SILFunction; class SILModule; @@ -120,30 +120,30 @@ class SILVTable final : public SILAllocated, /// Whether or not this vtable is serialized, which allows /// devirtualization from another module. - bool Serialized : 1; + unsigned SerializedKind : 2; /// The number of SILVTables entries. unsigned NumEntries : 31; /// Private constructor. Create SILVTables by calling SILVTable::create. - SILVTable(ClassDecl *c, SILType classType, IsSerialized_t serialized, + SILVTable(ClassDecl *c, SILType classType, SerializedKind_t serialized, ArrayRef entries); - public: +public: ~SILVTable(); /// Create a new SILVTable with the given method-to-implementation mapping. /// The SILDeclRef keys should reference the most-overridden members available /// through the class. static SILVTable *create(SILModule &M, ClassDecl *Class, SILType classType, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArrayRef Entries); /// Create a new SILVTable with the given method-to-implementation mapping. /// The SILDeclRef keys should reference the most-overridden members available /// through the class. static SILVTable *create(SILModule &M, ClassDecl *Class, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArrayRef Entries); /// Return the class that the vtable represents. @@ -155,13 +155,22 @@ class SILVTable final : public SILAllocated, SILType getClassType() const { return classType; } /// Returns true if this vtable is going to be (or was) serialized. - IsSerialized_t isSerialized() const { - return Serialized ? IsSerialized : IsNotSerialized; + bool isSerialized() const { + return SerializedKind_t(SerializedKind) == IsSerialized; + } + bool isSerializedForPackage() const { + return SerializedKind_t(SerializedKind) == IsSerializedForPackage; + } + bool isNotSerialized() const { + return SerializedKind_t(SerializedKind) == IsNotSerialized; } + SerializedKind_t getSerializedKind() const { + return SerializedKind_t(SerializedKind); + } /// Sets the serialized flag. - void setSerialized(IsSerialized_t serialized) { - Serialized = (serialized ? 1 : 0); + void setSerializedKind(SerializedKind_t serializedKind) { + SerializedKind = serializedKind; } /// Return all of the method entries. diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h index 0c0d08f3b0794..78f6b24c09710 100644 --- a/include/swift/SIL/SILWitnessTable.h +++ b/include/swift/SIL/SILWitnessTable.h @@ -35,7 +35,7 @@ class SILFunction; class SILModule; class ProtocolConformance; class RootProtocolConformance; -enum IsSerialized_t : unsigned char; +enum SerializedKind_t : uint8_t; /// A mapping from each requirement of a protocol to the SIL-level entity /// satisfying the requirement for a concrete type. @@ -197,10 +197,10 @@ class SILWitnessTable : public llvm::ilist_node, /// Whether or not this witness table is serialized, which allows /// devirtualization from another module. - bool Serialized; + unsigned SerializedKind : 2; /// Private constructor for making SILWitnessTable definitions. - SILWitnessTable(SILModule &M, SILLinkage Linkage, IsSerialized_t Serialized, + SILWitnessTable(SILModule &M, SILLinkage Linkage, SerializedKind_t Serialized, StringRef name, RootProtocolConformance *conformance, ArrayRef entries, ArrayRef conditionalConformances); @@ -214,7 +214,7 @@ class SILWitnessTable : public llvm::ilist_node, public: /// Create a new SILWitnessTable definition with the given entries. static SILWitnessTable * - create(SILModule &M, SILLinkage Linkage, IsSerialized_t Serialized, + create(SILModule &M, SILLinkage Linkage, SerializedKind_t SerializedKind, RootProtocolConformance *conformance, ArrayRef entries, ArrayRef conditionalConformances); @@ -252,13 +252,21 @@ class SILWitnessTable : public llvm::ilist_node, bool isDefinition() const { return !isDeclaration(); } /// Returns true if this witness table is going to be (or was) serialized. - IsSerialized_t isSerialized() const { - return Serialized ? IsSerialized : IsNotSerialized; + bool isSerialized() const { + return SerializedKind_t(SerializedKind) == IsSerialized; + } + bool isSerializedForPackage() const { + return SerializedKind_t(SerializedKind) == IsSerializedForPackage; + } + bool isNotSerialized() const { + return SerializedKind_t(SerializedKind) == IsNotSerialized; + } + SerializedKind_t getSerializedKind() const { + return SerializedKind_t(SerializedKind); } - /// Sets the serialized flag. - void setSerialized(IsSerialized_t serialized) { - Serialized = (serialized ? 1 : 0); + void setSerializedKind(SerializedKind_t serializedKind) { + SerializedKind = serializedKind; } /// Return all of the witness table entries. @@ -295,11 +303,11 @@ class SILWitnessTable : public llvm::ilist_node, void convertToDefinition(ArrayRef newEntries, ArrayRef conditionalConformances, - IsSerialized_t isSerialized); + SerializedKind_t serializedKind); - // Whether a conformance should be serialized. - static bool - conformanceIsSerialized(const RootProtocolConformance *conformance); + // Gets conformance serialized kind. + static SerializedKind_t + conformanceSerializedKind(const RootProtocolConformance *conformance); /// Call \c fn on each (split apart) conditional requirement of \c conformance /// that should appear in a witness table, i.e., conformance requirements that diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h index 69aba4e114fb8..39719fa2cba2d 100644 --- a/include/swift/SIL/TypeSubstCloner.h +++ b/include/swift/SIL/TypeSubstCloner.h @@ -399,7 +399,7 @@ class TypeSubstCloner : public SILClonerWithScopes { ParentFunction = FuncBuilder.getOrCreateFunction( ParentFunction->getLocation(), MangledName, SILLinkage::Shared, ParentFunction->getLoweredFunctionType(), ParentFunction->isBare(), - ParentFunction->isTransparent(), ParentFunction->isSerialized(), + ParentFunction->isTransparent(), ParentFunction->getSerializedKind(), IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, 0, ParentFunction->isThunk(), ParentFunction->getClassSubclassScope()); // Increment the ref count for the inlined function, so it doesn't diff --git a/include/swift/SILOptimizer/Utils/GenericCloner.h b/include/swift/SILOptimizer/Utils/GenericCloner.h index 39deba38428ca..cc049f1bda00a 100644 --- a/include/swift/SILOptimizer/Utils/GenericCloner.h +++ b/include/swift/SILOptimizer/Utils/GenericCloner.h @@ -34,7 +34,7 @@ class GenericCloner using SuperTy = TypeSubstCloner; SILOptFunctionBuilder &FuncBuilder; - IsSerialized_t Serialized; + SerializedKind_t Serialized; const ReabstractionInfo &ReInfo; CloneCollector::CallbackType Callback; llvm::SmallDenseMap diff --git a/include/swift/SILOptimizer/Utils/Generics.h b/include/swift/SILOptimizer/Utils/Generics.h index 66f1f41c09c04..137b18a572153 100644 --- a/include/swift/SILOptimizer/Utils/Generics.h +++ b/include/swift/SILOptimizer/Utils/Generics.h @@ -156,8 +156,8 @@ class ReabstractionInfo { bool isPrespecialization = false; // Is the generated specialization going to be serialized? - IsSerialized_t Serialized = IsNotSerialized; - + SerializedKind_t Serialized = IsNotSerialized; + enum TypeCategory { NotLoadable, Loadable, @@ -201,13 +201,10 @@ class ReabstractionInfo { /// substitutions \p ParamSubs. /// If specialization is not possible getSpecializedType() will return an /// invalid type. - ReabstractionInfo(ModuleDecl *targetModule, - bool isModuleWholeModule, + ReabstractionInfo(ModuleDecl *targetModule, bool isModuleWholeModule, ApplySite Apply, SILFunction *Callee, - SubstitutionMap ParamSubs, - IsSerialized_t Serialized, - bool ConvertIndirectToDirect, - bool dropMetatypeArgs, + SubstitutionMap ParamSubs, SerializedKind_t Serialized, + bool ConvertIndirectToDirect, bool dropMetatypeArgs, OptRemark::Emitter *ORE = nullptr); /// Constructs the ReabstractionInfo for generic function \p Callee with @@ -226,9 +223,8 @@ class ReabstractionInfo { bool isPrespecialized() const { return isPrespecialization; } - IsSerialized_t isSerialized() const { - return Serialized; - } + bool isSerialized() const { return Serialized == IsSerialized; } + SerializedKind_t getSerializedKind() const { return Serialized; } unsigned param2ArgIndex(unsigned ParamIdx) const { return ParamIdx + NumFormalIndirectResults + (hasIndirectErrorResult ? 1: 0); diff --git a/include/swift/SILOptimizer/Utils/SpecializationMangler.h b/include/swift/SILOptimizer/Utils/SpecializationMangler.h index 87e3e6f82602f..70b45b2af42b7 100644 --- a/include/swift/SILOptimizer/Utils/SpecializationMangler.h +++ b/include/swift/SILOptimizer/Utils/SpecializationMangler.h @@ -34,7 +34,7 @@ class PartialSpecializationMangler : public SpecializationMangler { public: PartialSpecializationMangler(SILFunction *F, CanSILFunctionType SpecializedFnTy, - IsSerialized_t Serialized, bool isReAbstracted) + swift::SerializedKind_t Serialized, bool isReAbstracted) : SpecializationMangler(SpecializationPass::GenericSpecializer, Serialized, F), SpecializedFnTy(SpecializedFnTy), isReAbstracted(isReAbstracted) {} @@ -93,7 +93,7 @@ class FunctionSignatureSpecializationMangler : public SpecializationMangler { public: FunctionSignatureSpecializationMangler(SpecializationPass Pass, - IsSerialized_t Serialized, + swift::SerializedKind_t Serialized, SILFunction *F); // For arguments / return values void setArgumentConstantProp(unsigned OrigArgIdx, SILInstruction *constInst); diff --git a/lib/SIL/IR/Linker.cpp b/lib/SIL/IR/Linker.cpp index 7c584935eb85d..ecb2431a32134 100644 --- a/lib/SIL/IR/Linker.cpp +++ b/lib/SIL/IR/Linker.cpp @@ -87,7 +87,7 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) { return; } - assert((bool)F->isSerialized() == !Mod.isSerialized() && + assert(F->isNotSerialized() == Mod.isSerialized() && "the de-serializer did set the wrong serialized flag"); F->setBare(IsBare); @@ -98,10 +98,11 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) { } /// Deserialize a function and add it to the worklist for processing. -void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F, - bool setToSerializable) { +void SILLinkerVisitor::maybeAddFunctionToWorklist( + SILFunction *F, SerializedKind_t callerSerializedKind) { SILLinkage linkage = F->getLinkage(); - assert((!setToSerializable || F->hasValidLinkageForFragileRef() || + assert((callerSerializedKind == IsNotSerialized || + F->hasValidLinkageForFragileRef(callerSerializedKind) || hasSharedVisibility(linkage) || F->isExternForwardDeclaration()) && "called function has wrong linkage for serialized function"); @@ -109,10 +110,12 @@ void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F, // The function is already in the module, so no need to de-serialized it. // But check if we need to set the IsSerialized flag. // See the top-level comment for SILLinkerVisitor for details. - if (setToSerializable && !Mod.isSerialized() && - hasSharedVisibility(linkage) && !F->isSerialized()) { - F->setSerialized(IsSerialized); - + if (callerSerializedKind == IsSerialized && + hasSharedVisibility(linkage) && + !Mod.isSerialized() && + !F->isSerialized()) { + F->setSerializedKind(IsSerialized); + // Push the function to the worklist so that all referenced shared functions // are also set to IsSerialized. Worklist.push_back(F); @@ -148,7 +151,7 @@ void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F, bool SILLinkerVisitor::processFunction(SILFunction *F) { // If F is a declaration, first deserialize it. if (F->isExternalDeclaration()) { - maybeAddFunctionToWorklist(F, /*setToSerializable*/ false); + maybeAddFunctionToWorklist(F, /*serializedKind*/ IsNotSerialized); } else { Worklist.push_back(F); } @@ -183,10 +186,12 @@ void SILLinkerVisitor::linkInVTable(ClassDecl *D) { // for processing. for (auto &entry : Vtbl->getEntries()) { SILFunction *impl = entry.getImplementation(); - if (!Vtbl->isSerialized() || impl->hasValidLinkageForFragileRef()) { + if (!Vtbl->isSerialized() || + impl->hasValidLinkageForFragileRef()) { // Deserialize and recursively walk any vtable entries that do not have // bodies yet. - maybeAddFunctionToWorklist(impl, Vtbl->isSerialized()); + maybeAddFunctionToWorklist(impl, + Vtbl->getSerializedKind()); } } @@ -213,19 +218,19 @@ void SILLinkerVisitor::visitPartialApplyInst(PartialApplyInst *PAI) { void SILLinkerVisitor::visitFunctionRefInst(FunctionRefInst *FRI) { maybeAddFunctionToWorklist(FRI->getReferencedFunction(), - FRI->getFunction()->isSerialized()); + FRI->getFunction()->getSerializedKind()); } void SILLinkerVisitor::visitDynamicFunctionRefInst( DynamicFunctionRefInst *FRI) { maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(), - FRI->getFunction()->isSerialized()); + FRI->getFunction()->getSerializedKind()); } void SILLinkerVisitor::visitPreviousDynamicFunctionRefInst( PreviousDynamicFunctionRefInst *FRI) { maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(), - FRI->getFunction()->isSerialized()); + FRI->getFunction()->getSerializedKind()); } // Eagerly visiting all used conformances leads to a large blowup @@ -315,7 +320,8 @@ void SILLinkerVisitor::visitProtocolConformance(ProtocolConformanceRef ref) { // Otherwise, deserialize the witness if it has shared linkage, or if // we were asked to deserialize everything. maybeAddFunctionToWorklist(E.getMethodWitness().Witness, - WT->isSerialized() || isAvailableExternally(WT->getLinkage())); + (WT->isSerialized() || isAvailableExternally(WT->getLinkage()) ? + IsSerialized : WT->getSerializedKind())); break; } @@ -445,7 +451,7 @@ void SILLinkerVisitor::process() { // If the containing module has been serialized, // Remove The Serialized state (if any) // This allows for more optimizations - Fn->setSerialized(IsSerialized_t::IsNotSerialized); + Fn->setSerializedKind(SerializedKind_t::IsNotSerialized); } if (Fn->getModule().getOptions().EmbeddedSwift && diff --git a/lib/SIL/IR/Linker.h b/lib/SIL/IR/Linker.h index dc5255f4d2bdb..9f2b9ff57b91b 100644 --- a/lib/SIL/IR/Linker.h +++ b/lib/SIL/IR/Linker.h @@ -139,9 +139,10 @@ class SILLinkerVisitor : public SILInstructionVisitor { /// Consider a function for deserialization if the current linking mode /// requires it. /// - /// If `setToSerializable` is true than all shared functions which are referenced - /// from `F` are set to - void maybeAddFunctionToWorklist(SILFunction *F, bool setToSerializable); + /// If `callerSerializedKind` is IsSerialized, then all shared + /// functions which are referenced from `F` are set to be serialized. + void maybeAddFunctionToWorklist(SILFunction *F, + SerializedKind_t callerSerializedKind); /// Is the current mode link all? Link all implies we should try and link /// everything, not just transparent/shared functions. diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 0cd582eb08b70..84bff5fa10ca7 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -531,7 +531,7 @@ SILLinkage SILDeclRef::getDefinitionLinkage() const { auto privateLinkage = [&]() { // Private decls may still be serialized if they are e.g in an inlinable // function. In such a case, they receive shared linkage. - return isSerialized() ? SILLinkage::Shared : SILLinkage::Private; + return isNotSerialized() ? SILLinkage::Private : SILLinkage::Shared; }; // Prespecializations are public. @@ -793,8 +793,16 @@ bool SILDeclRef::isTransparent() const { return false; } +bool SILDeclRef::isSerialized() const { + return getSerializedKind() == IsSerialized; +} + +bool SILDeclRef::isNotSerialized() const { + return getSerializedKind() == IsNotSerialized; +} + /// True if the function should have its body serialized. -IsSerialized_t SILDeclRef::isSerialized() const { +SerializedKind_t SILDeclRef::getSerializedKind() const { if (auto closure = getAbstractClosureExpr()) { // Ask the AST if we're inside an @inlinable context. if (closure->getResilienceExpansion() == ResilienceExpansion::Minimal) { @@ -867,6 +875,7 @@ IsSerialized_t SILDeclRef::isSerialized() const { } // Anything else that is not public is not serializable. + // pcmo TODO: should check if package-cmo is enabled? if (d->getEffectiveAccess() < AccessLevel::Public) return IsNotSerialized; diff --git a/lib/SIL/IR/SILFunction.cpp b/lib/SIL/IR/SILFunction.cpp index 542954b1474ac..c58d1e3ef5ff3 100644 --- a/lib/SIL/IR/SILFunction.cpp +++ b/lib/SIL/IR/SILFunction.cpp @@ -153,7 +153,7 @@ SILFunction *SILFunction::create( SILModule &M, SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, GenericEnvironment *genericEnv, std::optional 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, IsExactSelfClass_t isExactSelfClass, IsThunk_t isThunk, @@ -175,14 +175,14 @@ SILFunction *SILFunction::create( // This happens for example if a specialized function gets dead and gets // deleted. And afterwards the same specialization is created again. fn->init(linkage, name, loweredType, genericEnv, isBareSILFunction, isTrans, - isSerialized, entryCount, isThunk, classSubclassScope, + serializedKind, entryCount, isThunk, classSubclassScope, inlineStrategy, E, debugScope, isDynamic, isExactSelfClass, isDistributed, isRuntimeAccessible); assert(fn->empty()); } else { fn = new (M) SILFunction( M, linkage, name, loweredType, genericEnv, isBareSILFunction, isTrans, - isSerialized, entryCount, isThunk, classSubclassScope, inlineStrategy, + serializedKind, entryCount, isThunk, classSubclassScope, inlineStrategy, E, debugScope, isDynamic, isExactSelfClass, isDistributed, isRuntimeAccessible); } @@ -210,7 +210,7 @@ SILFunction::SILFunction( SILModule &Module, SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType, GenericEnvironment *genericEnv, IsBare_t isBareSILFunction, IsTransparent_t isTrans, - IsSerialized_t isSerialized, ProfileCounter entryCount, IsThunk_t isThunk, + SerializedKind_t serializedKind, ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope classSubclassScope, Inline_t inlineStrategy, EffectsKind E, const SILDebugScope *DebugScope, IsDynamicallyReplaceable_t isDynamic, IsExactSelfClass_t isExactSelfClass, IsDistributed_t isDistributed, @@ -219,7 +219,7 @@ SILFunction::SILFunction( index(Module.getNewFunctionIndex()), Availability(AvailabilityContext::alwaysAvailable()) { init(Linkage, Name, LoweredType, genericEnv, isBareSILFunction, isTrans, - isSerialized, entryCount, isThunk, classSubclassScope, inlineStrategy, E, + serializedKind, entryCount, isThunk, classSubclassScope, inlineStrategy, E, DebugScope, isDynamic, isExactSelfClass, isDistributed, isRuntimeAccessible); @@ -233,7 +233,7 @@ SILFunction::SILFunction( void SILFunction::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, IsDynamicallyReplaceable_t isDynamic, @@ -250,8 +250,7 @@ void SILFunction::init( this->Availability = AvailabilityContext::alwaysAvailable(); this->Bare = isBareSILFunction; this->Transparent = isTrans; - this->Serialized = isSerialized; - this->SerializedForPackage = false; + this->SerializedKind = serializedKind; this->Thunk = isThunk; this->ClassSubclassScope = unsigned(classSubclassScope); this->GlobalInitFlag = false; @@ -323,7 +322,7 @@ void SILFunction::createSnapshot(int id) { SILFunction *newSnapshot = new (Module) SILFunction( Module, getLinkage(), getName(), getLoweredFunctionType(), - getGenericEnvironment(), isBare(), isTransparent(), isSerialized(), + getGenericEnvironment(), isBare(), isTransparent(), getSerializedKind(), getEntryCount(), isThunk(), getClassSubclassScope(), getInlineStrategy(), getEffectsKind(), getDebugScope(), isDynamicallyReplaceable(), isExactSelfClass(), isDistributed(), isRuntimeAccessible()); @@ -554,9 +553,6 @@ ResilienceExpansion SILFunction::getResilienceExpansion() const { // attribute is preserved if the current module is in // the same package, thus should be in the same resilience // domain. - if (isSerializedForPackage() == IsSerializedForPackage) - return ResilienceExpansion::Maximal; - return (isSerialized() ? ResilienceExpansion::Minimal : ResilienceExpansion::Maximal); @@ -920,16 +916,72 @@ bool SILFunction::hasName(const char *Name) const { return getName() == Name; } +/* + 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 + +*/ +bool SILFunction::canBeInlinedIntoCaller( + std::optional callerSerializedKind, + bool assumeFragileCaller) const { + // If the \p assumeFragileCaller is true, the caller must + // be serialized, so return true only if the callee is also + // serialized. + if (assumeFragileCaller) + return isSerialized(); + + switch (getSerializedKind()) { + // 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. + case IsNotSerialized: + return callerSerializedKind.has_value() && + callerSerializedKind.value() == IsNotSerialized; + + // If Package-CMO is enabled, we serialize package, public, + // and @usableFromInline decls as [serialized_for_package]. + // Their bodies must not, however, leak into @inlinable + // functons (that are [serialized]) since they are inlined + // outside of their defining module. + // + // If this callee is [serialized_for_package], the caller + // must be either non-serialized or [serialized_for_package] + // for this callee's body to be inlined into the caller. + // It can however be referenced by [serialized] caller. + case IsSerializedForPackage: + return callerSerializedKind.has_value() && + callerSerializedKind.value() != IsSerialized; + case IsSerialized: + return true; + } + llvm_unreachable("Invalid serialized kind"); +} + /// Returns true if this function can be referenced from a fragile function /// body. -bool SILFunction::hasValidLinkageForFragileRef() const { +bool SILFunction::hasValidLinkageForFragileRef( + std::optional callerSerializedKind, + bool assumeFragileCaller) const { // Fragile functions can reference 'static inline' functions imported // from C. if (hasForeignBody()) return true; // If we can inline it, we can reference it. - if (hasValidLinkageForFragileInline()) + if (canBeInlinedIntoCaller(callerSerializedKind, assumeFragileCaller)) return true; // If the containing module has been serialized already, we no longer diff --git a/lib/SIL/IR/SILFunctionBuilder.cpp b/lib/SIL/IR/SILFunctionBuilder.cpp index feb2db7927e52..7344864d2c3da 100644 --- a/lib/SIL/IR/SILFunctionBuilder.cpp +++ b/lib/SIL/IR/SILFunctionBuilder.cpp @@ -24,8 +24,9 @@ using namespace swift; SILFunction *SILFunctionBuilder::getOrCreateFunction( - SILLocation loc, StringRef name, SILLinkage linkage, CanSILFunctionType type, IsBare_t isBareSILFunction, - IsTransparent_t isTransparent, IsSerialized_t isSerialized, + SILLocation loc, StringRef name, SILLinkage linkage, + CanSILFunctionType type, IsBare_t isBareSILFunction, + IsTransparent_t isTransparent, SerializedKind_t serializedKind, IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible, ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope subclassScope) { @@ -38,7 +39,7 @@ SILFunction *SILFunctionBuilder::getOrCreateFunction( } auto fn = SILFunction::create(mod, linkage, name, type, nullptr, loc, - isBareSILFunction, isTransparent, isSerialized, + isBareSILFunction, isTransparent, serializedKind, entryCount, isDynamic, isDistributed, isRuntimeAccessible, IsNotExactSelfClass, isThunk, subclassScope); @@ -329,9 +330,9 @@ SILFunction *SILFunctionBuilder::getOrCreateFunction( IsTransparent_t IsTrans = constant.isTransparent() ? IsTransparent : IsNotTransparent; - IsSerialized_t IsSer = constant.isSerialized(); + SerializedKind_t IsSer = constant.getSerializedKind(); // Don't create a [serialized] function after serialization has happened. - if (IsSer == IsSerialized && mod.isSerialized()) + if (IsSer != IsNotSerialized && mod.isSerialized()) IsSer = IsNotSerialized; Inline_t inlineStrategy = InlineDefault; @@ -408,11 +409,11 @@ SILFunction *SILFunctionBuilder::getOrCreateFunction( SILFunction *SILFunctionBuilder::getOrCreateSharedFunction( SILLocation loc, StringRef name, CanSILFunctionType type, IsBare_t isBareSILFunction, IsTransparent_t isTransparent, - IsSerialized_t isSerialized, ProfileCounter entryCount, IsThunk_t isThunk, + SerializedKind_t serializedKind, ProfileCounter entryCount, IsThunk_t isThunk, IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible) { return getOrCreateFunction(loc, name, SILLinkage::Shared, type, - isBareSILFunction, isTransparent, isSerialized, + isBareSILFunction, isTransparent, serializedKind, isDynamic, isDistributed, isRuntimeAccessible, entryCount, isThunk, SubclassScope::NotApplicable); } @@ -421,13 +422,13 @@ SILFunction *SILFunctionBuilder::createFunction( SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, GenericEnvironment *genericEnv, std::optional loc, IsBare_t isBareSILFunction, IsTransparent_t isTrans, - IsSerialized_t isSerialized, IsDynamicallyReplaceable_t isDynamic, + SerializedKind_t serializedKind, IsDynamicallyReplaceable_t isDynamic, IsDistributed_t isDistributed, IsRuntimeAccessible_t isRuntimeAccessible, ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope subclassScope, Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore, const SILDebugScope *DebugScope) { return SILFunction::create(mod, linkage, name, loweredType, genericEnv, loc, - isBareSILFunction, isTrans, isSerialized, + isBareSILFunction, isTrans, serializedKind, entryCount, isDynamic, isDistributed, isRuntimeAccessible, IsNotExactSelfClass, isThunk, subclassScope, inlineStrategy, EK, InsertBefore, diff --git a/lib/SIL/IR/SILGlobalVariable.cpp b/lib/SIL/IR/SILGlobalVariable.cpp index 0131de8008149..2f568c9a729ed 100644 --- a/lib/SIL/IR/SILGlobalVariable.cpp +++ b/lib/SIL/IR/SILGlobalVariable.cpp @@ -22,7 +22,7 @@ using namespace swift; SwiftMetatype SILGlobalVariable::registeredMetatype; SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage, - IsSerialized_t isSerialized, + SerializedKind_t serializedKind, StringRef name, SILType loweredType, std::optional loc, @@ -35,7 +35,7 @@ SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage, assert(!entry->getValue() && "global variable already exists"); name = entry->getKey(); - auto var = new (M) SILGlobalVariable(M, linkage, isSerialized, name, + auto var = new (M) SILGlobalVariable(M, linkage, serializedKind, name, loweredType, loc, Decl); if (entry) entry->setValue(var); @@ -43,14 +43,14 @@ SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage, } SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage, - IsSerialized_t isSerialized, + SerializedKind_t serializedKind, StringRef Name, SILType LoweredType, std::optional Loc, VarDecl *Decl) : SwiftObjectHeader(registeredMetatype), Module(Module), Name(Name), LoweredType(LoweredType), Location(Loc.value_or(SILLocation::invalid())), Linkage(unsigned(Linkage)), HasLocation(Loc.has_value()), VDecl(Decl) { - setSerialized(isSerialized); + setSerializedKind(serializedKind); IsDeclaration = isAvailableExternally(Linkage); setLet(Decl ? Decl->isLet() : false); Module.silGlobals.push_back(this); @@ -75,12 +75,23 @@ bool SILGlobalVariable::shouldBePreservedForDebugger() const { return VDecl != nullptr; } +bool SILGlobalVariable::isSerialized() const { + return SerializedKind_t(Serialized) == IsSerialized; +} +bool SILGlobalVariable::isSerializedForPackage() const { + return SerializedKind_t(Serialized) == IsSerializedForPackage; +} +bool SILGlobalVariable::isNotSerialized() const { + return SerializedKind_t(Serialized) == IsNotSerialized; +} + /// Get this global variable's fragile attribute. -IsSerialized_t SILGlobalVariable::isSerialized() const { - return Serialized ? IsSerialized : IsNotSerialized; +SerializedKind_t SILGlobalVariable::getSerializedKind() const { + return SerializedKind_t(Serialized); } -void SILGlobalVariable::setSerialized(IsSerialized_t isSerialized) { - Serialized = isSerialized ? 1 : 0; + +void SILGlobalVariable::setSerializedKind(SerializedKind_t serializedKind) { + Serialized = unsigned(serializedKind); } /// Return the value that is written into the global variable. diff --git a/lib/SIL/IR/SILModule.cpp b/lib/SIL/IR/SILModule.cpp index 6dca4a99de5ff..1432c5f3ffd72 100644 --- a/lib/SIL/IR/SILModule.cpp +++ b/lib/SIL/IR/SILModule.cpp @@ -936,7 +936,7 @@ void SILModule::performOnceForPrespecializedImportedExtensions( } SILProperty * -SILProperty::create(SILModule &M, bool Serialized, AbstractStorageDecl *Decl, +SILProperty::create(SILModule &M, unsigned Serialized, AbstractStorageDecl *Decl, std::optional Component) { auto prop = new (M) SILProperty(Serialized, Decl, Component); M.properties.push_back(prop); diff --git a/lib/SIL/IR/SILMoveOnlyDeinit.cpp b/lib/SIL/IR/SILMoveOnlyDeinit.cpp index 7a5cc6da36edd..4821871d0261b 100644 --- a/lib/SIL/IR/SILMoveOnlyDeinit.cpp +++ b/lib/SIL/IR/SILMoveOnlyDeinit.cpp @@ -18,12 +18,12 @@ using namespace swift; SILMoveOnlyDeinit *SILMoveOnlyDeinit::create(SILModule &mod, NominalTypeDecl *nominalDecl, - IsSerialized_t serialized, + SerializedKind_t serialized, SILFunction *funcImpl) { auto buf = mod.allocate(sizeof(SILMoveOnlyDeinit), alignof(SILMoveOnlyDeinit)); auto *table = - ::new (buf) SILMoveOnlyDeinit(nominalDecl, funcImpl, serialized); + ::new (buf) SILMoveOnlyDeinit(nominalDecl, funcImpl, unsigned(serialized)); mod.moveOnlyDeinits.push_back(table); mod.MoveOnlyDeinitMap[nominalDecl] = table; return table; @@ -31,7 +31,7 @@ SILMoveOnlyDeinit *SILMoveOnlyDeinit::create(SILModule &mod, SILMoveOnlyDeinit::SILMoveOnlyDeinit(NominalTypeDecl *nominalDecl, SILFunction *implementation, - bool serialized) + unsigned serialized) : nominalDecl(nominalDecl), funcImpl(implementation), serialized(serialized) { assert(funcImpl); diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index ae1c7f16d9107..8a7ae3014b085 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -3295,6 +3295,20 @@ static void printLinkage(llvm::raw_ostream &OS, SILLinkage linkage, OS << getLinkageString(linkage); } + +static void printSerializedKind(llvm::raw_ostream &OS, SerializedKind_t kind) { + switch (kind) { + case IsNotSerialized: + break; + case IsSerializedForPackage: + OS << "[serialized_for_package] "; + break; + case IsSerialized: + OS << "[serialized] "; + break; + } +} + static void printClangQualifiedNameCommentIfPresent(llvm::raw_ostream &OS, const clang::Decl *decl) { if (decl) { @@ -3348,18 +3362,7 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { if (isTransparent()) OS << "[transparent] "; - switch (isSerialized()) { - case IsNotSerialized: break; - case IsSerialized: OS << "[serialized] "; break; - } - - switch (isSerializedForPackage()) { - case IsNotSerializedForPackage: - break; - case IsSerializedForPackage: - OS << "[serialized_for_package] "; - break; - } + printSerializedKind(OS, getSerializedKind()); switch (isThunk()) { case IsNotThunk: break; @@ -3545,9 +3548,7 @@ void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const { // Passing true for 'isDefinition' lets print the (external) linkage if it's // not a definition. printLinkage(OS, getLinkage(), /*isDefinition*/ true); - - if (isSerialized()) - OS << "[serialized] "; + printSerializedKind(OS, getSerializedKind()); if (isLet()) OS << "[let] "; @@ -3858,8 +3859,7 @@ void SILProperty::print(SILPrintContext &Ctx) const { auto &OS = Ctx.OS(); OS << "sil_property "; - if (isSerialized()) - OS << "[serialized] "; + printSerializedKind(OS, getSerializedKind()); OS << '#'; printValueDecl(getDecl(), OS); @@ -4037,9 +4037,8 @@ void SILVTableEntry::print(llvm::raw_ostream &OS) const { void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const { OS << "sil_vtable "; - if (isSerialized()) - OS << "[serialized] "; - + printSerializedKind(OS, getSerializedKind()); + if (SILType classTy = getClassType()) { OS << classTy; } else { @@ -4059,8 +4058,7 @@ void SILVTable::dump() const { print(llvm::errs()); } void SILMoveOnlyDeinit::print(llvm::raw_ostream &OS, bool verbose) const { OS << "sil_moveonlydeinit "; - if (isSerialized()) - OS << "[serialized] "; + printSerializedKind(OS, getSerializedKind()); OS << getNominalDecl()->getName() << " {\n"; OS << " @" << getImplementation()->getName(); OS << "\t// " << demangleSymbol(getImplementation()->getName()); @@ -4150,8 +4148,7 @@ void SILWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const { PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType(); OS << "sil_witness_table "; printLinkage(OS, getLinkage(), /*isDefinition*/ isDefinition()); - if (isSerialized()) - OS << "[serialized] "; + printSerializedKind(OS, getSerializedKind()); getConformance()->printName(OS, Options); Options.GenericSig = diff --git a/lib/SIL/IR/SILSymbolVisitor.cpp b/lib/SIL/IR/SILSymbolVisitor.cpp index 25ec721cf36f4..9b8276d53352d 100644 --- a/lib/SIL/IR/SILSymbolVisitor.cpp +++ b/lib/SIL/IR/SILSymbolVisitor.cpp @@ -279,13 +279,13 @@ class SILSymbolVisitorImpl : public ASTVisitor { // FIXME: the logic around visibility in extensions is confusing, and // sometimes witness thunks need to be manually made public. - auto conformanceIsFixed = - SILWitnessTable::conformanceIsSerialized(rootConformance); + auto conformanceSeializedKind = + SILWitnessTable::conformanceSerializedKind(rootConformance); auto addSymbolIfNecessary = [&](ValueDecl *requirementDecl, ValueDecl *witnessDecl) { auto witnessRef = SILDeclRef(witnessDecl); if (Ctx.getOpts().PublicOrPackageSymbolsOnly) { - if (!conformanceIsFixed) + if (conformanceSeializedKind == IsNotSerialized) return; if (!isa(rootConformance) && diff --git a/lib/SIL/IR/SILVTable.cpp b/lib/SIL/IR/SILVTable.cpp index 29b0395f28b81..5a136476d9fa7 100644 --- a/lib/SIL/IR/SILVTable.cpp +++ b/lib/SIL/IR/SILVTable.cpp @@ -30,13 +30,13 @@ void SILVTableEntry::setImplementation(SILFunction *f) { } SILVTable *SILVTable::create(SILModule &M, ClassDecl *Class, - IsSerialized_t Serialized, - ArrayRef Entries) { + SerializedKind_t Serialized, + ArrayRef Entries) { return create(M, Class, SILType(), Serialized, Entries); } SILVTable *SILVTable::create(SILModule &M, ClassDecl *Class, SILType classType, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArrayRef Entries) { auto size = totalSizeToAlloc(Entries.size()); auto buf = M.allocate(size, alignof(SILVTable)); @@ -75,9 +75,10 @@ void SILVTable::updateVTableCache(const Entry &entry) { M.VTableEntryCache[{this, entry.getMethod()}] = entry; } -SILVTable::SILVTable(ClassDecl *c, SILType classType, IsSerialized_t serialized, - ArrayRef entries) - : Class(c), classType(classType), Serialized(serialized), NumEntries(entries.size()) { +SILVTable::SILVTable(ClassDecl *c, SILType classType, + SerializedKind_t serialized, ArrayRef entries) + : Class(c), classType(classType), SerializedKind(serialized), + NumEntries(entries.size()) { std::uninitialized_copy(entries.begin(), entries.end(), getTrailingObjects()); diff --git a/lib/SIL/IR/SILWitnessTable.cpp b/lib/SIL/IR/SILWitnessTable.cpp index 033007b8624a0..f933e92490f11 100644 --- a/lib/SIL/IR/SILWitnessTable.cpp +++ b/lib/SIL/IR/SILWitnessTable.cpp @@ -57,7 +57,7 @@ void SILWitnessTable::addWitnessTable() { } SILWitnessTable *SILWitnessTable::create( - SILModule &M, SILLinkage Linkage, IsSerialized_t Serialized, + SILModule &M, SILLinkage Linkage, SerializedKind_t SerializedKind, RootProtocolConformance *Conformance, ArrayRef entries, ArrayRef conditionalConformances) { @@ -72,7 +72,7 @@ SILWitnessTable *SILWitnessTable::create( // Allocate the witness table and initialize it. void *buf = M.allocate(sizeof(SILWitnessTable), alignof(SILWitnessTable)); SILWitnessTable *wt = ::new (buf) - SILWitnessTable(M, Linkage, Serialized, Name.str(), Conformance, entries, + SILWitnessTable(M, Linkage, SerializedKind, Name.str(), Conformance, entries, conditionalConformances); wt->addWitnessTable(); @@ -103,18 +103,20 @@ SILWitnessTable::create(SILModule &M, SILLinkage Linkage, } SILWitnessTable::SILWitnessTable( - SILModule &M, SILLinkage Linkage, IsSerialized_t Serialized, StringRef N, + SILModule &M, SILLinkage Linkage, SerializedKind_t SerializedKind, StringRef N, RootProtocolConformance *Conformance, ArrayRef entries, ArrayRef conditionalConformances) : Mod(M), Name(N), Linkage(Linkage), Conformance(Conformance), Entries(), - ConditionalConformances(), IsDeclaration(true), Serialized(false) { - convertToDefinition(entries, conditionalConformances, Serialized); + ConditionalConformances(), IsDeclaration(true), + SerializedKind(IsNotSerialized) { + convertToDefinition(entries, conditionalConformances, SerializedKind); } SILWitnessTable::SILWitnessTable(SILModule &M, SILLinkage Linkage, StringRef N, RootProtocolConformance *Conformance) : Mod(M), Name(N), Linkage(Linkage), Conformance(Conformance), Entries(), - ConditionalConformances(), IsDeclaration(true), Serialized(false) {} + ConditionalConformances(), IsDeclaration(true), + SerializedKind(IsNotSerialized) {} SILWitnessTable::~SILWitnessTable() { if (isDeclaration()) @@ -140,10 +142,10 @@ SILWitnessTable::~SILWitnessTable() { void SILWitnessTable::convertToDefinition( ArrayRef entries, ArrayRef conditionalConformances, - IsSerialized_t isSerialized) { + SerializedKind_t serializedKind) { assert(isDeclaration() && "Definitions should never call this method."); IsDeclaration = false; - Serialized = (isSerialized == IsSerialized); + SerializedKind = serializedKind; Entries = Mod.allocateCopy(entries); ConditionalConformances = Mod.allocateCopy(conditionalConformances); @@ -165,25 +167,28 @@ void SILWitnessTable::convertToDefinition( } } -bool SILWitnessTable::conformanceIsSerialized( - const RootProtocolConformance *conformance) { +SerializedKind_t SILWitnessTable::conformanceSerializedKind( + const RootProtocolConformance *conformance) { // Allow serializing conformance with package or public access level // if package serialization is enabled. - auto optInPackage = conformance->getDeclContext() - ->getASTContext() - .SILOpts.EnableSerializePackage; + auto optInPackage = conformance->getDeclContext()->getParentModule()->serializePackageEnabled(); auto accessLevelToCheck = - optInPackage ? AccessLevel::Package : AccessLevel::Public; + optInPackage ? AccessLevel::Package : AccessLevel::Public; auto normalConformance = dyn_cast(conformance); if (normalConformance && normalConformance->isResilient() && !optInPackage) - return false; + return IsNotSerialized; if (conformance->getProtocol()->getEffectiveAccess() < accessLevelToCheck) - return false; + return IsNotSerialized; auto *nominal = conformance->getDeclContext()->getSelfNominalTypeDecl(); - return nominal->getEffectiveAccess() >= accessLevelToCheck; + if (nominal->getEffectiveAccess() >= accessLevelToCheck) + return optInPackage && + conformance->getDeclContext()->getParentModule()->isResilient() ? + IsSerializedForPackage : IsSerialized; + + return IsNotSerialized; } bool SILWitnessTable::enumerateWitnessTableConditionalConformances( diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 0404dde0f9140..ad5e77cfd5184 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -665,8 +665,7 @@ void SILParser::convertRequirements(ArrayRef From, } static bool parseDeclSILOptional( - bool *isTransparent, IsSerialized_t *isSerialized, - IsSerializedForPackage_t *isSerializedForPackage, bool *isCanonical, + bool *isTransparent, SerializedKind_t *serializedKind, bool *isCanonical, bool *hasOwnershipSSA, bool *hasResultDependsOnSelf, IsThunk_t *isThunk, IsDynamicallyReplaceable_t *isDynamic, IsDistributed_t *isDistributed, IsRuntimeAccessible_t *isRuntimeAccessible, @@ -695,11 +694,10 @@ static bool parseDeclSILOptional( return true; } else if (isTransparent && SP.P.Tok.getText() == "transparent") *isTransparent = true; - else if (isSerialized && SP.P.Tok.getText() == "serialized") - *isSerialized = IsSerialized; - else if (isSerializedForPackage && - SP.P.Tok.getText() == "serialized_for_package") - *isSerializedForPackage = IsSerializedForPackage; + else if (serializedKind && SP.P.Tok.getText() == "serialized") + *serializedKind = IsSerialized; + else if (serializedKind && SP.P.Tok.getText() == "serialized_for_package") + *serializedKind = IsSerializedForPackage; else if (isDynamic && SP.P.Tok.getText() == "dynamically_replacable") *isDynamic = IsDynamic; else if (isDistributed && SP.P.Tok.getText() == "distributed") @@ -7108,8 +7106,7 @@ bool SILParserState::parseDeclSIL(Parser &P) { SourceLoc FnNameLoc; bool isTransparent = false; - IsSerialized_t isSerialized = IsNotSerialized; - IsSerializedForPackage_t isSerializedForPackage = IsNotSerializedForPackage; + SerializedKind_t isSerialized = IsNotSerialized; bool isCanonical = false; IsDynamicallyReplaceable_t isDynamic = IsNotDynamic; IsDistributed_t isDistributed = IsNotDistributed; @@ -7142,9 +7139,9 @@ bool SILParserState::parseDeclSIL(Parser &P) { Identifier objCReplacementFor; if (parseSILLinkage(FnLinkage, P) || parseDeclSILOptional( - &isTransparent, &isSerialized, &isSerializedForPackage, &isCanonical, - &hasOwnershipSSA, &hasResultDependsOnSelf, &isThunk, &isDynamic, - &isDistributed, &isRuntimeAccessible, &forceEnableLexicalLifetimes, + &isTransparent, &isSerialized, &isCanonical, &hasOwnershipSSA, + &hasResultDependsOnSelf, &isThunk, &isDynamic, &isDistributed, + &isRuntimeAccessible, &forceEnableLexicalLifetimes, &useStackForPackMetadata, &hasUnsafeNonEscapableResult, &isExactSelfClass, &DynamicallyReplacedFunction, &AdHocWitnessFunction, &objCReplacementFor, &specialPurpose, @@ -7176,9 +7173,7 @@ bool SILParserState::parseDeclSIL(Parser &P) { FunctionState.getGlobalNameForDefinition(FnName, SILFnType, FnNameLoc); FunctionState.F->setBare(IsBare); FunctionState.F->setTransparent(IsTransparent_t(isTransparent)); - FunctionState.F->setSerialized(IsSerialized_t(isSerialized)); - FunctionState.F->setSerializedForPackage( - IsSerializedForPackage_t(isSerializedForPackage)); + FunctionState.F->setSerializedKind(SerializedKind_t(isSerialized)); FunctionState.F->setWasDeserializedCanonical(isCanonical); if (!hasOwnershipSSA) FunctionState.F->setOwnershipEliminated(); @@ -7397,7 +7392,7 @@ bool SILParserState::parseSILGlobal(Parser &P) { Identifier GlobalName; SILType GlobalType; SourceLoc NameLoc; - IsSerialized_t isSerialized = IsNotSerialized; + SerializedKind_t isSerialized = IsNotSerialized; bool isLet = false; SILParser State(P); @@ -7406,8 +7401,8 @@ bool SILParserState::parseSILGlobal(Parser &P) { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, &isLet, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, State, M) || + &isLet, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, State, M) || P.parseToken(tok::at_sign, diag::expected_sil_value_name) || P.parseIdentifier(GlobalName, NameLoc, /*diagnoseDollarPrefix=*/false, diag::expected_sil_value_name) || @@ -7453,14 +7448,14 @@ bool SILParserState::parseSILProperty(Parser &P) { auto loc = P.consumeToken(tok::kw_sil_property); auto InstLoc = RegularLocation(loc); SILParser SP(P); - - IsSerialized_t Serialized = IsNotSerialized; + + SerializedKind_t Serialized = IsNotSerialized; if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, SP, M)) + nullptr, nullptr, nullptr, SP, M)) return true; ValueDecl *VD; @@ -7524,13 +7519,13 @@ bool SILParserState::parseSILVTable(Parser &P) { P.consumeToken(tok::kw_sil_vtable); SILParser VTableState(P); - IsSerialized_t Serialized = IsNotSerialized; + SerializedKind_t Serialized = IsNotSerialized; if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, VTableState, M)) + nullptr, nullptr, nullptr, VTableState, M)) return true; @@ -7647,14 +7642,13 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) { parser.consumeToken(tok::kw_sil_moveonlydeinit); SILParser moveOnlyDeinitTableState(parser); - IsSerialized_t Serialized = IsNotSerialized; - if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - moveOnlyDeinitTableState, M)) + SerializedKind_t Serialized = IsNotSerialized; + if (parseDeclSILOptional( + nullptr, &Serialized, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, moveOnlyDeinitTableState, M)) return true; // Parse the class name. @@ -8134,14 +8128,14 @@ bool SILParserState::parseSILWitnessTable(Parser &P) { // Parse the linkage. std::optional Linkage; parseSILLinkage(Linkage, P); - - IsSerialized_t isSerialized = IsNotSerialized; + + SerializedKind_t isSerialized = IsNotSerialized; if (parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, WitnessState, M)) + nullptr, nullptr, nullptr, WitnessState, M)) return true; // Parse the protocol conformance. diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index f96f36ed52d8c..4a03935251c8d 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -2449,6 +2449,8 @@ class SILVerifier : public SILVerifierBase { // A direct reference to a non-public or shared but not fragile function // from a fragile function is an error. + // pcmo TODO: change to !isNotSerialized and pass serializedKind to + // hasValidLinkageForFragileRef if (F.isSerialized()) { require((SingleFunction && RefF->isExternalDeclaration()) || RefF->hasValidLinkageForFragileRef(), @@ -2497,6 +2499,7 @@ class SILVerifier : public SILVerifierBase { require(!checkResilience(VD, F), "cannot access storage of resilient global"); } + // pcmo TODO: replace this with F.canInlineCalleeBody(RefG) if (F.isSerialized()) { // If it has a package linkage at this point, package CMO must // have been enabled, so opt in for visibility. @@ -7037,7 +7040,7 @@ class SILVerifier : public SILVerifierBase { SILModule &mod = F->getModule(); bool embedded = mod.getASTContext().LangOpts.hasFeature(Feature::Embedded); - require(!F->isSerialized() || !mod.isSerialized() || mod.isParsedAsSerializedSIL(), + require(F->isNotSerialized() || !mod.isSerialized() || mod.isParsedAsSerializedSIL(), "cannot have a serialized function after the module has been serialized"); switch (F->getLinkage()) { @@ -7051,23 +7054,25 @@ class SILVerifier : public SILVerifierBase { case SILLinkage::PackageNonABI: require(F->isDefinition(), "alwaysEmitIntoClient function must have a body"); - require(F->isSerialized() || mod.isSerialized(), + require(!F->isNotSerialized() || mod.isSerialized(), "alwaysEmitIntoClient function must be serialized"); break; case SILLinkage::Hidden: case SILLinkage::Private: require(F->isDefinition() || F->hasForeignBody(), "internal/private function must have a body"); - require(!F->isSerialized() || embedded, + require(F->isNotSerialized() || embedded, "internal/private function cannot be serialized or serializable"); break; case SILLinkage::PublicExternal: - require(F->isExternalDeclaration() || F->isSerialized() || + require(F->isExternalDeclaration() || + !F->isNotSerialized() || mod.isSerialized(), "public-external function definition must be serialized"); break; case SILLinkage::PackageExternal: - require(F->isExternalDeclaration() || F->isSerialized() || + require(F->isExternalDeclaration() || + !F->isNotSerialized() || mod.isSerialized(), "package-external function definition must be serialized"); break; diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 7a3d00d865cd2..3127fe022878c 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -821,7 +821,7 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) { if (constant.isForeignToNativeThunk()) { f->setThunk(IsThunk); if (constant.asForeign().isClangGenerated()) - f->setSerialized(IsSerialized); + f->setSerializedKind(IsSerialized); auto loc = constant.getAsRegularLocation(); loc.markAutoGenerated(); @@ -1981,7 +1981,7 @@ void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) { bool needsGenericContext = true; if (canStorageUseTrivialDescriptor(*this, decl)) { - (void)SILProperty::create(M, /*serialized*/ false, decl, std::nullopt); + (void)SILProperty::create(M, /*serializedKind*/ 0, decl, std::nullopt); return; } @@ -1998,7 +1998,7 @@ void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) { M.getSwiftModule(), /*property descriptor*/ true); - (void)SILProperty::create(M, /*serialized*/ false, decl, component); + (void)SILProperty::create(M, /*serializedKind*/ 0, decl, component); } void SILGenModule::visitIfConfigDecl(IfConfigDecl *ICD) { diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h index 147abf30c7ad0..1834c9452eafe 100644 --- a/lib/SILGen/SILGen.h +++ b/lib/SILGen/SILGen.h @@ -381,7 +381,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor { /// Emit a protocol witness entry point. SILFunction * emitProtocolWitness(ProtocolConformanceRef conformance, SILLinkage linkage, - IsSerialized_t isSerialized, SILDeclRef requirement, + SerializedKind_t serializedKind, SILDeclRef requirement, SILDeclRef witnessRef, IsFreeFunctionWitness_t isFree, Witness witness); diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 4e9a64da08978..4ef1d246a2454 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -1528,17 +1528,11 @@ SILFunction *SILGenFunction::emitNativeAsyncToForeignThunk(SILDeclRef thunk) { closureName.push_back(thunkSuffix[0]); SILGenFunctionBuilder fb(SGM); - auto closure = fb.getOrCreateSharedFunction(loc, closureName, - closureTy, - IsBare, - IsNotTransparent, - F.isSerialized(), - ProfileCounter(), - IsThunk, - IsNotDynamic, - IsNotDistributed, - IsNotRuntimeAccessible); - + auto closure = fb.getOrCreateSharedFunction( + loc, closureName, closureTy, IsBare, IsNotTransparent, + F.getSerializedKind(), ProfileCounter(), IsThunk, IsNotDynamic, + IsNotDistributed, IsNotRuntimeAccessible); + auto closureRef = B.createFunctionRef(loc, closure); auto closureVal = B.createPartialApply(loc, closureRef, subs, diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp index 1026348ccdc8f..cc3f3ed79df3b 100644 --- a/lib/SILGen/SILGenGlobalVariable.cpp +++ b/lib/SILGen/SILGenGlobalVariable.cpp @@ -42,7 +42,8 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl, // Get the linkage for SILGlobalVariable. FormalLinkage formalLinkage; - if (gDecl->isResilient()) + if (gDecl->isResilient() && + !gDecl->getModuleContext()->serializePackageEnabled()) formalLinkage = FormalLinkage::Private; else formalLinkage = getDeclLinkage(gDecl); diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 724a6df31660e..36790109e2dfa 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -6239,7 +6239,7 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk( auto linkage = stripExternalFromLinkage(originalFn->getLinkage()); auto *thunk = fb.getOrCreateFunction( loc, name, linkage, thunkFnTy, IsBare, IsNotTransparent, - customDerivativeFn->isSerialized(), + customDerivativeFn->getSerializedKind(), customDerivativeFn->isDynamicallyReplaceable(), customDerivativeFn->isDistributed(), customDerivativeFn->isRuntimeAccessible(), diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp index f7d9e7377bb32..739ae7046b1fa 100644 --- a/lib/SILGen/SILGenThunk.cpp +++ b/lib/SILGen/SILGenThunk.cpp @@ -671,7 +671,7 @@ SILFunction *SILGenModule::getOrCreateDerivativeVTableThunk( /*isVTableThunk*/ true); auto *thunk = builder.getOrCreateFunction( derivativeFnDecl, name, SILLinkage::Private, constantTy, IsBare, - IsTransparent, derivativeFnDeclRef.isSerialized(), IsNotDynamic, + IsTransparent, derivativeFnDeclRef.getSerializedKind(), IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, ProfileCounter(), IsThunk); if (!thunk->empty()) return thunk; diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index 279e9a4835aba..0b0bc197a5b09 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -302,7 +302,7 @@ class SILGenVTable : public SILVTableVisitor { false); } - IsSerialized_t serialized = IsNotSerialized; + SerializedKind_t serialized = IsNotSerialized; auto classIsPublic = theClass->getEffectiveAccess() >= AccessLevel::Public; // Only public, fixed-layout classes should have serialized vtables. if (classIsPublic && !isResilient) @@ -515,9 +515,8 @@ template class SILGenWitnessTable : public SILWitnessVisitor { } }; -static IsSerialized_t isConformanceSerialized(RootProtocolConformance *conf) { - return SILWitnessTable::conformanceIsSerialized(conf) - ? IsSerialized : IsNotSerialized; +static SerializedKind_t getConformanceSerializedKind(RootProtocolConformance *conf) { + return SILWitnessTable::conformanceSerializedKind(conf); } /// Emit a witness table for a protocol conformance. @@ -530,13 +529,13 @@ class SILGenConformance : public SILGenWitnessTable { std::vector Entries; std::vector ConditionalConformances; SILLinkage Linkage; - IsSerialized_t Serialized; + SerializedKind_t SerializedKind; SILGenConformance(SILGenModule &SGM, NormalProtocolConformance *C) : SGM(SGM), Conformance(C), Linkage(getLinkageForProtocolConformance(Conformance, ForDefinition)), - Serialized(isConformanceSerialized(Conformance)) + SerializedKind(getConformanceSerializedKind(Conformance)) { auto *proto = Conformance->getProtocol(); @@ -572,7 +571,7 @@ class SILGenConformance : public SILGenWitnessTable { // If we have a declaration, convert the witness table to a definition. if (wt->isDeclaration()) { - wt->convertToDefinition(Entries, ConditionalConformances, Serialized); + wt->convertToDefinition(Entries, ConditionalConformances, SerializedKind); // Since we had a declaration before, its linkage should be external, // ensure that we have a compatible linkage for soundness. *NOTE* we are ok @@ -589,7 +588,7 @@ class SILGenConformance : public SILGenWitnessTable { } // Otherwise if we have no witness table yet, create it. - return SILWitnessTable::create(SGM.M, Linkage, Serialized, Conformance, + return SILWitnessTable::create(SGM.M, Linkage, SerializedKind, Conformance, Entries, ConditionalConformances); } @@ -628,8 +627,8 @@ class SILGenConformance : public SILGenWitnessTable { Witness witness) { // Emit the witness thunk and add it to the table. auto witnessLinkage = witnessRef.getLinkage(ForDefinition); - auto witnessSerialized = Serialized; - if (witnessSerialized && + auto witnessSerializedKind = SerializedKind; + if (witnessSerializedKind != IsNotSerialized && // If package optimization is enabled, this is false; // witness thunk should get a `shared` linkage in the // else block below. @@ -637,7 +636,7 @@ class SILGenConformance : public SILGenWitnessTable { witnessRef, witnessRef.getASTContext().SILOpts.EnableSerializePackage)) { witnessLinkage = SILLinkage::Public; - witnessSerialized = IsNotSerialized; + witnessSerializedKind = IsNotSerialized; } else { // This is the "real" rule; the above case should go away once we // figure out what's going on. @@ -646,7 +645,7 @@ class SILGenConformance : public SILGenWitnessTable { witnessLinkage = SILLinkage::Private; // Unless the witness table is going to be serialized. - if (witnessSerialized) + if (witnessSerializedKind != IsNotSerialized) witnessLinkage = SILLinkage::Shared; // Or even if its not serialized, it might be for an imported @@ -660,7 +659,7 @@ class SILGenConformance : public SILGenWitnessTable { } SILFunction *witnessFn = SGM.emitProtocolWitness( - ProtocolConformanceRef(Conformance), witnessLinkage, witnessSerialized, + ProtocolConformanceRef(Conformance), witnessLinkage, witnessSerializedKind, requirementRef, witnessRef, isFree, witness); Entries.push_back( SILWitnessTable::MethodWitness{requirementRef, witnessFn}); @@ -722,8 +721,8 @@ SILGenModule::getWitnessTable(NormalProtocolConformance *conformance) { SILFunction *SILGenModule::emitProtocolWitness( ProtocolConformanceRef conformance, SILLinkage linkage, - IsSerialized_t isSerialized, SILDeclRef requirement, SILDeclRef witnessRef, - IsFreeFunctionWitness_t isFree, Witness witness) { + SerializedKind_t serializedKind, SILDeclRef requirement, + SILDeclRef witnessRef, IsFreeFunctionWitness_t isFree, Witness witness) { auto requirementInfo = Types.getConstantInfo(TypeExpansionContext::minimal(), requirement); @@ -849,7 +848,7 @@ SILFunction *SILGenModule::emitProtocolWitness( SILGenFunctionBuilder builder(*this); auto *f = builder.createFunction( linkage, nameBuffer, witnessSILFnType, genericEnv, - SILLocation(witnessRef.getDecl()), IsNotBare, IsTransparent, isSerialized, + SILLocation(witnessRef.getDecl()), IsNotBare, IsTransparent, serializedKind, IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, ProfileCounter(), IsThunk, SubclassScope::NotApplicable, InlineStrategy); @@ -969,7 +968,7 @@ class SILGenSelfConformanceWitnessTable SILGenModule &SGM; SelfProtocolConformance *conformance; SILLinkage linkage; - IsSerialized_t serialized; + SerializedKind_t serialized; SmallVector entries; public: @@ -977,7 +976,7 @@ class SILGenSelfConformanceWitnessTable SelfProtocolConformance *conformance) : SGM(SGM), conformance(conformance), linkage(getLinkageForProtocolConformance(conformance, ForDefinition)), - serialized(isConformanceSerialized(conformance)) { + serialized(getConformanceSerializedKind(conformance)) { } void emit() { @@ -1121,10 +1120,10 @@ void SILGenModule::emitNonCopyableTypeDeinitTable(NominalTypeDecl *nom) { SILDeclRef constant(dd, SILDeclRef::Kind::Deallocator); SILFunction *f = getFunction(constant, NotForDefinition); - auto serialized = IsSerialized_t::IsNotSerialized; + auto serialized = SerializedKind_t::IsNotSerialized; bool nomIsPublic = nom->getEffectiveAccess() >= AccessLevel::Public; // We only serialize the deinit if the type is public and not resilient. - if (nomIsPublic && !nom->isResilient()) + if (nomIsPublic && !nom->isResilient()) // pcmo TODO: isFragile()? serialized = IsSerialized; SILMoveOnlyDeinit::create(f->getModule(), nom, serialized, f); } diff --git a/lib/SILOptimizer/Differentiation/JVPCloner.cpp b/lib/SILOptimizer/Differentiation/JVPCloner.cpp index 226919e63b840..ff47a11f6d15f 100644 --- a/lib/SILOptimizer/Differentiation/JVPCloner.cpp +++ b/lib/SILOptimizer/Differentiation/JVPCloner.cpp @@ -1704,9 +1704,8 @@ void JVPCloner::Implementation::prepareForDifferentialGeneration() { auto *differential = fb.createFunction( linkage, context.getASTContext().getIdentifier(diffName).str(), diffType, diffGenericEnv, original->getLocation(), original->isBare(), - IsNotTransparent, jvp->isSerialized(), - original->isDynamicallyReplaceable(), - original->isDistributed(), + IsNotTransparent, jvp->getSerializedKind(), + original->isDynamicallyReplaceable(), original->isDistributed(), original->isRuntimeAccessible()); differential->setDebugScope( new (module) SILDebugScope(original->getLocation(), differential)); diff --git a/lib/SILOptimizer/Differentiation/Thunk.cpp b/lib/SILOptimizer/Differentiation/Thunk.cpp index 163d7dbb170a6..99b6201c42f5c 100644 --- a/lib/SILOptimizer/Differentiation/Thunk.cpp +++ b/lib/SILOptimizer/Differentiation/Thunk.cpp @@ -765,9 +765,9 @@ getOrCreateSubsetParametersThunkForDerivativeFunction( auto loc = origFnOperand.getLoc(); auto *thunk = fb.getOrCreateSharedFunction( - loc, thunkName, thunkType, IsBare, IsTransparent, caller->isSerialized(), - ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed, - IsNotRuntimeAccessible); + loc, thunkName, thunkType, IsBare, IsTransparent, + caller->getSerializedKind(), ProfileCounter(), IsThunk, IsNotDynamic, + IsNotDistributed, IsNotRuntimeAccessible); if (!thunk->empty()) return {thunk, interfaceSubs}; diff --git a/lib/SILOptimizer/Differentiation/VJPCloner.cpp b/lib/SILOptimizer/Differentiation/VJPCloner.cpp index b329e6ea4dd97..c713aa6db5afc 100644 --- a/lib/SILOptimizer/Differentiation/VJPCloner.cpp +++ b/lib/SILOptimizer/Differentiation/VJPCloner.cpp @@ -1301,7 +1301,7 @@ SILFunction *VJPCloner::Implementation::createEmptyPullback() { auto *pullback = fb.createFunction( linkage, context.getASTContext().getIdentifier(pbName).str(), pbType, pbGenericEnv, original->getLocation(), original->isBare(), - IsNotTransparent, vjp->isSerialized(), + IsNotTransparent, vjp->getSerializedKind(), original->isDynamicallyReplaceable(), original->isDistributed(), original->isRuntimeAccessible()); pullback->setDebugScope(new (module) diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp index d25ebac8976e9..730940f56fe26 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp @@ -312,7 +312,7 @@ void ExistentialSpecializer::specializeExistentialArgsInAppliesWithinFunction( /// Name Mangler for naming the protocol constrained generic method. auto P = Demangle::SpecializationPass::FunctionSignatureOpts; Mangle::FunctionSignatureSpecializationMangler Mangler( - P, Callee->isSerialized(), Callee); + P, Callee->getSerializedKind(), Callee); /// Save the arguments in a descriptor. llvm::SpecificBumpPtrAllocator Allocator; diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp index 6e16f16a7020f..4fa1c42ce1b87 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp @@ -616,11 +616,11 @@ void ExistentialTransform::createExistentialSpecializedFunction() { SILLinkage linkage = getSpecializedLinkage(F, F->getLinkage()); NewF = FunctionBuilder.createFunction( - linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(), - F->isTransparent(), F->isSerialized(), IsNotDynamic, IsNotDistributed, - IsNotRuntimeAccessible, F->getEntryCount(), F->isThunk(), - F->getClassSubclassScope(), F->getInlineStrategy(), F->getEffectsKind(), - nullptr, F->getDebugScope()); + linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(), + F->isTransparent(), F->getSerializedKind(), IsNotDynamic, + IsNotDistributed, IsNotRuntimeAccessible, F->getEntryCount(), + F->isThunk(), F->getClassSubclassScope(), F->getInlineStrategy(), + F->getEffectsKind(), nullptr, F->getDebugScope()); /// Set the semantics attributes for the new function. for (auto &Attr : F->getSemanticsAttrs()) diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 26bff4018e92e..f3f360abae733 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -185,8 +185,8 @@ FunctionSignatureTransformDescriptor::createOptimizedSILFunctionName() { SILFunction *F = OriginalFunction; auto P = Demangle::SpecializationPass::FunctionSignatureOpts; - Mangle::FunctionSignatureSpecializationMangler Mangler(P, F->isSerialized(), - F); + Mangle::FunctionSignatureSpecializationMangler Mangler( + P, F->getSerializedKind(), F); // Handle arguments' changes. for (unsigned i : indices(ArgumentDescList)) { @@ -542,8 +542,9 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() { // classSubclassScope. TransformDescriptor.OptimizedFunction = FunctionBuilder.createFunction( linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(), - F->isTransparent(), F->isSerialized(), IsNotDynamic, IsNotDistributed, - IsNotRuntimeAccessible, F->getEntryCount(), F->isThunk(), + F->isTransparent(), F->getSerializedKind(), IsNotDynamic, + IsNotDistributed, IsNotRuntimeAccessible, F->getEntryCount(), + F->isThunk(), /*classSubclassScope=*/SubclassScope::NotApplicable, F->getInlineStrategy(), F->getEffectsKind(), nullptr, F->getDebugScope()); SILFunction *NewF = TransformDescriptor.OptimizedFunction.get(); @@ -856,8 +857,8 @@ class FunctionSignatureOpts : public SILFunctionTransform { // going to change, make sure the mangler is aware of all the changes done // to the function. auto P = Demangle::SpecializationPass::FunctionSignatureOpts; - Mangle::FunctionSignatureSpecializationMangler Mangler(P, - F->isSerialized(), F); + Mangle::FunctionSignatureSpecializationMangler Mangler( + P, F->getSerializedKind(), F); /// Keep a map between the exploded argument index and the original argument /// index. diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp index 228a22df3c262..e0360868e18a1 100644 --- a/lib/SILOptimizer/IPO/CapturePropagation.cpp +++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp @@ -84,8 +84,8 @@ static SILInstruction *getConstant(SILValue V) { return nullptr; } -static std::string getClonedName(PartialApplyInst *PAI, IsSerialized_t Serialized, - SILFunction *F) { +static std::string getClonedName(PartialApplyInst *PAI, + SerializedKind_t Serialized, SILFunction *F) { auto P = Demangle::SpecializationPass::CapturePropagation; Mangle::FunctionSignatureSpecializationMangler Mangler(P, Serialized, F); @@ -267,16 +267,13 @@ CanSILFunctionType getPartialApplyInterfaceResultType(PartialApplyInst *PAI) { /// function body. SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, SILFunction *OrigF) { - IsSerialized_t Serialized = IsNotSerialized; - if (PAI->getFunction()->isSerialized()) - Serialized = IsSerialized; - - std::string Name = getClonedName(PAI, Serialized, OrigF); + SerializedKind_t serializedKind = PAI->getFunction()->getSerializedKind(); + std::string Name = getClonedName(PAI, serializedKind, OrigF); // See if we already have a version of this function in the module. If so, // just return it. if (auto *NewF = OrigF->getModule().lookUpFunction(Name)) { - assert(NewF->isSerialized() == Serialized); + assert(NewF->getSerializedKind() == serializedKind); LLVM_DEBUG(llvm::dbgs() << " Found an already specialized version of the callee: "; NewF->printName(llvm::dbgs()); llvm::dbgs() << "\n"); @@ -295,7 +292,7 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, SILOptFunctionBuilder FuncBuilder(*this); SILFunction *NewF = FuncBuilder.createFunction( SILLinkage::Shared, Name, NewFTy, GenericEnv, OrigF->getLocation(), - OrigF->isBare(), OrigF->isTransparent(), Serialized, IsNotDynamic, + OrigF->isBare(), OrigF->isTransparent(), serializedKind, IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, OrigF->getEntryCount(), OrigF->isThunk(), OrigF->getClassSubclassScope(), OrigF->getInlineStrategy(), OrigF->getEffectsKind(), @@ -491,8 +488,8 @@ static SILFunction *getSpecializedWithDeadParams( ReabstractionInfo ReInfo( FuncBuilder.getModule().getSwiftModule(), FuncBuilder.getModule().isWholeModule(), ApplySite(), Specialized, - PAI->getSubstitutionMap(), Specialized->isSerialized(), - /* ConvertIndirectToDirect */ false, /*dropMetatypeArgs=*/ false); + PAI->getSubstitutionMap(), Specialized->getSerializedKind(), + /* ConvertIndirectToDirect */ false, /*dropMetatypeArgs=*/false); GenericFuncSpecializer FuncSpecializer(FuncBuilder, Specialized, ReInfo.getClonerParamSubstitutionMap(), diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index 7e20513c60346..eb1a5c3d7ba7c 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -350,7 +350,8 @@ class CallSiteDescriptor { FullApplySite getApplyInst() const { return AI; } - IsSerialized_t isSerialized() const; + bool isSerialized() const; + SerializedKind_t getSerializedKind() const; std::string createName() const; @@ -597,16 +598,17 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc, // AI from parent? } -IsSerialized_t CallSiteDescriptor::isSerialized() const { - if (getClosure()->getFunction()->isSerialized()) - return IsSerialized; - return IsNotSerialized; +bool CallSiteDescriptor::isSerialized() const { + return getClosure()->getFunction()->getSerializedKind() == IsSerialized; +} +SerializedKind_t CallSiteDescriptor::getSerializedKind() const { + return getClosure()->getFunction()->getSerializedKind(); } std::string CallSiteDescriptor::createName() const { auto P = Demangle::SpecializationPass::ClosureSpecializer; - Mangle::FunctionSignatureSpecializationMangler Mangler(P, isSerialized(), - getApplyCallee()); + Mangle::FunctionSignatureSpecializationMangler Mangler(P, getSerializedKind(), + getApplyCallee()); if (auto *PAI = dyn_cast(getClosure())) { Mangler.setArgumentClosureProp(getClosureIndex(), PAI); @@ -801,7 +803,7 @@ ClosureSpecCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, getSpecializedLinkage(ClosureUser, ClosureUser->getLinkage()), ClonedName, ClonedTy, ClosureUser->getGenericEnvironment(), ClosureUser->getLocation(), IsBare, ClosureUser->isTransparent(), - CallSiteDesc.isSerialized(), IsNotDynamic, IsNotDistributed, + CallSiteDesc.getSerializedKind(), IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, ClosureUser->getEntryCount(), ClosureUser->isThunk(), /*classSubclassScope=*/SubclassScope::NotApplicable, @@ -1308,8 +1310,10 @@ bool SILClosureSpecializerTransform::gatherCallSites( // Don't specialize non-fragile callees if the caller is fragile; // the specialized callee will have shared linkage, and thus cannot // be referenced from the fragile caller. + // pcmo TODO: remove F->isSerialiezd() and pass its kind to + // canBeInlinedIntoCaller instead. if (Caller->isSerialized() && - !ApplyCallee->hasValidLinkageForFragileInline()) + !ApplyCallee->canBeInlinedIntoCaller()) continue; // If the callee uses a dynamic Self, we cannot specialize it, diff --git a/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp b/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp index 678eb0a246b7a..3156d25ed7e65 100644 --- a/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp +++ b/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp @@ -187,6 +187,34 @@ static bool isPackageOrPublic(AccessLevel accessLevel, SILOptions options) { return accessLevel == AccessLevel::Public; } +/// Checks wither this function is [serialized_for_package] due to Package CMO +/// or [serialized] with non-package CMO. The [serialized_for_package] attribute +/// is used to indicate that a function is serialized because of Package CMO, which +/// allows loadable types in a serialized function in a resiliently built module, which +/// is otherwise illegal. It's also used to determine during SIL deserialization whether +/// loadable types in a serialized function can be allowed in the client module that +/// imports the module built with Package CMO. If the client contains a [serialized] +/// function due to `@inlinable`, funtions with [serialized_for_package] from +/// the imported module are not allowed being inlined into the client function, which +/// is the correct behavior. +static bool isSerializedWithRightKind(const SILModule &mod, + SILFunction *f) { + return mod.getSwiftModule()->serializePackageEnabled() && + mod.getSwiftModule()->isResilient() ? + f->isSerializedForPackage() : f->isSerialized(); +} +static bool isSerializedWithRightKind(const SILModule &mod, + SILGlobalVariable *g) { + return mod.getSwiftModule()->serializePackageEnabled() && + mod.getSwiftModule()->isResilient() ? + g->isSerializedForPackage() : g->isSerialized(); +} +static SerializedKind_t getRightSerializedKind(const SILModule &mod) { + return mod.getSwiftModule()->serializePackageEnabled() && + mod.getSwiftModule()->isResilient() ? + IsSerializedForPackage : IsSerialized; +} + static bool isSerializeCandidate(SILFunction *F, SILOptions options) { auto linkage = F->getLinkage(); // We allow serializing a shared definition. For example, @@ -203,7 +231,7 @@ static bool isSerializeCandidate(SILFunction *F, SILOptions options) { static bool isReferenceSerializeCandidate(SILFunction *F, SILOptions options) { if (options.EnableSerializePackage) { - if (F->isSerialized()) + if (isSerializedWithRightKind(F->getModule(), F)) return true; return hasPublicOrPackageVisibility(F->getLinkage(), /*includePackage*/ true); @@ -214,7 +242,7 @@ static bool isReferenceSerializeCandidate(SILFunction *F, SILOptions options) { static bool isReferenceSerializeCandidate(SILGlobalVariable *G, SILOptions options) { if (options.EnableSerializePackage) { - if (G->isSerialized()) + if (isSerializedWithRightKind(G->getModule(), G)) return true; return hasPublicOrPackageVisibility(G->getLinkage(), /*includePackage*/ true); @@ -239,30 +267,30 @@ void CrossModuleOptimization::serializeFunctionsInModule( } void CrossModuleOptimization::serializeTablesInModule() { - if (!M.getOptions().EnableSerializePackage) + if (!M.getSwiftModule()->serializePackageEnabled()) return; for (const auto &vt : M.getVTables()) { - if (!vt->isSerialized() && + if (vt->isNotSerialized() && vt->getClass()->getEffectiveAccess() >= AccessLevel::Package) { - vt->setSerialized(IsSerialized); + vt->setSerializedKind(getRightSerializedKind(M)); } } for (auto &wt : M.getWitnessTables()) { - if (!wt.isSerialized() && hasPublicOrPackageVisibility( - wt.getLinkage(), /*includePackage*/ true)) { + if (wt.isNotSerialized() && + hasPublicOrPackageVisibility(wt.getLinkage(), /*includePackage*/ true)) { for (auto &entry : wt.getEntries()) { // Witness thunks are not serialized, so serialize them here. if (entry.getKind() == SILWitnessTable::Method && - !entry.getMethodWitness().Witness->isSerialized() && + entry.getMethodWitness().Witness->isNotSerialized() && isSerializeCandidate(entry.getMethodWitness().Witness, M.getOptions())) { - entry.getMethodWitness().Witness->setSerialized(IsSerialized); + entry.getMethodWitness().Witness->setSerializedKind(getRightSerializedKind(M)); } } // Then serialize the witness table itself. - wt.setSerialized(IsSerialized); + wt.setSerializedKind(getRightSerializedKind(M)); } } } @@ -285,8 +313,8 @@ bool CrossModuleOptimization::canSerializeFunction( canSerializeFlags[function] = false; if (everything) { - canSerializeFlags[function] = true; - return true; + canSerializeFlags[function] = true; + return true; } if (DeclContext *funcCtxt = function->getDeclContext()) { @@ -294,7 +322,8 @@ bool CrossModuleOptimization::canSerializeFunction( return false; } - if (function->isSerialized()) { + if (function->isSerialized() || + isSerializedWithRightKind(M, function)) { canSerializeFlags[function] = true; return true; } @@ -546,7 +575,7 @@ bool CrossModuleOptimization::canUseFromInline(SILFunction *function) { /// Decide whether to serialize a function. bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { // Check if we already handled this function before. - if (function->isSerialized()) + if (isSerializedWithRightKind(M, function)) return false; if (everything) @@ -567,7 +596,7 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { // If package-cmo is enabled, we don't want to limit inlining // or should at least increase the cap. - if (!M.getOptions().EnableSerializePackage) { + if (!M.getSwiftModule()->serializePackageEnabled()) { // Also serialize "small" non-generic functions. int size = 0; for (SILBasicBlock &block : *function) { @@ -582,37 +611,24 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { return true; } -/// Adds [serialized_for_package] attribute to an already [serialized] function. -/// It's used to indicate that a function was [serialized] because of package-cmo. -/// 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`, where -/// the callee was serialized due to package-cmo. -static void addSerializedForPackageAttrIfEnabled(SILFunction *f, - const SILModule &mod) { - assert(f->isSerialized()); - auto shouldSet = mod.getSwiftModule()->serializePackageEnabled() && - mod.getSwiftModule()->isResilient(); - f->setSerializedForPackage(shouldSet ? IsSerializedForPackage - : IsNotSerializedForPackage); -} - /// Serialize \p function and recursively all referenced functions which are /// marked in \p canSerializeFlags. void CrossModuleOptimization::serializeFunction(SILFunction *function, - const FunctionFlags &canSerializeFlags) { - if (function->isSerialized()) { - addSerializedForPackageAttrIfEnabled(function, M); + const FunctionFlags &canSerializeFlags) { + // This means the function is @inlinable (or similar) + // so should have [serialized] attribute. + if (function->isSerialized()) return; - } + + // If not, check whether it was serialized with + // this optimization. + if (isSerializedWithRightKind(M, function)) + return; + if (!canSerializeFlags.lookup(function)) return; - function->setSerialized(IsSerialized); - addSerializedForPackageAttrIfEnabled(function, M); + function->setSerializedKind(getRightSerializedKind(M)); for (SILBasicBlock &block : *function) { for (SILInstruction &inst : block) { @@ -657,7 +673,7 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst, } } serializeFunction(callee, canSerializeFlags); - assert(callee->isSerialized() || + assert(isSerializedWithRightKind(M, callee) || isPackageOrPublic(callee->getLinkage(), M.getOptions())); return; } @@ -667,7 +683,7 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst, if (canSerializeGlobal(global)) { serializeGlobal(global); } - if (!hasPublicOrPackageVisibility(global->getLinkage(), M.getOptions().EnableSerializePackage)) { + if (!hasPublicOrPackageVisibility(global->getLinkage(), M.getSwiftModule()->serializePackageEnabled())) { global->setLinkage(SILLinkage::Public); } return; @@ -688,6 +704,8 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst, } void CrossModuleOptimization::serializeGlobal(SILGlobalVariable *global) { + if (isSerializedWithRightKind(M, global)) + return; for (const SILInstruction &initInst : *global) { if (auto *FRI = dyn_cast(&initInst)) { SILFunction *callee = FRI->getReferencedFunction(); @@ -695,7 +713,7 @@ void CrossModuleOptimization::serializeGlobal(SILGlobalVariable *global) { makeFunctionUsableFromInline(callee); } } - global->setSerialized(IsSerialized); + global->setSerializedKind(getRightSerializedKind(M)); } void CrossModuleOptimization::keepMethodAlive(SILDeclRef method) { @@ -709,7 +727,7 @@ void CrossModuleOptimization::keepMethodAlive(SILDeclRef method) { void CrossModuleOptimization::makeFunctionUsableFromInline(SILFunction *function) { assert(canUseFromInline(function)); if (!isAvailableExternally(function->getLinkage()) && - function->getLinkage() != SILLinkage::Public) { + !isPackageOrPublic(function->getLinkage(), M.getOptions())) { function->setLinkage(SILLinkage::Public); } } @@ -733,11 +751,14 @@ void CrossModuleOptimization::makeDeclUsableFromInline(ValueDecl *decl) { decl->getAttrs().add(attr); if (everything) { - // Serialize vtables, their superclass vtables, and make all vfunctions - // usable from inline. + // The following does _not_ apply to the Package CMO as + // it is only supported for the conservative mode. + // + // With non-package CMO, serialize vtables, their superclass + // vtables, and make all vfunctions usable from inline. if (auto *classDecl = dyn_cast(decl)) { auto *vTable = M.lookUpVTable(classDecl); - vTable->setSerialized(IsSerialized); + vTable->setSerializedKind(IsSerialized); for (auto &entry : vTable->getEntries()) { makeFunctionUsableFromInline(entry.getImplementation()); } @@ -747,7 +768,7 @@ void CrossModuleOptimization::makeDeclUsableFromInline(ValueDecl *decl) { if (!vTable) { return TypeWalker::Action::Stop; } - vTable->setSerialized(IsSerialized); + vTable->setSerializedKind(IsSerialized); for (auto &entry : vTable->getEntries()) { makeFunctionUsableFromInline(entry.getImplementation()); } @@ -807,7 +828,7 @@ class CrossModuleOptimizationPass: public SILModuleTransform { auto &M = *getModule(); if (M.getSwiftModule()->isResilient() && - !M.getOptions().EnableSerializePackage) + !M.getSwiftModule()->serializePackageEnabled()) return; if (!M.isWholeModule()) return; diff --git a/lib/SILOptimizer/Mandatory/CapturePromotion.cpp b/lib/SILOptimizer/Mandatory/CapturePromotion.cpp index 84360cc661b5c..a49dc2fbb146f 100644 --- a/lib/SILOptimizer/Mandatory/CapturePromotion.cpp +++ b/lib/SILOptimizer/Mandatory/CapturePromotion.cpp @@ -292,7 +292,7 @@ class ClosureCloner : public SILClonerWithScopes { friend class SILCloner; ClosureCloner(SILOptFunctionBuilder &funcBuilder, SILFunction *orig, - IsSerialized_t serialized, StringRef clonedName, + SerializedKind_t serialized, StringRef clonedName, IndicesSet &promotableIndices, ResilienceExpansion expansion); void populateCloned(); @@ -307,7 +307,7 @@ class ClosureCloner : public SILClonerWithScopes { private: static SILFunction *initCloned(SILOptFunctionBuilder &funcBuilder, - SILFunction *orig, IsSerialized_t serialized, + SILFunction *orig, SerializedKind_t serialized, StringRef clonedName, IndicesSet &promotableIndices, ResilienceExpansion expansion); @@ -334,7 +334,7 @@ class ClosureCloner : public SILClonerWithScopes { } // end anonymous namespace ClosureCloner::ClosureCloner(SILOptFunctionBuilder &funcBuilder, - SILFunction *orig, IsSerialized_t serialized, + SILFunction *orig, SerializedKind_t serialized, StringRef clonedName, IndicesSet &promotableIndices, ResilienceExpansion resilienceExpansion) @@ -410,7 +410,8 @@ computeNewArgInterfaceTypes(SILFunction *f, IndicesSet &promotableIndices, } } -static std::string getSpecializedName(SILFunction *f, IsSerialized_t serialized, +static std::string getSpecializedName(SILFunction *f, + SerializedKind_t serialized, IndicesSet &promotableIndices) { auto p = Demangle::SpecializationPass::CapturePromotion; Mangle::FunctionSignatureSpecializationMangler mangler(p, serialized, f); @@ -436,7 +437,7 @@ static std::string getSpecializedName(SILFunction *f, IsSerialized_t serialized, /// the address value. SILFunction * ClosureCloner::initCloned(SILOptFunctionBuilder &functionBuilder, - SILFunction *orig, IsSerialized_t serialized, + SILFunction *orig, SerializedKind_t serialized, StringRef clonedName, IndicesSet &promotableIndices, ResilienceExpansion resilienceExpansion) { SILModule &mod = orig->getModule(); @@ -546,20 +547,17 @@ SILFunction *ClosureCloner::constructClonedFunction( // Create the Cloned Name for the function. SILFunction *origF = fri->getReferencedFunction(); - IsSerialized_t isSerialized = IsNotSerialized; - if (f->isSerialized()) - isSerialized = IsSerialized_t::IsSerialized; - - auto clonedName = getSpecializedName(origF, isSerialized, promotableIndices); + SerializedKind_t serializedKind = f->getSerializedKind(); + auto clonedName = getSpecializedName(origF, serializedKind, promotableIndices); // If we already have such a cloned function in the module then just use it. if (auto *prevF = f->getModule().lookUpFunction(clonedName)) { - assert(prevF->isSerialized() == isSerialized); + assert(prevF->getSerializedKind() == serializedKind); return prevF; } // Otherwise, create a new clone. - ClosureCloner cloner(funcBuilder, origF, isSerialized, clonedName, + ClosureCloner cloner(funcBuilder, origF, serializedKind, clonedName, promotableIndices, resilienceExpansion); cloner.populateCloned(); return cloner.getCloned(); diff --git a/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableAddressesChecker.cpp b/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableAddressesChecker.cpp index 7dfbba3668180..dd76d6b05a04a 100644 --- a/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableAddressesChecker.cpp +++ b/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableAddressesChecker.cpp @@ -973,7 +973,7 @@ struct ClosureArgumentInOutToOutCloner public: ClosureArgumentInOutToOutCloner( SILOptFunctionBuilder &funcBuilder, SILFunction *orig, - IsSerialized_t isSerialized, + SerializedKind_t serializedKind, SmallBlotSetVector &postDominatingConsumingUsers, const SmallBitVector &argsToConvertIndices, StringRef name); @@ -1057,14 +1057,14 @@ struct ClosureArgumentInOutToOutCloner private: static SILFunction *initCloned( SILOptFunctionBuilder &funcBuilder, SILFunction *orig, - IsSerialized_t isSerialized, + SerializedKind_t serializedKind, SmallBlotSetVector &postDominatingConsumingUsers, const SmallBitVector &argsToConvertIndices, StringRef cloneName); }; } // namespace -static std::string getClonedName(SILFunction *func, IsSerialized_t serialized, +static std::string getClonedName(SILFunction *func, SerializedKind_t serialized, const SmallBitVector &argsToConvertIndices) { auto kind = Demangle::SpecializationPass::MoveDiagnosticInOutToOut; Mangle::FunctionSignatureSpecializationMangler Mangler(kind, serialized, @@ -1078,11 +1078,11 @@ static std::string getClonedName(SILFunction *func, IsSerialized_t serialized, ClosureArgumentInOutToOutCloner::ClosureArgumentInOutToOutCloner( SILOptFunctionBuilder &funcBuilder, SILFunction *orig, - IsSerialized_t isSerialized, + SerializedKind_t serializedKind, SmallBlotSetVector &postDominatingConsumingUsers, const SmallBitVector &argsToConvertIndices, StringRef name) : SILClonerWithScopes(*initCloned( - funcBuilder, orig, isSerialized, postDominatingConsumingUsers, + funcBuilder, orig, serializedKind, postDominatingConsumingUsers, argsToConvertIndices, name)), postDominatingConsumingUsers(postDominatingConsumingUsers), orig(orig), argsToConvertIndices(argsToConvertIndices) { @@ -1095,7 +1095,7 @@ ClosureArgumentInOutToOutCloner::ClosureArgumentInOutToOutCloner( /// parameters (which are specified by PromotedArgIndices). SILFunction *ClosureArgumentInOutToOutCloner::initCloned( SILOptFunctionBuilder &funcBuilder, SILFunction *orig, - IsSerialized_t serialized, + SerializedKind_t serialized, SmallBlotSetVector &postDominatingConsumingUsers, const SmallBitVector &argsToConvertIndices, StringRef clonedName) { SILModule &mod = orig->getModule(); @@ -1961,14 +1961,15 @@ void ConsumeOperatorCopyableAddressesChecker::cloneDeferCalleeAndRewriteUses( auto *origCallee = oldApplySite.getReferencedFunctionOrNull(); assert(origCallee); - auto name = getClonedName(origCallee, origCallee->isSerialized(), bitVector); + auto name = + getClonedName(origCallee, origCallee->getSerializedKind(), bitVector); SILFunction *newCallee = nullptr; if (auto *fn = origCallee->getModule().lookUpFunction(name)) { newCallee = fn; } else { ClosureArgumentInOutToOutCloner cloner( - funcBuilder, origCallee, origCallee->isSerialized(), + funcBuilder, origCallee, origCallee->getSerializedKind(), postDominatingConsumingUsers, bitVector, name); cloner.populateCloned(); newCallee = cloner.getCloned(); diff --git a/lib/SILOptimizer/Mandatory/DiagnosticDeadFunctionElimination.cpp b/lib/SILOptimizer/Mandatory/DiagnosticDeadFunctionElimination.cpp index 3d131c9a63dd6..70a56d6a6175e 100644 --- a/lib/SILOptimizer/Mandatory/DiagnosticDeadFunctionElimination.cpp +++ b/lib/SILOptimizer/Mandatory/DiagnosticDeadFunctionElimination.cpp @@ -72,7 +72,7 @@ struct DiagnosticDeadFunctionEliminator : SILFunctionTransform { // ODR shootouts. if (fn->getLinkage() == SILLinkage::Shared) { fn->setLinkage(SILLinkage::Private); - fn->setSerialized(IsNotSerialized); + fn->setSerializedKind(IsNotSerialized); } invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody); diff --git a/lib/SILOptimizer/Mandatory/Differentiation.cpp b/lib/SILOptimizer/Mandatory/Differentiation.cpp index 9faea438c6889..b8251eccfdd09 100644 --- a/lib/SILOptimizer/Mandatory/Differentiation.cpp +++ b/lib/SILOptimizer/Mandatory/Differentiation.cpp @@ -110,9 +110,10 @@ class DifferentiationTransformer { /// /// \param serializeFunctions specifies whether generated functions should be /// serialized. - bool canonicalizeDifferentiabilityWitness( - SILDifferentiabilityWitness *witness, DifferentiationInvoker invoker, - IsSerialized_t serializeFunctions); + bool + canonicalizeDifferentiabilityWitness(SILDifferentiabilityWitness *witness, + DifferentiationInvoker invoker, + SerializedKind_t serializeFunctions); /// Process the given `differentiable_function` instruction, filling in /// missing derivative functions if necessary. @@ -772,7 +773,7 @@ emitDerivativeFunctionReference( static SILFunction *createEmptyVJP(ADContext &context, SILDifferentiabilityWitness *witness, - IsSerialized_t isSerialized) { + SerializedKind_t isSerialized) { auto original = witness->getOriginalFunction(); auto config = witness->getConfig(); LLVM_DEBUG({ @@ -817,7 +818,7 @@ static SILFunction *createEmptyVJP(ADContext &context, static SILFunction *createEmptyJVP(ADContext &context, SILDifferentiabilityWitness *witness, - IsSerialized_t isSerialized) { + SerializedKind_t isSerialized) { auto original = witness->getOriginalFunction(); auto config = witness->getConfig(); LLVM_DEBUG({ @@ -894,7 +895,7 @@ static void emitFatalError(ADContext &context, SILFunction *f, /// Returns true on error. bool DifferentiationTransformer::canonicalizeDifferentiabilityWitness( SILDifferentiabilityWitness *witness, DifferentiationInvoker invoker, - IsSerialized_t serializeFunctions) { + SerializedKind_t serializeFunctions) { std::string traceMessage; llvm::raw_string_ostream OS(traceMessage); OS << "processing "; @@ -1043,10 +1044,10 @@ static SILValue promoteCurryThunkApplicationToDifferentiableFunction( SILOptFunctionBuilder fb(dt.getTransform()); auto *newThunk = fb.getOrCreateFunction( loc, newThunkName, getSpecializedLinkage(thunk, thunk->getLinkage()), - thunkType, thunk->isBare(), thunk->isTransparent(), thunk->isSerialized(), - thunk->isDynamicallyReplaceable(), thunk->isDistributed(), - thunk->isRuntimeAccessible(), - ProfileCounter(), thunk->isThunk()); + thunkType, thunk->isBare(), thunk->isTransparent(), + thunk->getSerializedKind(), thunk->isDynamicallyReplaceable(), + thunk->isDistributed(), thunk->isRuntimeAccessible(), ProfileCounter(), + thunk->isThunk()); // If new thunk is newly created: clone the old thunk body, wrap the // returned function value with an `differentiable_function` // instruction, and process the `differentiable_function` instruction. @@ -1395,7 +1396,8 @@ void Differentiation::run() { auto *witness = invokerPair.first; auto invoker = invokerPair.second; if (transformer.canonicalizeDifferentiabilityWitness( - witness, invoker, witness->getOriginalFunction()->isSerialized())) + witness, invoker, + witness->getOriginalFunction()->getSerializedKind())) errorOccurred = true; } diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 67acaf247a5d1..3f0b2de21cba1 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -753,8 +753,10 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick, if (CalleeFunction->empty()) return nullptr; + // pcmo TODO: remove F->isSerialiezd() and pass its kind to + // canBeInlinedIntoCaller instead. if (F->isSerialized() && - !CalleeFunction->hasValidLinkageForFragileInline()) { + !CalleeFunction->canBeInlinedIntoCaller()) { if (!CalleeFunction->hasValidLinkageForFragileRef()) { llvm::errs() << "caller: " << F->getName() << "\n"; llvm::errs() << "callee: " << CalleeFunction->getName() << "\n"; diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp index 2e48312c96d8d..f4a63e82237b7 100644 --- a/lib/SILOptimizer/PassManager/PassManager.cpp +++ b/lib/SILOptimizer/PassManager/PassManager.cpp @@ -1786,8 +1786,8 @@ BridgedOwnedString BridgedPassContext::mangleAsyncRemoved(BridgedFunction functi // FIXME: hard assumption on what pass is requesting this. auto P = Demangle::SpecializationPass::AsyncDemotion; - Mangle::FunctionSignatureSpecializationMangler Mangler(P, F->isSerialized(), - F); + Mangle::FunctionSignatureSpecializationMangler Mangler( + P, F->getSerializedKind(), F); Mangler.setRemovedEffect(EffectKind::Async); return Mangler.mangle(); } @@ -1796,7 +1796,9 @@ BridgedOwnedString BridgedPassContext::mangleWithDeadArgs(const SwiftInt * _Null SwiftInt numDeadArgs, BridgedFunction function) const { SILFunction *f = function.getFunction(); - Mangle::FunctionSignatureSpecializationMangler Mangler(Demangle::SpecializationPass::FunctionSignatureOpts, f->isSerialized(), f); + Mangle::FunctionSignatureSpecializationMangler Mangler( + Demangle::SpecializationPass::FunctionSignatureOpts, + f->getSerializedKind(), f); for (SwiftInt idx = 0; idx < numDeadArgs; idx++) { Mangler.setArgumentDead((unsigned)idx); } @@ -1809,9 +1811,9 @@ BridgedOwnedString BridgedPassContext::mangleWithClosureArgs( BridgedFunction applySiteCallee ) const { auto pass = Demangle::SpecializationPass::ClosureSpecializer; - auto isSerialized = applySiteCallee.getFunction()->isSerialized(); + auto serializedKind = applySiteCallee.getFunction()->getSerializedKind(); Mangle::FunctionSignatureSpecializationMangler mangler( - pass, isSerialized, applySiteCallee.getFunction()); + pass, serializedKind, applySiteCallee.getFunction()); llvm::SmallVector closureArgsStorage; auto closureArgs = bridgedClosureArgs.getValues(closureArgsStorage); @@ -1930,11 +1932,12 @@ createEmptyFunction(BridgedStringRef name, SILOptFunctionBuilder functionBuilder(*invocation->getTransform()); SILFunction *newF = functionBuilder.createFunction( - fromFn->getLinkage(), name.unbridged(), newTy, nullptr, fromFn->getLocation(), fromFn->isBare(), - fromFn->isTransparent(), fromFn->isSerialized(), IsNotDynamic, IsNotDistributed, - IsNotRuntimeAccessible, fromFn->getEntryCount(), fromFn->isThunk(), - fromFn->getClassSubclassScope(), fromFn->getInlineStrategy(), fromFn->getEffectsKind(), - nullptr, fromFn->getDebugScope()); + fromFn->getLinkage(), name.unbridged(), newTy, nullptr, + fromFn->getLocation(), fromFn->isBare(), fromFn->isTransparent(), + fromFn->getSerializedKind(), IsNotDynamic, IsNotDistributed, + IsNotRuntimeAccessible, fromFn->getEntryCount(), fromFn->isThunk(), + fromFn->getClassSubclassScope(), fromFn->getInlineStrategy(), + fromFn->getEffectsKind(), nullptr, fromFn->getDebugScope()); return {newF}; } diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index c96e73bbf10c9..28c2ffce5d1b9 100644 --- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -761,7 +761,7 @@ class PromotedParamCloner : public SILClonerWithScopes { public: PromotedParamCloner(SILOptFunctionBuilder &FuncBuilder, SILFunction *Orig, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArgIndexList &PromotedArgIndices, StringRef ClonedName); void populateCloned(); @@ -770,7 +770,7 @@ class PromotedParamCloner : public SILClonerWithScopes { private: static SILFunction *initCloned(SILOptFunctionBuilder &FuncBuilder, - SILFunction *Orig, IsSerialized_t Serialized, + SILFunction *Orig, SerializedKind_t Serialized, ArgIndexList &PromotedArgIndices, StringRef ClonedName); @@ -789,7 +789,7 @@ class PromotedParamCloner : public SILClonerWithScopes { PromotedParamCloner::PromotedParamCloner(SILOptFunctionBuilder &FuncBuilder, SILFunction *Orig, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArgIndexList &PromotedArgIndices, StringRef ClonedName) : SILClonerWithScopes(*initCloned( @@ -800,7 +800,7 @@ PromotedParamCloner::PromotedParamCloner(SILOptFunctionBuilder &FuncBuilder, getCloned()->getDebugScope()->getParentFunction()); } -static std::string getClonedName(SILFunction *F, IsSerialized_t Serialized, +static std::string getClonedName(SILFunction *F, SerializedKind_t Serialized, ArgIndexList &PromotedArgIndices) { auto P = Demangle::SpecializationPass::AllocBoxToStack; Mangle::FunctionSignatureSpecializationMangler Mangler(P, Serialized, F); @@ -815,7 +815,7 @@ static std::string getClonedName(SILFunction *F, IsSerialized_t Serialized, /// parameters (which are specified by PromotedArgIndices). SILFunction *PromotedParamCloner::initCloned(SILOptFunctionBuilder &FuncBuilder, SILFunction *Orig, - IsSerialized_t Serialized, + SerializedKind_t Serialized, ArgIndexList &PromotedArgIndices, StringRef ClonedName) { SILModule &M = Orig->getModule(); @@ -1041,22 +1041,19 @@ specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply, auto *F = FRI->getReferencedFunction(); assert(F && "Expected a referenced function!"); - IsSerialized_t Serialized = IsNotSerialized; - if (Apply.getFunction()->isSerialized()) - Serialized = IsSerialized; - + SerializedKind_t serializedKind = Apply.getFunction()->getSerializedKind(); std::string ClonedName = - getClonedName(F, Serialized, PromotedCalleeArgIndices); + getClonedName(F, serializedKind, PromotedCalleeArgIndices); auto &M = Apply.getModule(); SILFunction *ClonedFn; if (auto *PrevFn = M.lookUpFunction(ClonedName)) { - assert(PrevFn->isSerialized() == Serialized); + assert(PrevFn->getSerializedKind() == serializedKind); ClonedFn = PrevFn; } else { // Clone the function the existing ApplySite references. - PromotedParamCloner Cloner(FuncBuilder, F, Serialized, + PromotedParamCloner Cloner(FuncBuilder, F, serializedKind, PromotedCalleeArgIndices, ClonedName); Cloner.populateCloned(); diff --git a/lib/SILOptimizer/Transforms/VTableSpecializer.cpp b/lib/SILOptimizer/Transforms/VTableSpecializer.cpp index 027225e90ca8e..580da21a9056c 100644 --- a/lib/SILOptimizer/Transforms/VTableSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/VTableSpecializer.cpp @@ -230,7 +230,7 @@ static SILFunction *specializeVTableMethod(SILFunction *origMethod, module.linkFunction(SpecializedF, SILModule::LinkingMode::LinkAll); SpecializedF->setLinkage(SILLinkage::Public); - SpecializedF->setSerialized(IsNotSerialized); + SpecializedF->setSerializedKind(IsNotSerialized); return SpecializedF; } diff --git a/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp b/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp index 8546d05a8cad1..bd478503f96fd 100644 --- a/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp +++ b/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp @@ -426,8 +426,8 @@ class SerializeSILPass : public SILModuleTransform { /// optimizations and for a better dead function elimination. void removeSerializedFlagFromAllFunctions(SILModule &M) { for (auto &F : M) { - bool wasSerialized = F.isSerialized() != IsNotSerialized; - F.setSerialized(IsNotSerialized); + bool wasSerialized = !F.isNotSerialized(); + F.setSerializedKind(IsNotSerialized); // We are removing [serialized] from the function. This will change how // opaque archetypes are lowered in SIL - they might lower to their @@ -459,15 +459,15 @@ class SerializeSILPass : public SILModuleTransform { } for (auto &WT : M.getWitnessTables()) { - WT.setSerialized(IsNotSerialized); + WT.setSerializedKind(IsNotSerialized); } for (auto &VT : M.getVTables()) { - VT->setSerialized(IsNotSerialized); + VT->setSerializedKind(IsNotSerialized); } for (auto &Deinit : M.getMoveOnlyDeinits()) { - Deinit->setSerialized(IsNotSerialized); + Deinit->setSerializedKind(IsNotSerialized); } } diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp index 15171199a291d..1c188e8b9b49a 100644 --- a/lib/SILOptimizer/Utils/Devirtualize.cpp +++ b/lib/SILOptimizer/Utils/Devirtualize.cpp @@ -719,6 +719,7 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd, return false; } + // pcmo TODO: check for tri-state serialized kind if (applySite.getFunction()->isSerialized()) { // function_ref inside fragile function cannot reference a private or // hidden symbol. @@ -1167,6 +1168,7 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite, bool isMandatory) if (!f) return false; + // pcmo TODO: check for tri-state serialized kind if (applySite.getFunction()->isSerialized()) { // function_ref inside fragile function cannot reference a private or // hidden symbol. diff --git a/lib/SILOptimizer/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp index 3f40e9effc6e2..b3c39ee99764d 100644 --- a/lib/SILOptimizer/Utils/GenericCloner.cpp +++ b/lib/SILOptimizer/Utils/GenericCloner.cpp @@ -43,7 +43,7 @@ SILFunction *GenericCloner::createDeclaration( getSpecializedLinkage(Orig, Orig->getLinkage()), NewName, ReInfo.getSpecializedType(), ReInfo.getSpecializedGenericEnvironment(), Orig->getLocation(), Orig->isBare(), Orig->isTransparent(), - ReInfo.isSerialized(), IsNotDynamic, IsNotDistributed, + ReInfo.getSerializedKind(), IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible, Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(), Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig, Orig->getDebugScope()); diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index ec02377b9488d..33e814cf9b0bf 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -598,11 +598,11 @@ bool ReabstractionInfo::canBeSpecialized(ApplySite Apply, SILFunction *Callee, ReabstractionInfo::ReabstractionInfo( ModuleDecl *targetModule, bool isWholeModule, ApplySite Apply, - SILFunction *Callee, SubstitutionMap ParamSubs, IsSerialized_t Serialized, - bool ConvertIndirectToDirect, bool dropMetatypeArgs, OptRemark::Emitter *ORE) + SILFunction *Callee, SubstitutionMap ParamSubs, SerializedKind_t Serialized, + bool ConvertIndirectToDirect, bool dropMetatypeArgs, + OptRemark::Emitter *ORE) : ConvertIndirectToDirect(ConvertIndirectToDirect), - dropMetatypeArgs(dropMetatypeArgs), - M(&Callee->getModule()), + dropMetatypeArgs(dropMetatypeArgs), M(&Callee->getModule()), TargetModule(targetModule), isWholeModule(isWholeModule), Serialized(Serialized) { if (!prepareAndCheck(Apply, Callee, ParamSubs, ORE)) @@ -1948,7 +1948,7 @@ ReabstractionInfo::ReabstractionInfo(ModuleDecl *targetModule, : M(&Callee->getModule()), TargetModule(targetModule), isWholeModule(isWholeModule), isPrespecialization(isPrespecialization) { Serialized = - this->isPrespecialization ? IsNotSerialized : Callee->isSerialized(); + this->isPrespecialization ? IsNotSerialized : Callee->getSerializedKind(); if (shouldNotSpecialize(Callee, nullptr)) return; @@ -1987,11 +1987,11 @@ GenericFuncSpecializer::GenericFuncSpecializer( if (ReInfo.isPartialSpecialization()) { Mangle::PartialSpecializationMangler Mangler( - GenericFunc, FnTy, ReInfo.isSerialized(), /*isReAbstracted*/ true); + GenericFunc, FnTy, ReInfo.getSerializedKind(), /*isReAbstracted*/ true); ClonedName = Mangler.mangle(); } else { Mangle::GenericSpecializationMangler Mangler( - GenericFunc, ReInfo.isSerialized()); + GenericFunc, ReInfo.getSerializedKind()); if (ReInfo.isPrespecialized()) { ClonedName = Mangler.manglePrespecialized(ParamSubs); } else { @@ -2509,13 +2509,13 @@ class ReabstractionThunkGenerator { SpecializedFunc(SpecializedFunc), ReInfo(ReInfo), OrigPAI(OrigPAI), Loc(RegularLocation::getAutoGeneratedLocation()) { if (!ReInfo.isPartialSpecialization()) { - Mangle::GenericSpecializationMangler Mangler(OrigF, ReInfo.isSerialized()); + Mangle::GenericSpecializationMangler Mangler(OrigF, ReInfo.getSerializedKind()); ThunkName = Mangler.mangleNotReabstracted( ReInfo.getCalleeParamSubstitutionMap(), ReInfo.hasDroppedMetatypeArgs()); } else { Mangle::PartialSpecializationMangler Mangler( - OrigF, ReInfo.getSpecializedType(), ReInfo.isSerialized(), + OrigF, ReInfo.getSpecializedType(), ReInfo.getSerializedKind(), /*isReAbstracted*/ false); ThunkName = Mangler.mangle(); @@ -2544,7 +2544,7 @@ SILFunction *ReabstractionThunkGenerator::createThunk() { CanSILFunctionType thunkType = ReInfo.createThunkType(OrigPAI); SILFunction *Thunk = FunctionBuilder.getOrCreateSharedFunction( Loc, ThunkName, thunkType, IsBare, IsTransparent, - ReInfo.isSerialized(), ProfileCounter(), IsThunk, IsNotDynamic, + ReInfo.getSerializedKind(), ProfileCounter(), IsThunk, IsNotDynamic, IsNotDistributed, IsNotRuntimeAccessible); // Re-use an existing thunk. if (!Thunk->empty()) @@ -2808,7 +2808,7 @@ static bool createPrespecialized(StringRef UnspecializedName, M.linkFunction(SpecializedF, SILModule::LinkingMode::LinkAll); SpecializedF->setLinkage(SILLinkage::Public); - SpecializedF->setSerialized(IsNotSerialized); + SpecializedF->setSerializedKind(IsNotSerialized); return true; } @@ -3006,7 +3006,7 @@ bool usePrespecialized( ReabstractionInfo layoutReInfo = ReabstractionInfo( funcBuilder.getModule().getSwiftModule(), funcBuilder.getModule().isWholeModule(), apply, refF, newSubstMap, - apply.getFunction()->isSerialized() ? IsSerialized : IsNotSerialized, + apply.getFunction()->getSerializedKind(), /*ConvertIndirectToDirect=*/ true, /*dropMetatypeArgs=*/ false, nullptr); if (layoutReInfo.getSpecializedType() == reInfo.getSpecializedType()) { @@ -3018,7 +3018,7 @@ bool usePrespecialized( } SubstitutionMap subs = reInfo.getCalleeParamSubstitutionMap(); - Mangle::GenericSpecializationMangler mangler(refF, reInfo.isSerialized()); + Mangle::GenericSpecializationMangler mangler(refF, reInfo.getSerializedKind()); std::string name = reInfo.isPrespecialized() ? mangler.manglePrespecialized(subs) : mangler.mangleReabstracted(subs, reInfo.needAlternativeMangling()); @@ -3047,7 +3047,7 @@ bool usePrespecialized( // TODO: Deduplicate SubstitutionMap subs = reInfo.getCalleeParamSubstitutionMap(); - Mangle::GenericSpecializationMangler mangler(refF, reInfo.isSerialized()); + Mangle::GenericSpecializationMangler mangler(refF, reInfo.getSerializedKind()); std::string name = reInfo.isPrespecialized() ? mangler.manglePrespecialized(subs) : mangler.mangleReabstracted( @@ -3140,10 +3140,12 @@ void swift::trySpecializeApplyOfGeneric( // callee either. bool needSetLinkage = false; if (isMandatory) { - if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline()) + // pcmo TODO: remove F->isSerialiezd() and pass its kind to + // canBeInlinedIntoCaller instead. + if (F->isSerialized() && !RefF->canBeInlinedIntoCaller()) needSetLinkage = true; } else { - if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline()) + if (F->isSerialized() && !RefF->canBeInlinedIntoCaller()) return; if (shouldNotSpecialize(RefF, F)) @@ -3153,9 +3155,7 @@ void swift::trySpecializeApplyOfGeneric( // If the caller and callee are both fragile, preserve the fragility when // cloning the callee. Otherwise, strip it off so that we can optimize // the body more. - IsSerialized_t Serialized = IsNotSerialized; - if (F->isSerialized()) - Serialized = IsSerialized; + SerializedKind_t serializedKind = F->getSerializedKind(); // If it is OnoneSupport consider all specializations as non-serialized // as we do not SIL serialize their bodies. @@ -3165,12 +3165,12 @@ void swift::trySpecializeApplyOfGeneric( if (createPrespecializations(Apply, RefF, FuncBuilder)) { return; } - Serialized = IsNotSerialized; + serializedKind = IsNotSerialized; } ReabstractionInfo ReInfo(FuncBuilder.getModule().getSwiftModule(), FuncBuilder.getModule().isWholeModule(), Apply, RefF, - Apply.getSubstitutionMap(), Serialized, + Apply.getSubstitutionMap(), serializedKind, /*ConvertIndirectToDirect=*/ true, /*dropMetatypeArgs=*/ canDropMetatypeArgs(Apply, RefF), &ORE); @@ -3265,20 +3265,22 @@ void swift::trySpecializeApplyOfGeneric( return; } + // pcmo TODO: remove F->isSerialiezd() and pass its kind to + // canBeInlinedIntoCaller instead. if (needSetLinkage) { - assert(F->isSerialized() && !RefF->hasValidLinkageForFragileInline()); + assert(F->isSerialized() && !RefF->canBeInlinedIntoCaller()); // If called from a serialized function we cannot make the specialized function // shared and non-serialized. The only other option is to keep the original // function's linkage. It's not great, because it can prevent dead code // elimination - usually the original function is a public function. SpecializedF->setLinkage(RefF->getLinkage()); - SpecializedF->setSerialized(IsNotSerialized); - } else if (F->isSerialized() && !SpecializedF->hasValidLinkageForFragileInline()) { + SpecializedF->setSerializedKind(IsNotSerialized); + } else if (F->isSerialized() && !SpecializedF->canBeInlinedIntoCaller()) { // If the specialized function already exists as a "IsNotSerialized" function, // but now it's called from a "IsSerialized" function, we need to mark it as // IsSerialized. - SpecializedF->setSerialized(IsSerialized); - assert(SpecializedF->hasValidLinkageForFragileInline()); + SpecializedF->setSerializedKind(IsSerialized); + assert(SpecializedF->canBeInlinedIntoCaller()); // ... including all referenced shared functions. FuncBuilder.getModule().linkFunction(SpecializedF.getFunction(), diff --git a/lib/SILOptimizer/Utils/InstOptUtils.cpp b/lib/SILOptimizer/Utils/InstOptUtils.cpp index 7a04ebd1938e9..c10e83edccae0 100644 --- a/lib/SILOptimizer/Utils/InstOptUtils.cpp +++ b/lib/SILOptimizer/Utils/InstOptUtils.cpp @@ -559,7 +559,7 @@ TermInst *swift::addArgumentsToBranch(ArrayRef vals, } SILLinkage swift::getSpecializedLinkage(SILFunction *f, SILLinkage linkage) { - if (hasPrivateVisibility(linkage) && !f->isSerialized()) { + if (hasPrivateVisibility(linkage) && f->isNotSerialized()) { // Specializations of private symbols should remain so, unless // they were serialized, which can only happen when specializing // definitions from a standard library built with -sil-serialize-all. diff --git a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp index 6ddb982707f8d..00b027e293856 100644 --- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp +++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp @@ -846,8 +846,10 @@ SILFunction *swift::getEligibleFunction(FullApplySite AI, } // A non-fragile function may not be inlined into a fragile function. + // pcmo TODO: remove Caller->isSerialized() and pass its kind to + // canBeInlinedIntoCaller instead. if (Caller->isSerialized() && - !Callee->hasValidLinkageForFragileInline()) { + !Callee->canBeInlinedIntoCaller()) { if (!Callee->hasValidLinkageForFragileRef()) { llvm::errs() << "caller: " << Caller->getName() << "\n"; llvm::errs() << "callee: " << Callee->getName() << "\n"; @@ -857,17 +859,6 @@ SILFunction *swift::getEligibleFunction(FullApplySite AI, return nullptr; } - // If the caller is [serialized] due to explicit `@inlinable` but - // the callee was [serialized_for_package] due to package-cmo, the - // callee is [serialized] and might contain loadable types, which - // is normally disallowed. This check prevents such loadable types - // from being inlined. - if (Caller->isSerialized() && - !Caller->isSerializedForPackage() && - Callee->isSerializedForPackage()) { - return nullptr; - } - // Inlining self-recursive functions into other functions can result // in excessive code duplication since we run the inliner multiple // times in our pipeline diff --git a/lib/SILOptimizer/Utils/SpecializationMangler.cpp b/lib/SILOptimizer/Utils/SpecializationMangler.cpp index fbfb59f809a92..1c48581dda109 100644 --- a/lib/SILOptimizer/Utils/SpecializationMangler.cpp +++ b/lib/SILOptimizer/Utils/SpecializationMangler.cpp @@ -37,10 +37,9 @@ std::string PartialSpecializationMangler::mangle() { // Function Signature Optimizations //===----------------------------------------------------------------------===// -FunctionSignatureSpecializationMangler:: -FunctionSignatureSpecializationMangler(Demangle::SpecializationPass P, - IsSerialized_t Serialized, SILFunction *F) - : SpecializationMangler(P, Serialized, F) { +FunctionSignatureSpecializationMangler::FunctionSignatureSpecializationMangler( + Demangle::SpecializationPass P, SerializedKind_t Serialized, SILFunction *F) + : SpecializationMangler(P, Serialized, F) { for (unsigned i = 0, e = F->getConventions().getNumSILArguments(); i != e; ++i) { (void)i; diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index 604db6dc8731d..b42a330f465f0 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -564,16 +564,16 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, IdentifierID replacedFunctionID; IdentifierID usedAdHocWitnessFunctionID; GenericSignatureID genericSigID; - unsigned rawLinkage, isTransparent, isSerialized, isSerializedForPackage, - isThunk, isWithoutActuallyEscapingThunk, specialPurpose, inlineStrategy, + unsigned rawLinkage, isTransparent, serializedKind, isThunk, + isWithoutActuallyEscapingThunk, specialPurpose, inlineStrategy, optimizationMode, perfConstr, subclassScope, hasCReferences, effect, numAttrs, hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass, isDistributed, isRuntimeAccessible, forceEnableLexicalLifetimes; ArrayRef SemanticsIDs; SILFunctionLayout::readRecord( - scratch, rawLinkage, isTransparent, isSerialized, isSerializedForPackage, - isThunk, isWithoutActuallyEscapingThunk, specialPurpose, inlineStrategy, + scratch, rawLinkage, isTransparent, serializedKind, isThunk, + isWithoutActuallyEscapingThunk, specialPurpose, inlineStrategy, optimizationMode, perfConstr, subclassScope, hasCReferences, effect, numAttrs, hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass, @@ -641,7 +641,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, // as serialized, since we no longer need to enforce resilience // boundaries. if (SILMod.isSerialized()) - isSerialized = IsNotSerialized; + serializedKind = IsNotSerialized; SILSerializationFunctionBuilder builder(SILMod); @@ -655,20 +655,21 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, return MF->diagnoseFatal(std::move(error)); } - fn->setSerialized(IsSerialized_t(isSerialized)); + fn->setSerializedKind(SerializedKind_t(serializedKind)); + // pcmo TODO: check if this can be deleted // If fn was serialized in a module with package serialization // enabled, a new attribute [serialized_for_package] was added // to its definition. Preserve the attribute here if the current // module is in the same package, and use it to determine the // resilience expansion for this function. auto loadedModule = getFile()->getParentModule(); - if (isSerializedForPackage == IsSerializedForPackage && + if (SerializedKind_t(serializedKind) == IsSerializedForPackage && loadedModule->isResilient() && loadedModule != SILMod.getSwiftModule() && loadedModule->serializePackageEnabled() && loadedModule->inSamePackage(SILMod.getSwiftModule())) - fn->setSerializedForPackage(IsSerializedForPackage); + fn->setSerializedKind(IsSerializedForPackage); // If the serialized function comes from the same module, we're merging // modules, and can update the linkage directly. This is needed to @@ -716,8 +717,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, fn = builder.createDeclaration(name, ty, loc); fn->setLinkage(linkage); fn->setTransparent(IsTransparent_t(isTransparent == 1)); - fn->setSerialized(IsSerialized_t(isSerialized)); - fn->setSerializedForPackage(IsSerializedForPackage_t(isSerializedForPackage)); + fn->setSerializedKind(SerializedKind_t(serializedKind)); fn->setThunk(IsThunk_t(isThunk)); fn->setWithoutActuallyEscapingThunk(bool(isWithoutActuallyEscapingThunk)); fn->setInlineStrategy(Inline_t(inlineStrategy)); @@ -981,8 +981,8 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, Callback->didDeserializeFunctionBody(MF->getAssociatedModule(), fn); if (!MF->isSIB() && !SILMod.isSerialized()) { - assert((fn->isSerialized() || fn->empty()) && - "deserialized function must have the IsSerialized flag set"); + assert((!fn->isNotSerialized() || fn->empty()) && + "deserialized function must have the IsSerialized or IsSerializedForPackage flag set"); } return fn; } @@ -3535,16 +3535,16 @@ bool SILDeserializer::hasSILFunction(StringRef Name, IdentifierID replacedFunctionID; IdentifierID usedAdHocWitnessFunctionID; GenericSignatureID genericSigID; - unsigned rawLinkage, isTransparent, isSerialized, isSerializedForPackage, - isThunk, isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy, + unsigned rawLinkage, isTransparent, serializedKind, isThunk, + isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy, optimizationMode, perfConstr, subclassScope, hasCReferences, effect, numSpecAttrs, hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass, isDistributed, isRuntimeAccessible, forceEnableLexicalLifetimes; ArrayRef SemanticsIDs; SILFunctionLayout::readRecord( - scratch, rawLinkage, isTransparent, isSerialized, isSerializedForPackage, - isThunk, isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy, + scratch, rawLinkage, isTransparent, serializedKind, isThunk, + isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy, optimizationMode, perfConstr, subclassScope, hasCReferences, effect, numSpecAttrs, hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available), isDynamic, isExactSelfClass, @@ -3638,8 +3638,8 @@ SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name) { TypeID TyID; DeclID dID; - unsigned rawLinkage, isSerialized, IsDeclaration, IsLet; - SILGlobalVarLayout::readRecord(scratch, rawLinkage, isSerialized, + unsigned rawLinkage, serializedKind, IsDeclaration, IsLet; + SILGlobalVarLayout::readRecord(scratch, rawLinkage, serializedKind, IsDeclaration, IsLet, TyID, dID); if (TyID == 0) { LLVM_DEBUG(llvm::dbgs() << "SILGlobalVariable typeID is 0.\n"); @@ -3655,7 +3655,7 @@ SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name) { auto Ty = MF->getType(TyID); SILGlobalVariable *v = SILGlobalVariable::create( - SILMod, linkage.value(), isSerialized ? IsSerialized : IsNotSerialized, + SILMod, linkage.value(), SerializedKind_t(serializedKind), Name.str(), getSILType(Ty, SILValueCategory::Object, nullptr), std::nullopt, dID ? cast(MF->getDecl(dID)) : nullptr); v->setLet(IsLet); @@ -3848,11 +3848,11 @@ SILVTable *SILDeserializer::readVTable(DeclID VId) { // as serialized, since we no longer need to enforce resilience // boundaries. if (SILMod.isSerialized()) - Serialized = 0; + Serialized = unsigned(SerializedKind_t::IsNotSerialized); SILVTable *vT = SILVTable::create( SILMod, theClass, - Serialized ? IsSerialized : IsNotSerialized, + SerializedKind_t(Serialized), vtableEntries); vTableOrOffset.set(vT, true /*isFullyDeserialized*/); @@ -3932,7 +3932,7 @@ SILMoveOnlyDeinit *SILDeserializer::readMoveOnlyDeinit(DeclID tableID) { rawSerialized = 0; auto *deinit = SILMoveOnlyDeinit::create( - SILMod, theNomDecl, rawSerialized ? IsSerialized : IsNotSerialized, + SILMod, theNomDecl, SerializedKind_t(rawSerialized), theFunc); moveOnlyDeinitOrOffset.set(deinit, true /*isFullyDeserialized*/); @@ -4154,7 +4154,6 @@ llvm::Expected ProtocolConformanceID conformance; WitnessTableLayout::readRecord(scratch, RawLinkage, IsDeclaration, Serialized, conformance); - auto Linkage = fromStableSILLinkage(RawLinkage); if (!Linkage) { LLVM_DEBUG(llvm::dbgs() << "invalid linkage code " << RawLinkage @@ -4229,10 +4228,10 @@ llvm::Expected // as serialized, since we no longer need to enforce resilience // boundaries. if (SILMod.isSerialized()) - Serialized = 0; + Serialized = unsigned(SerializedKind_t::IsNotSerialized); wT->convertToDefinition(witnessEntries, conditionalConformances, - Serialized ? IsSerialized : IsNotSerialized); + SerializedKind_t(Serialized)); wTableOrOffset.set(wT, /*fully deserialized*/ true); if (Callback) Callback->didDeserializeWitnessTableEntries(MF->getAssociatedModule(), wT); diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index f68dd64b581c8..5f613242fc787 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,8 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 874; // SDKVersion +const uint16_t SWIFTMODULE_VERSION_MINOR = + 875; // Add package field to SerializedKind_t /// A standard hash seed used for all string hashes in a serialized module. /// diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index 8a4d71a67ef61..38196e664fb3a 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -183,7 +183,7 @@ namespace sil_block { using VTableLayout = BCRecordLayout< SIL_VTABLE, DeclIDField, // Class Decl - BCFixed<1> // IsSerialized. + BCFixed<2> // SerializedKind. >; using VTableEntryLayout = BCRecordLayout< @@ -198,13 +198,13 @@ namespace sil_block { SIL_MOVEONLY_DEINIT, DeclIDField, // Class Decl DeclIDField, // SILFunction name - BCFixed<1> // IsSerialized. + BCFixed<2> // SerializedKind. >; using PropertyLayout = BCRecordLayout< SIL_PROPERTY, DeclIDField, // Property decl - BCFixed<1>, // Is serialized + BCFixed<2>, // SerializedKind BCArray // Encoded key path component // Any substitutions or conformances required for the key path component // follow. @@ -216,7 +216,7 @@ namespace sil_block { BCFixed<1>, // Is this a declaration. We represent this separately // from whether or not we have entries since we can // have empty witness tables. - BCFixed<1>, // IsSerialized. + BCFixed<2>, // SerializedKind. ProtocolConformanceIDField // conformance // Witness table entries will be serialized after. >; @@ -266,7 +266,7 @@ namespace sil_block { using SILGlobalVarLayout = BCRecordLayout< SIL_GLOBALVAR, SILLinkageField, - BCFixed<1>, // serialized + BCFixed<2>, // serialized BCFixed<1>, // Is this a declaration. BCFixed<1>, // Is this a let variable. TypeIDField, @@ -278,7 +278,7 @@ namespace sil_block { DeclIDField, // Original function name SILLinkageField, // Linkage BCFixed<1>, // Is declaration? - BCFixed<1>, // Is serialized? + BCFixed<2>, // Is serialized? DifferentiabilityKindField, // Differentiability kind GenericSignatureIDField, // Derivative function generic signature DeclIDField, // JVP function name @@ -291,8 +291,7 @@ namespace sil_block { using SILFunctionLayout = BCRecordLayout, // transparent - BCFixed<1>, // serialized - BCFixed<1>, // serializedForPackage + BCFixed<2>, // serializedKind BCFixed<2>, // thunks: signature optimized/reabstraction BCFixed<1>, // without_actually_escaping BCFixed<3>, // specialPurpose diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 36b99c4382181..537bc16bee48d 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -277,7 +277,8 @@ namespace { void writeSILMoveOnlyDeinit(const SILMoveOnlyDeinit &deinit); void writeSILGlobalVar(const SILGlobalVariable &g); void writeSILWitnessTable(const SILWitnessTable &wt); - void writeSILWitnessTableEntry(const SILWitnessTable::Entry &entry); + void writeSILWitnessTableEntry(const SILWitnessTable::Entry &entry, + std::optional serializedKind = std::nullopt); void writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt); void writeSILDifferentiabilityWitness(const SILDifferentiabilityWitness &dw); @@ -375,7 +376,8 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F, } if (F->getLinkage() == SILLinkage::Shared) { - assert(F->isSerialized() || F->hasForeignBody()); + assert(!F->isNotSerialized() || + F->hasForeignBody()); FuncsToEmit[F] = false; functionWorklist.push_back(F); @@ -493,7 +495,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { } unsigned numAttrs = NoBody ? 0 : F.getSpecializeAttrs().size(); - + // pcmo TODO: check if package-cmo is enabled auto resilience = F.getModule().getSwiftModule()->getResilienceStrategy(); bool serializeDerivedEffects = (resilience != ResilienceStrategy::Resilient) && !F.hasSemanticsAttr("optimize.no.crossmodule"); @@ -514,9 +516,8 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { SILFunctionLayout::emitRecord( Out, ScratchRecord, abbrCode, toStableSILLinkage(Linkage), - (unsigned)F.isTransparent(), (unsigned)F.isSerialized(), - (unsigned)F.isSerializedForPackage(), (unsigned)F.isThunk(), - (unsigned)F.isWithoutActuallyEscapingThunk(), + (unsigned)F.isTransparent(), (unsigned)F.getSerializedKind(), + (unsigned)F.isThunk(), (unsigned)F.isWithoutActuallyEscapingThunk(), (unsigned)F.getSpecialPurpose(), (unsigned)F.getInlineStrategy(), (unsigned)F.getOptimizationMode(), (unsigned)F.getPerfConstraints(), (unsigned)F.getClassSubclassScope(), (unsigned)F.hasCReferences(), @@ -2872,13 +2873,13 @@ void SILSerializer::writeSILGlobalVar(const SILGlobalVariable &g) { SILGlobalVarLayout::emitRecord(Out, ScratchRecord, SILAbbrCodes[SILGlobalVarLayout::Code], toStableSILLinkage(g.getLinkage()), - g.isSerialized() ? 1 : 0, + (unsigned)g.getSerializedKind(), (unsigned)!g.isDefinition(), (unsigned)g.isLet(), TyID, dID); // Don't emit the initializer instructions if not marked as "serialized". - if (!g.isSerialized()) + if (g.isNotSerialized()) return; ValueIDs.clear(); @@ -2918,13 +2919,15 @@ void SILSerializer::writeSILVTable(const SILVTable &vt) { VTableOffset.push_back(Out.GetCurrentBitNo()); VTableLayout::emitRecord(Out, ScratchRecord, SILAbbrCodes[VTableLayout::Code], S.addDeclRef(vt.getClass()), - vt.isSerialized() == IsSerialized ? 1 : 0); + (unsigned)vt.getSerializedKind()); for (auto &entry : vt.getEntries()) { SmallVector ListOfValues; SILFunction *impl = entry.getImplementation(); - if (ShouldSerializeAll || impl->hasValidLinkageForFragileRef()) { + if (ShouldSerializeAll || + impl->hasValidLinkageForFragileRef(vt.getSerializedKind(), + /*assumeFragileCaller*/ false)) { handleSILDeclRef(S, entry.getMethod(), ListOfValues); addReferencedSILFunction(impl, true); // Each entry is a pair of SILDeclRef and SILFunction. @@ -2968,7 +2971,7 @@ void SILSerializer::writeSILMoveOnlyDeinit(const SILMoveOnlyDeinit &deinit) { Out, ScratchRecord, SILAbbrCodes[MoveOnlyDeinitLayout::Code], S.addDeclRef(deinit.getNominalDecl()), S.addUniquedStringRef(impl->getName()), - deinit.isSerialized() == IsSerialized ? 1 : 0); + deinit.getSerializedKind()); } void SILSerializer::writeSILProperty(const SILProperty &prop) { @@ -2986,7 +2989,7 @@ void SILSerializer::writeSILProperty(const SILProperty &prop) { Out, ScratchRecord, SILAbbrCodes[PropertyLayout::Code], S.addDeclRef(prop.getDecl()), - prop.isSerialized(), + prop.getSerializedKind(), componentValues); } @@ -3000,7 +3003,7 @@ void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) { SILAbbrCodes[WitnessTableLayout::Code], toStableSILLinkage(wt.getLinkage()), unsigned(wt.isDeclaration()), - wt.isSerialized() == IsSerialized ? 1 : 0, + unsigned(wt.getSerializedKind()), conformanceID); // If we have a declaration, do not attempt to serialize entries. @@ -3008,7 +3011,7 @@ void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) { return; for (auto &entry : wt.getEntries()) { - writeSILWitnessTableEntry(entry); + writeSILWitnessTableEntry(entry, wt.getSerializedKind()); } for (auto conditional : wt.getConditionalConformances()) { @@ -3022,7 +3025,8 @@ void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) { } void SILSerializer::writeSILWitnessTableEntry( - const SILWitnessTable::Entry &entry) { + const SILWitnessTable::Entry &entry, + std::optional serializedKind) { if (entry.getKind() == SILWitnessTable::BaseProtocol) { auto &baseWitness = entry.getBaseProtocolWitness(); @@ -3063,7 +3067,9 @@ void SILSerializer::writeSILWitnessTableEntry( handleSILDeclRef(S, methodWitness.Requirement, ListOfValues); IdentifierID witnessID = 0; SILFunction *witness = methodWitness.Witness; - if (witness && witness->hasValidLinkageForFragileRef()) { + if (witness && + witness->hasValidLinkageForFragileRef(serializedKind, + /*assumeFragileCaller*/ false)) { addReferencedSILFunction(witness, true); witnessID = S.addUniquedStringRef(witness->getName()); } @@ -3096,7 +3102,6 @@ writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt) { SILAbbrCodes[DefaultWitnessTableNoEntryLayout::Code]); continue; } - writeSILWitnessTableEntry(entry); } } @@ -3169,7 +3174,8 @@ bool SILSerializer::shouldEmitFunctionBody(const SILFunction *F, // If F is serialized, we should always emit its body. // Shared functions are only serialized if they are referenced from another // serialized function. This is handled in `addReferencedSILFunction`. - if (F->isSerialized() && !hasSharedVisibility(F->getLinkage())) + if (!F->isNotSerialized() && + !hasSharedVisibility(F->getLinkage())) return true; return false; @@ -3231,13 +3237,13 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // serialize everything. // FIXME: Resilience: could write out vtable for fragile classes. for (const auto &vt : SILMod->getVTables()) { - if ((ShouldSerializeAll || vt->isSerialized()) && + if ((ShouldSerializeAll || !vt->isNotSerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(vt->getClass())) writeSILVTable(*vt); } for (const auto &deinit : SILMod->getMoveOnlyDeinits()) { - if ((ShouldSerializeAll || deinit->isSerialized()) && + if ((ShouldSerializeAll || !deinit->isNotSerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( deinit->getNominalDecl())) writeSILMoveOnlyDeinit(*deinit); @@ -3245,7 +3251,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Write out property descriptors. for (const SILProperty &prop : SILMod->getPropertyList()) { - if ((ShouldSerializeAll || prop.isSerialized()) && + if ((ShouldSerializeAll || !prop.isNotSerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( prop.getDecl()->getInnermostDeclContext())) writeSILProperty(prop); @@ -3253,7 +3259,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Write out fragile WitnessTables. for (const SILWitnessTable &wt : SILMod->getWitnessTables()) { - if ((ShouldSerializeAll || wt.isSerialized()) && + if ((ShouldSerializeAll || !wt.isNotSerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( wt.getConformance()->getDeclContext())) writeSILWitnessTable(wt); @@ -3270,7 +3276,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Add global variables that must be emitted to the list. for (const SILGlobalVariable &g : SILMod->getSILGlobals()) { - if (g.isSerialized() || ShouldSerializeAll) + if (!g.isNotSerialized() || ShouldSerializeAll) addReferencedGlobalVariable(&g); } @@ -3316,6 +3322,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Now write function declarations for every function we've // emitted a reference to without emitting a function body for. + // pcmo TODO: check if package-cmo is enabled auto resilience = SILMod->getSwiftModule()->getResilienceStrategy(); for (const SILFunction &F : *SILMod) { auto iter = FuncsToEmit.find(&F); diff --git a/test/AutoDiff/compiler_crashers/issue-54722-apply-opened-opened-existential-argument.swift b/test/AutoDiff/compiler_crashers/issue-54722-apply-opened-opened-existential-argument.swift index 8ef9080e3ec1a..e6d59341206b6 100644 --- a/test/AutoDiff/compiler_crashers/issue-54722-apply-opened-opened-existential-argument.swift +++ b/test/AutoDiff/compiler_crashers/issue-54722-apply-opened-opened-existential-argument.swift @@ -54,4 +54,4 @@ public func abs(_ x: T) -> T where T.Element: Numer // #13 0x0000000000f1a1e1 swift::autodiff::LinearMapInfo::addLinearMapToStruct(swift::autodiff::ADContext&, swift::ApplyInst*) (build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift+0xf1a1e1) // #14 0x0000000000f17925 swift::autodiff::LinearMapInfo::generateDifferentiationDataStructures(swift::autodiff::ADContext&, swift::SILFunction*) (build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift+0xf17925) // #15 0x0000000000f2615f swift::autodiff::VJPEmitter::VJPEmitter(swift::autodiff::ADContext&, swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::SILFunction*, swift::autodiff::DifferentiationInvoker) (build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift+0xf2615f) -// #16 0x0000000000e7efff (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) (build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift+0xe7efff) +// #16 0x0000000000e7efff (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::SerializedKind_t) (build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift+0xe7efff) diff --git a/test/AutoDiff/compiler_crashers_fixed/issue-55085-silgen-immutable-address-use-verification-failure.swift b/test/AutoDiff/compiler_crashers_fixed/issue-55085-silgen-immutable-address-use-verification-failure.swift index 24c46a1ccd413..ef35d0ae64916 100644 --- a/test/AutoDiff/compiler_crashers_fixed/issue-55085-silgen-immutable-address-use-verification-failure.swift +++ b/test/AutoDiff/compiler_crashers_fixed/issue-55085-silgen-immutable-address-use-verification-failure.swift @@ -67,5 +67,5 @@ func loadableOriginal(_ loadable: LoadableOriginal) -> // #10 0x0000000000f8248b swift::autodiff::PullbackEmitter::emitZeroDerivativesForNonvariedResult(swift::SILValue) // #11 0x0000000000f7fcae swift::autodiff::PullbackEmitter::run() // #12 0x0000000000f3fba4 swift::autodiff::VJPEmitter::run() -// #13 0x0000000000eb1669 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) +// #13 0x0000000000eb1669 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::SerializedKind_t) // #14 0x0000000000eaea5e (anonymous namespace)::Differentiation::run() diff --git a/test/AutoDiff/compiler_crashers_fixed/issue-56263-library-evolution-mode-crasher-property-differentiation.swift b/test/AutoDiff/compiler_crashers_fixed/issue-56263-library-evolution-mode-crasher-property-differentiation.swift index 6b4eb9e96d42e..79e527c820858 100644 --- a/test/AutoDiff/compiler_crashers_fixed/issue-56263-library-evolution-mode-crasher-property-differentiation.swift +++ b/test/AutoDiff/compiler_crashers_fixed/issue-56263-library-evolution-mode-crasher-property-differentiation.swift @@ -57,7 +57,7 @@ public struct Struct: Differentiable { // 11 swift-frontend 0x0000000109ae8196 swift::autodiff::PullbackCloner::Implementation::visitSILBasicBlock(swift::SILBasicBlock*) + 838 // 12 swift-frontend 0x0000000109ae5504 swift::autodiff::PullbackCloner::Implementation::run() + 7268 // 13 swift-frontend 0x0000000109b077d3 swift::autodiff::VJPCloner::Implementation::run() + 1539 -// 14 swift-frontend 0x0000000109c4e0b4 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) + 7172 +// 14 swift-frontend 0x0000000109c4e0b4 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILFunction*, swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::SerializedKind_t) + 7172 // 15 swift-frontend 0x0000000109c4bafa (anonymous namespace)::Differentiation::run() + 1530 // 16 swift-frontend 0x0000000109c9c86e swift::SILPassManager::runModulePass(unsigned int) + 558 // 17 swift-frontend 0x0000000109ca144a swift::SILPassManager::execute() + 666 diff --git a/test/SILOptimizer/package-cmo-closure.swift b/test/SILOptimizer/package-cmo-closure.swift new file mode 100644 index 0000000000000..08d027b464ea1 --- /dev/null +++ b/test/SILOptimizer/package-cmo-closure.swift @@ -0,0 +1,64 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-build-swift %s \ +// RUN: -module-name=Lib -package-name Pkg \ +// RUN: -parse-as-library -emit-module -emit-module-path %t/Lib.swiftmodule -I%t \ +// RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ +// RUN: -O -wmo -enable-library-evolution + +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib.sil +// RUN: %FileCheck %s --check-prefix=CHECK < %t/Lib.sil + +// REQUIRES: swift_in_compiler + +public struct Something { + public init() {} + + public func f() -> Int { + return 7 + } +} + + +@usableFromInline +func use(_ c: () -> Int) { } + +// Don't crash on this example +@inlinable +public func reproduce(_ e: Something) { + use { + return e.f() + } +} + +// use(_:) +// CHECK: sil [serialized_for_package] [canonical] @$s3Lib3useyySiyXEF : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> Int) -> () { +// CHECK: bb0(%0 : $@noescape @callee_guaranteed () -> Int): +// CHECK: [[RESULT:%.*]] = tuple () +// CHECK: return [[RESULT]] : $() +// CHECK: } // end sil function '$s3Lib3useyySiyXEF' + +// closure #1 in reproduce(_:) +// CHECK: sil shared [serialized] [canonical] @$s3Lib9reproduceyyAA9SomethingVFSiyXEfU_ : $@convention(thin) (@in_guaranteed Something) -> Int { + // function_ref Something.f() +// CHECK: bb0(%0 : @closureCapture $*Something): +// CHECK: [[REF:%.*]] = function_ref @$s3Lib9SomethingV1fSiyF : $@convention(method) (@in_guaranteed Something) -> Int +// CHECK: [[VAL:%.*]] = apply [[REF]](%0) : $@convention(method) (@in_guaranteed Something) -> Int +// CHECK: return [[VAL]] : $Int +// CHECK: } // end sil function '$s3Lib9reproduceyyAA9SomethingVFSiyXEfU_' + +// Something.f() +// CHECK: sil [serialized_for_package] [canonical] @$s3Lib9SomethingV1fSiyF : $@convention(method) (@in_guaranteed Something) -> Int { + +// Something.init() +// CHECK: sil [serialized_for_package] [canonical] @$s3Lib9SomethingVACycfC : $@convention(method) (@thin Something.Type) -> @out Something { + +// reproduce(_:) +// CHECK: sil [serialized] [canonical] @$s3Lib9reproduceyyAA9SomethingVF : $@convention(thin) (@in_guaranteed Something) -> () { +// CHECK: bb0(%0 : $*Something): +// CHECK: [[CLOSURE_PTR:%.*]] = function_ref @$s3Lib9reproduceyyAA9SomethingVFSiyXEfU_ : $@convention(thin) (@in_guaranteed Something) -> Int +// CHECK: [[CLOSURE_W_ARG:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[CLOSURE_PTR]](%0) : $@convention(thin) (@in_guaranteed Something) -> Int +// CHECK: [[MARKED:%.*]] = mark_dependence [nonescaping] [[CLOSURE_W_ARG]] : $@noescape @callee_guaranteed () -> Int on %0 : $*Something +// CHECK: [[USE_REF:%.*]] = function_ref @$s3Lib3useyySiyXEF : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> Int) -> () +// CHECK: [[RESULT:%.*]] = apply [[USE_REF]]([[MARKED]]) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> Int) -> () + diff --git a/test/SILOptimizer/package-cmo-inlinable.swift b/test/SILOptimizer/package-cmo-inlinable.swift new file mode 100644 index 0000000000000..80fa4bdd930db --- /dev/null +++ b/test/SILOptimizer/package-cmo-inlinable.swift @@ -0,0 +1,202 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-build-swift %t/Lib.swift \ +// RUN: -module-name=Lib -package-name Pkg \ +// RUN: -parse-as-library -emit-module -emit-module-path %t/Lib.swiftmodule -I%t \ +// RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ +// RUN: -O -wmo -enable-library-evolution +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib.sil + +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-silgen %t/main.swift -o %t/MAIN.sil +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O %t/main.swift -o %t/Main-opt.sil + +// RUN: %FileCheck %s --check-prefix=CHECK < %t/Lib.sil +// RUN: %FileCheck %s --check-prefix=CHECK-MAIN-OPT < %t/Main-opt.sil +// RUN: %FileCheck %s --check-prefix=CHECK-MAIN < %t/MAIN.sil + +// REQUIRES: swift_in_compiler + +//--- main.swift + +import Lib + +// CHECK-MAIN-OPT-NOT: function_ref +// CHECK-MAIN-OPT: struct $PubStruct +// CHECK-MAIN-OPT: store {{.*}} to %0 : $*PubStruct +// CHECK-MAIN-OPT: struct $UfiPkgStruct +// CHECK-MAIN-OPT: store {{.*}} to %0 : $*UfiPkgStruct +// CHECK-MAIN-OPT: struct $PkgStruct +// CHECK-MAIN-OPT: store {{.*}} to %0 : $*PkgStruct + +// CHECK-MAIN: sil [serialized] [ossa] @$s4Main14inUsePubStructy3Lib0dE0VSiF : $@convention(thin) (Int) -> @out PubStruct { +@inlinable +public func inUsePubStruct(_ arg: Int) -> PubStruct { + var p = PubStruct(1) + // CHECK-MAIN: function_ref @$s3Lib9PubStructV3pubSivM : $@yield_once @convention(method) (@inout PubStruct) -> @yields @inout Int + p.pub += arg + return p +} + +// CHECK-MAIN: sil [ossa] @$s4Main12usePubStructy3Lib0cD0VSiF : $@convention(thin) (Int) -> @out PubStruct { +public func usePubStruct(_ arg: Int) -> PubStruct { + var p = PubStruct(1) + // CHECK-MAIN: struct_element_addr {{.*}} : $*PubStruct, #PubStruct.pub + p.pub += arg + return p +} + +// CHECK-MAIN: sil [serialized] [ossa] @$s4Main17inUseUfiPkgStructy3Lib0deF0VSiF : $@convention(thin) (Int) -> @out UfiPkgStruct { +@inlinable +package func inUseUfiPkgStruct(_ arg: Int) -> UfiPkgStruct { + var p = UfiPkgStruct(1) + // CHECK-MAIN: function_ref @$s3Lib12UfiPkgStructV03ufiC0SivM : $@yield_once @convention(method) (@inout UfiPkgStruct) -> @yields @inout Int + p.ufiPkg += arg + return p +} + +// CHECK-MAIN: sil package [ossa] @$s4Main15useUfiPkgStructy3Lib0cdE0VSiF : $@convention(thin) (Int) -> @out UfiPkgStruct { +package func useUfiPkgStruct(_ arg: Int) -> UfiPkgStruct { + var p = UfiPkgStruct(1) + // CHECK-MAIN: struct_element_addr {{.*}} : $*UfiPkgStruct, #UfiPkgStruct.ufiPkg + p.ufiPkg += arg + return p +} + +// CHECK-MAIN: sil package [ossa] @$s4Main12usePkgStructy3Lib0cD0VSiF : $@convention(thin) (Int) -> @out PkgStruct { +package func usePkgStruct(_ arg: Int) -> PkgStruct { + var p = PkgStruct(1) + // CHECK-MAIN: struct_element_addr {{.*}} : $*PkgStruct, #PkgStruct.pkg + p.pkg += arg + return p +} + +//--- Lib.swift + +// CHECK: sil package [serialized_for_package] [canonical] @$s3Lib6libPkgyAA0C6StructVSiF : $@convention(thin) (Int) -> @out PkgStruct { + // CHECK: struct $PkgStruct + // CHECK: store {{.*}} to %0 : $*PkgStruct + +// CHECK: sil [serialized_for_package] [canonical] @$s3Lib6libPubyAA0C6StructVSiF : $@convention(thin) (Int) -> @out PubStruct { + // CHECK: struct $PubStruct + // CHECK: store {{.*}} to %0 : $*PubStruct + +// CHECK: sil package [serialized_for_package] [canonical] @$s3Lib9libUfiPkgyAA0cD6StructVSiF : $@convention(thin) (Int) -> @out UfiPkgStruct { + // CHECK: struct $UfiPkgStruct + // CHECK: store {{.*}} to %0 : $*UfiPkgStruct + +/// @inlinable package func inLibUfiPkg(_ arg: Int) -> UfiPkgStruct +// CHECK: sil [serialized] [canonical] @$s3Lib02inA6UfiPkgyAA0cD6StructVSiF : $@convention(thin) (Int) -> @out UfiPkgStruct { + // CHECK: function_ref @$s3Lib12UfiPkgStructVyACSicfC : $@convention(method) (Int, @thin UfiPkgStruct.Type) -> @out UfiPkgStruct + // CHECK: function_ref @$s3Lib12UfiPkgStructV03ufiC0SivM : $@yield_once @convention(method) (@inout UfiPkgStruct) -> @yields @inout Int + +/// @inlinable func inLibUfiHid(_ arg: Int) -> UfiHidStruct +// CHECK: sil [serialized] [canonical] @$s3Lib02inA6UfiHidyAA0cD6StructVSiF : $@convention(thin) (Int) -> @out UfiHidStruct { + // CHECK: function_ref @$s3Lib12UfiHidStructVyACSicfC : $@convention(method) (Int, @thin UfiHidStruct.Type) -> @out UfiHidStruct + // CHECK: function_ref @$s3Lib12UfiHidStructV03ufiC0SivM : $@yield_once @convention(method) (@inout UfiHidStruct) -> @yields @inout Int + +/// @inlinable public func inLibPub(_ arg: Int) -> PubStruct +// CHECK: sil [serialized] [canonical] @$s3Lib02inA3PubyAA0C6StructVSiF : $@convention(thin) (Int) -> @out PubStruct { + // CHECK: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct + // CHECK: function_ref @$s3Lib9PubStructV3pubSivM : $@yield_once @convention(method) (@inout PubStruct) -> @yields @inout Int + +@inlinable +public func inLibPub(_ arg: Int) -> PubStruct { + var p = PubStruct(1) + p.pub += arg + return p +} + +public func libPub(_ arg: Int) -> PubStruct { + var p = PubStruct(1) + p.pub += arg + return p +} + +@inlinable +package func inLibUfiPkg(_ arg: Int) -> UfiPkgStruct { + var p = UfiPkgStruct(1) + p.ufiPkg += arg + return p +} + +package func libUfiPkg(_ arg: Int) -> UfiPkgStruct { + var p = UfiPkgStruct(1) + p.ufiPkg += arg + return p +} + +package func libPkg(_ arg: Int) -> PkgStruct { + var p = PkgStruct(1) + p.pkg += arg + return p +} + +@inlinable +func inLibUfiHid(_ arg: Int) -> UfiHidStruct { + var p = UfiHidStruct(1) + p.ufiHid += arg + return p +} + +func libUfiHid(_ arg: Int) -> UfiHidStruct { + var p = UfiHidStruct(1) + p.ufiHid += arg + return p +} + +public struct PubStruct { + // PubStruct.pub.getter + // sil [serialized_for_package] [canonical] @$s3Lib9PubStructV3pubSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int { + public var pub: Int + public init(_ arg: Int) { + pub = arg + } + public func pubFunc(_ arg: Int) -> Int { + return arg > 0 ? arg : arg + 11 + } +} + +package struct PkgStruct { + // PkgStruct.pkg.modify + // sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructV3pkgSivM : $@yield_once @convention(method) (@inout PkgStruct) -> @yields @inout Int { + package var pkg: Int + package init(_ arg: Int) { + pkg = arg + } + package func pkgFunc(_ arg: Int) -> Int { + return arg > 0 ? arg : 11 + } +} + +@usableFromInline +package struct UfiPkgStruct { + // UfiPkgStruct.ufiPkg.getter + // sil [serialized_for_package] [canonical] @$s3Lib12UfiPkgStructV03ufiC0Sivg : $@convention(method) (@in_guaranteed UfiPkgStruct) -> Int { + @usableFromInline + package var ufiPkg: Int + @usableFromInline + package init(_ arg: Int) { + ufiPkg = arg + } + @usableFromInline + package func ufiPkgFunc(_ arg: Int) -> Int { + return arg > 0 ? arg : 11 + } +} + +@usableFromInline +struct UfiHidStruct { + // UfiHidStruct.ufiHid.setter + // sil [serialized_for_package] [canonical] @$s3Lib12UfiHidStructV03ufiC0Sivs : $@convention(method) (Int, @inout UfiHidStruct) -> () { + @usableFromInline + var ufiHid: Int + @usableFromInline + init(_ arg: Int) { + ufiHid = arg + } + @usableFromInline + func ufiFunc(_ arg: Int) -> Int { + return arg > 0 ? arg : 11 + } +} diff --git a/test/SILOptimizer/package-cmo.swift b/test/SILOptimizer/package-cmo-non-resilient-mode.swift similarity index 91% rename from test/SILOptimizer/package-cmo.swift rename to test/SILOptimizer/package-cmo-non-resilient-mode.swift index c47a179bf45a4..7e5e9b5f1067f 100644 --- a/test/SILOptimizer/package-cmo.swift +++ b/test/SILOptimizer/package-cmo-non-resilient-mode.swift @@ -21,16 +21,11 @@ package func callStaticPkgClosurePointer(_ x: Int) -> Int { return Module.PkgModuleStruct.closurePointer(x) } -// CHECK-LABEL: sil_global public_external [serialized] @$s6Module0A6StructV21publicFunctionPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int = { - // function_ref incrementByThree(_:) -// CHECK: [[REF:%.*]] = function_ref @$s6Module16incrementByThreeyS2iF : $@convention(thin) (Int) -> Int -// CHECK-NEXT: [[INITVAL:%.*]] = thin_to_thick_function [[REF]] : $@convention(thin) (Int) -> Int to $@callee_guaranteed (Int) -> Int -// CHECK-NEXT: } +// static ModuleStruct.publicFunctionPointer +// CHECK-LABEL: sil_global public_external [serialized] @$s6Module0A6StructV21publicFunctionPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int +// static PkgModuleStruct.funcPointer +// CHECK-LABEL: sil_global package_external [serialized] @$s6Module03PkgA6StructV11funcPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int -// CHECK-LABEL: sil_global package_external [serialized] @$s6Module03PkgA6StructV11funcPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int = { -// CHECK: [[REF:%.*]] = function_ref @$s6Module7pkgFuncyS2iF : $@convention(thin) (Int) -> Int -// CHECK-NEXT: [[INITVAL:%.*]] = thin_to_thick_function [[REF]] : $@convention(thin) (Int) -> Int to $@callee_guaranteed (Int) -> Int -// CHECK-NEXT: } // CHECK-LABEL: sil @$s4Main25callPublicFunctionPointeryS2iF : $@convention(thin) (Int) -> Int { // CHECK: global_addr @$s6Module0A6StructV21publicFunctionPointeryS2icvpZ : $*@callee_guaranteed (Int) -> Int @@ -68,7 +63,6 @@ public func usePrivateCVarInModule() -> Int { // CHECK-NOT: function_ref // CHECK-NOT: apply // CHECK: } // end sil function '$s4Main11doIncrementyS2iF' -// CHECK-LABEL: sil public_external @$s6Module16incrementByThreeyS2iF : $@convention(thin) (Int) -> Int { public func doIncrement(_ x: Int) -> Int { return Module.incrementByThree(x) } @@ -77,7 +71,6 @@ public func doIncrement(_ x: Int) -> Int { // CHECK-NOT: function_ref // CHECK-NOT: apply // CHECK: } // end sil function '$s4Main11callPkgFuncyS2iF' -// CHECK-LABEL: sil public_external @$s6Module7pkgFuncyS2iF : $@convention(thin) (Int) -> Int { package func callPkgFunc(_ x: Int) -> Int { return Module.pkgFunc(x) } @@ -123,7 +116,6 @@ public func doIncrementTBDWithCall(_ x: Int) -> Int { // CHECK-LABEL: sil package @$s4Main19callPkgFuncNoCMOTBDyS2iF : $@convention(thin) (Int) -> Int { // CHECK: function_ref @$s9ModuleTBD12pkgFuncNoCMOyS2iF // CHECK: } // end sil function '$s4Main19callPkgFuncNoCMOTBDyS2iF' -// FIXME: should package_external be package? // CHECK-LABEL: sil package_external @$s9ModuleTBD12pkgFuncNoCMOyS2iF : $@convention(thin) (Int) -> Int package func callPkgFuncNoCMOTBD(_ x: Int) -> Int { return ModuleTBD.pkgFuncNoCMO(x) diff --git a/test/SILOptimizer/package-cmo-resilient-mode.swift b/test/SILOptimizer/package-cmo-resilient-mode.swift index b10a06191fc44..8c013576e145b 100644 --- a/test/SILOptimizer/package-cmo-resilient-mode.swift +++ b/test/SILOptimizer/package-cmo-resilient-mode.swift @@ -5,13 +5,16 @@ // RUN: -module-name=Lib -package-name Pkg \ // RUN: -parse-as-library -emit-module -emit-module-path %t/Lib.swiftmodule -I%t \ // RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ -// RUN: -O -wmo +// RUN: -O -wmo -enable-library-evolution -// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-non-res.sil -// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NONRES < %t/Lib-non-res.sil +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-RES < %t/Lib-res.sil -// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O %t/main.swift -o %t/Main-non-res.sil -// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-NONRES < %t/Main-non-res.sil +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O %t/main.swift -o %t/Main-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-RES < %t/Main-res.sil + +// RUN: llvm-bcanalyzer --dump %t/Lib.swiftmodule | %FileCheck %s --check-prefix=CHECK-BC +// CHECK-BC: SERIALIZE_PACKAGE_ENABLED // RUN: rm -rf %t/Lib.swiftmodule @@ -19,16 +22,13 @@ // RUN: -module-name=Lib -package-name Pkg \ // RUN: -parse-as-library -emit-module -emit-module-path %t/Lib.swiftmodule -I%t \ // RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ -// RUN: -O -wmo -enable-library-evolution - -// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-res.sil -// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-RES < %t/Lib-res.sil +// RUN: -O -wmo -// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O %t/main.swift -o %t/Main-res.sil -// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-RES < %t/Main-res.sil +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-non-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NONRES < %t/Lib-non-res.sil -// RUN: llvm-bcanalyzer --dump %t/Lib.swiftmodule | %FileCheck %s --check-prefix=CHECK-BC -// CHECK-BC: SERIALIZE_PACKAGE_ENABLED +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O %t/main.swift -o %t/Main-non-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-NONRES < %t/Main-non-res.sil // REQUIRES: swift_in_compiler @@ -110,22 +110,22 @@ import Lib // CHECK-MAIN-COMMON-NEXT: [[FNL_PKG_LOAD:%.*]] = load [[FNL_PKG_ACCESS]] : $*Int // CHECK-MAIN-COMMON-NEXT: store [[FNL_PKG_LOAD]] to {{.*}} : $*Int -// CHECK-MAIN-RES-DAG: sil public_external [serialized_for_package] @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { +// CHECK-MAIN-RES-DAG: sil public_external @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { // CHECK-MAIN-NONRES-DAG: sil public_external @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { -// CHECK-MAIN-RES-DAG: sil package_external [serialized_for_package] @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { +// CHECK-MAIN-RES-DAG: sil package_external @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { // CHECK-MAIN-NONRES-DAG: sil package_external @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { -// CHECK-MAIN-RES-DAG: sil public_external [serialized_for_package] @$s3Lib13FinalPubKlassCyACSicfC : $@convention(method) (Int, @thick FinalPubKlass.Type) -> @owned FinalPubKlass { +// CHECK-MAIN-RES-DAG: sil public_external @$s3Lib13FinalPubKlassCyACSicfC : $@convention(method) (Int, @thick FinalPubKlass.Type) -> @owned FinalPubKlass { // CHECK-MAIN-NONRES-DAG: sil public_external @$s3Lib13FinalPubKlassCyACSicfC : $@convention(method) (Int, @thick FinalPubKlass.Type) -> @owned FinalPubKlass { -// CHECK-MAIN-RES-DAG: sil public_external [serialized_for_package] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { +// CHECK-MAIN-RES-DAG: sil public_external @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { // CHECK-MAIN-NONRES-DAG: sil public_external [transparent] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { -// CHECK-MAIN-RES-DAG: sil package_external [serialized_for_package] @$s3Lib13FinalPkgKlassCyACSicfC : $@convention(method) (Int, @thick FinalPkgKlass.Type) -> @owned FinalPkgKlass { +// CHECK-MAIN-RES-DAG: sil package_external @$s3Lib13FinalPkgKlassCyACSicfC : $@convention(method) (Int, @thick FinalPkgKlass.Type) -> @owned FinalPkgKlass { // CHECK-MAIN-NONRES-DAG: sil package_external @$s3Lib13FinalPkgKlassCyACSicfC : $@convention(method) (Int, @thick FinalPkgKlass.Type) -> @owned FinalPkgKlass { -// CHECK-MAIN-RES-DAG: sil package_external [serialized_for_package] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { +// CHECK-MAIN-RES-DAG: sil package_external @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { // CHECK-MAIN-NONRES-DAG: sil package_external [transparent] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { // CHECK-MAIN-COMMON: sil_vtable PubKlass { @@ -174,48 +174,129 @@ public func mainPub() { print(PubStruct(1)) } -@inlinable -public func mainPubInlinable() { - print(PubStruct(2)) -} +//--- Lib.swift -public func mainPubArgRet(_ arg: PubKlass) -> PubStruct { - return PubStruct(arg.data) -} -@inlinable -public func mainPubArgRetInlinable(_ arg: PubKlass) -> PubStruct { - return PubStruct(arg.data) -} +// pcmo TODO: check for Fr public fields serialized kind +// and add silgen of pkg static pts. -//--- Lib.swift +// FIXME: serialize closure pointers? +// static PkgStruct.pkgStaticSimpleFuncPtr +// CHECK-RES-DAG: sil_global package [serialized_for_package] @$s3Lib9PkgStructV22pkgStaticSimpleFuncPtryS2icvpZ +// CHECK-NONRES-DAG: sil_global package [serialized] @$s3Lib9PkgStructV22pkgStaticSimpleFuncPtryS2icvpZ + +// static FrPubStruct.pubStaticClosurePtr +// CHECK-COMMON-DAG: sil_global @$s3Lib11FrPubStructV19pubStaticClosurePtrySiAA0cD0VcvpZ + +// static PkgStruct.pkgStaticClosurePtr +// CHECK-COMMON-DAG: sil_global package @$s3Lib9PkgStructV19pkgStaticClosurePtrySiACcvpZ + +// static PkgStruct.pkgStaticSimpleClosurePtr +// CHECK-COMMON-DAG: sil_global package @$s3Lib9PkgStructV25pkgStaticSimpleClosurePtryS2icvpZ + +// static PkgStruct.pkgStaticFuncPtr +// CHECK-RES-DAG: sil_global package [serialized_for_package] @$s3Lib9PkgStructV16pkgStaticFuncPtrySiACcvpZ +// CHECK-NONRES-DAG: sil_global package [serialized] @$s3Lib9PkgStructV16pkgStaticFuncPtrySiACcvpZ + +// static PubStruct.pubStaticClosurePtr +// CHECK-COMMON-DAG: sil_global @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvpZ + +// static FrPubStruct.pubStaticSimpleFuncPtr +// CHECK-RES-DAG: sil_global [serialized_for_package] @$s3Lib11FrPubStructV22pubStaticSimpleFuncPtryS2icvpZ +// CHECK-NONRES-DAG: sil_global [serialized] @$s3Lib11FrPubStructV22pubStaticSimpleFuncPtryS2icvpZ + +// static FrPubStruct.pubStaticFuncPtr +// CHECK-RES-DAG: sil_global [serialized_for_package] @$s3Lib11FrPubStructV16pubStaticFuncPtrySiAA0cD0VcvpZ +// CHECK-NONRES-DAG: sil_global [serialized] @$s3Lib11FrPubStructV16pubStaticFuncPtrySiAA0cD0VcvpZ + +// static PubStruct.pubStaticSimpleClosurePtr +// CHECK-COMMON-DAG: sil_global @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvpZ + +// static PubStruct.pubStaticSimpleFuncPtr +// CHECK-RES-DAG: sil_global [serialized_for_package] @$s3Lib9PubStructV22pubStaticSimpleFuncPtryS2icvpZ +// CHECK-NONRES-DAG: sil_global [serialized] @$s3Lib9PubStructV22pubStaticSimpleFuncPtryS2icvpZ + +// static PubStruct.pubStaticFuncPtr +// CHECK-RES-DAG: sil_global [serialized_for_package] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvpZ +// CHECK-NONRES-DAG: sil_global [serialized] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvpZ + +// static FrPubStruct.pubStaticSimpleClosurePtr +// CHECK-COMMON-DAG: sil_global @$s3Lib11FrPubStructV25pubStaticSimpleClosurePtryS2icvpZ public struct PubStruct { // PubStruct.foovar.getter - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (PubStruct) -> Int // CHECK-RES-DAG: [[PUB_GET:%.*]] = struct_element_addr {{.*}} : $*PubStruct, #PubStruct.fooVar // CHECK-RES-DAG: load [[PUB_GET]] : $*Int // CHECK-NONRES-DAG = struct_extract {{.*}} : $PubStruct, #PubStruct.fooVar // PubStruct.foovar.setter - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () { - /// NOTE: `struct $PubStruct` in [serialized] function is legal only if package serialization is enabled. + /// NOTE: loadable types (e.g. load/store `struct $PubStruct`) can be only allowed + /// in a serialized function with `[serialized_for_package]` (if Package CMO is + /// enabled in a resiliently built module), otherwise illegal. // CHECK-COMMON-DAG: [[PUB_SET:%.*]] = struct $PubStruct // CHECK-RES-DAG: store [[PUB_SET]] to {{.*}} : $*PubStruct // CHECK-NONRES-DAG: store [[PUB_SET]] to [trivial] {{.*}} : $*PubStruct // PubStruct.foovar.modify - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivM : $@yield_once @convention(method) (@inout PubStruct) -> @yields @inout Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV6fooVarSivM : $@yield_once @convention(method) (@inout PubStruct) -> @yields @inout Int { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV6fooVarSivM : $@yield_once @convention(method) (@inout PubStruct) -> @yields @inout Int { // CHECK-COMMON-DAG: [[PUB_MODIFY:%.*]] = struct_element_addr {{.*}} : $*PubStruct, #PubStruct.fooVar // CHECK-COMMON-DAG: yield [[PUB_MODIFY]] public var fooVar: Int + public static var pubStaticVar: String { "StaticPubVar" } + + // static PubStruct.pubStaticSimpleFuncPtr.modify + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV22pubStaticSimpleFuncPtryS2icvMZ : $@yield_once @convention(method) (@thin PubStruct.Type) -> @yields @inout @callee_guaranteed (Int) -> Int { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV22pubStaticSimpleFuncPtryS2icvMZ : $@yield_once @convention(method) (@thin PubStruct.Type) -> @yields @inout @callee_guaranteed (Int) -> Int { + public static var pubStaticSimpleFuncPtr: (Int) -> (Int) = runPubSimple + + // static PubStruct.pubStaticFuncPtr.modify + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvsZ : $@convention(method) (@owned @callee_guaranteed (@in_guaranteed PubStruct) -> Int, @thin PubStruct.Type) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvsZ : $@convention(method) (@owned @callee_guaranteed (PubStruct) -> Int, @thin PubStruct.Type) -> () { + // CHECK-RES-DAG: global_addr @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvpZ : $*@callee_guaranteed (@in_guaranteed PubStruct) -> Int + // CHECK-NONRES-DAG: function_ref @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer + + // PubStruct.pubStaticFuncPtr.unsafeMutableAddressor + // CHECK-RES-DAG: sil [serialized_for_package] [global_init] [canonical] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer + // CHECK-RES-DAG: global_addr @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvpZ : $*@callee_guaranteed (@in_guaranteed PubStruct) -> Int + // CHECK-NONRES-DAG: sil [serialized] [global_init] [canonical] @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer + // CHECK-NONRES-DAG: global_addr @$s3Lib9PubStructV16pubStaticFuncPtrySiACcvpZ : $*@callee_guaranteed (PubStruct) -> Int + public static var pubStaticFuncPtr: (PubStruct) -> (Int) = runPub + + // static PubStruct.pubStaticSimpleClosurePtr.setter + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvsZ : $@convention(method) (@owned @callee_guaranteed (Int) -> Int, @thin PubStruct.Type) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvsZ : $@convention(method) (@owned @callee_guaranteed (Int) -> Int, @thin PubStruct.Type) -> () { + // CHECK-RES-DAG: global_addr @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvpZ + // CHECK-NONRES-DAG: function_ref @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvau : $@convention(thin) () -> Builtin.RawPointer + + // PubStruct.pubStaticSimpleClosurePtr.unsafeMutableAddressor + // CHECK-RES-DAG: sil [serialized_for_package] [global_init] [canonical] @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvau : $@convention(thin) () -> Builtin.RawPointer { + // CHECK-NONRES-DAG: sil [serialized] [global_init] [canonical] @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvau : $@convention(thin) () -> Builtin.RawPointer { + // CHECK-COMMON-DAG: global_addr @$s3Lib9PubStructV25pubStaticSimpleClosurePtryS2icvpZ : $*@callee_guaranteed (Int) -> Int + public static var pubStaticSimpleClosurePtr: (Int) -> (Int) = { return $0 } + + // static PubStruct.pubStaticClosurePtr.setter + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvsZ : $@convention(method) (@owned @callee_guaranteed (@in_guaranteed PubStruct) -> Int, @thin PubStruct.Type) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvsZ : $@convention(method) (@owned @callee_guaranteed (PubStruct) -> Int, @thin PubStruct.Type) -> () { + // CHECK-RES-DAG: global_addr @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvpZ + // CHECK-NONRES-DAG: function_ref @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer + + // PubStruct.pubStaticClosurePtr.unsafeMutableAddressor + // CHECK-RES-DAG: sil [serialized_for_package] [global_init] [canonical] @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer { + // CHECK-RES-DAG: global_addr @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvpZ : $*@callee_guaranteed (@in_guaranteed PubStruct) -> Int + // CHECK-NONRES-DAG: sil [serialized] [global_init] [canonical] @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvau : $@convention(thin) () -> Builtin.RawPointer { + // CHECK-NONRES-DAG: global_addr @$s3Lib9PubStructV19pubStaticClosurePtrySiACcvpZ : $*@callee_guaranteed (PubStruct) -> Int + public static var pubStaticClosurePtr: (PubStruct) -> (Int) = { return $0.fooVar } + public static func pubStaticFunc() -> PubKlass { return PubKlass() } + public init(_ arg: Int) { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct { // CHECK-COMMON-DAG: [[PUB_INIT:%.*]] = struct $PubStruct // CHECK-RES-DAG: store [[PUB_INIT]] to {{.*}} : $*PubStruct @@ -223,93 +304,104 @@ public struct PubStruct { fooVar = arg } public func f() -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib9PubStructV1fSiyF : $@convention(method) (@in_guaranteed PubStruct) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib9PubStructV1fSiyF : $@convention(method) (@in_guaranteed PubStruct) -> Int { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib9PubStructV1fSiyF : $@convention(method) (PubStruct) -> Int { return fooVar > 7 ? fooVar : fooVar + 11 } } +public func runPubSimple(_ arg: Int) -> Int { + return arg + 3 +} + public func runPub(_ arg: PubStruct) -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib6runPubySiAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib6runPubySiAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> Int { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib6runPubySiAA0C6StructVF : $@convention(thin) (PubStruct) -> Int { return arg.f() > arg.fooVar ? arg.f() : arg.fooVar } -@inlinable -public func runPubInlinable(_ arg: Int) -> PubStruct { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib15runPubInlinableyAA0C6StructVSiF : $@convention(thin) (Int) -> @out PubStruct { - // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib15runPubInlinableyAA0C6StructVSiF : $@convention(thin) (Int) -> PubStruct { - // CHECK-RES-DAG: alloc_stack {{.*}} [var_decl] $PubStruct - // CHECK-RES-DAG: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct - // CHECK-NONRES-DAG: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct - var x = PubStruct(1) - x.fooVar = arg > 11 ? arg + 13 : arg + 17 - return x -} - @frozen public struct FrPubStruct { // FrPubStruct.fooVar.getter - // CHECK-RES-DAG: sil [transparent] [serialized] [serialized_for_package] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivg : $@convention(method) (FrPubStruct) -> Int { + // CHECK-RES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivg : $@convention(method) (FrPubStruct) -> Int { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivg : $@convention(method) (FrPubStruct) -> Int { // CHECK-COMMON-DAG: [[FR_GET:%.*]] = struct_extract {{.*}} : $FrPubStruct, #FrPubStruct.fooVar // CHECK-COMMON-DAG: return [[FR_GET]] : $Int // FrPubStruct.fooVar.setter - // CHECK-RES-DAG: sil [transparent] [serialized] [serialized_for_package] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivs : $@convention(method) (Int, @inout FrPubStruct) -> () { + // CHECK-RES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivs : $@convention(method) (Int, @inout FrPubStruct) -> () { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivs : $@convention(method) (Int, @inout FrPubStruct) -> () { // CHECK-COMMON-DAG: [[FR_SET:%.*]] = struct $FrPubStruct // CHECK-COMMON-DAG: store [[FR_SET]] to [trivial] {{.*}} : $*FrPubStruct // FrPubStruct.fooVar.modify - // CHECK-RES-DAG: sil [transparent] [serialized] [serialized_for_package] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivM : $@yield_once @convention(method) (@inout FrPubStruct) -> @yields @inout Int { + // CHECK-RES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivM : $@yield_once @convention(method) (@inout FrPubStruct) -> @yields @inout Int { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivM : $@yield_once @convention(method) (@inout FrPubStruct) -> @yields @inout Int { // CHECK-COMMON-DAG: [[FIELD:%.*]] = struct_element_addr {{.*}} : $*FrPubStruct, #FrPubStruct.fooVar // CHECK-COMMON-DAG: yield [[FIELD]] public var fooVar: Int + public static var pubStaticVar: String { "FrStaticPubVar" } + public static var pubStaticSimpleFuncPtr: (Int) -> (Int) = runPubSimple + public static var pubStaticFuncPtr: (PubStruct) -> (Int) = runPub + // static FrPubStruct.pubStaticSimpleClosurePtr.setter + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib11FrPubStructV25pubStaticSimpleClosurePtryS2icvsZ : $@convention(method) (@owned @callee_guaranteed (Int) -> Int, @thin FrPubStruct.Type) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV25pubStaticSimpleClosurePtryS2icvsZ : $@convention(method) (@owned @callee_guaranteed (Int) -> Int, @thin FrPubStruct.Type) -> () { + public static var pubStaticSimpleClosurePtr: (Int) -> (Int) = { return $0 } + + // static FrPubStruct.pubStaticClosurePtr.setter + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib11FrPubStructV19pubStaticClosurePtrySiAA0cD0VcvsZ : $@convention(method) (@owned @callee_guaranteed (@in_guaranteed PubStruct) -> Int, @thin FrPubStruct.Type) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV19pubStaticClosurePtrySiAA0cD0VcvsZ : $@convention(method) (@owned @callee_guaranteed (PubStruct) -> Int, @thin FrPubStruct.Type) -> () { + public static var pubStaticClosurePtr: (PubStruct) -> (Int) = { return $0.fooVar } + public init(_ arg: Int) { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct { // CHECK-COMMON-DAG: [[FR_MODIFY:%.*]] = struct $FrPubStruct // CHECK-COMMON-DAG: return [[FR_MODIFY]] : $FrPubStruct fooVar = arg } public func f() -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib11FrPubStructV1fSiyF : $@convention(method) (FrPubStruct) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib11FrPubStructV1fSiyF : $@convention(method) (FrPubStruct) -> Int { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib11FrPubStructV1fSiyF : $@convention(method) (FrPubStruct) -> Int { return fooVar > 13 ? fooVar : fooVar + 17 } } public func runFrPub(_ arg: FrPubStruct) -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8runFrPubySiAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8runFrPubySiAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> Int { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8runFrPubySiAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> Int { return arg.f() > arg.fooVar ? arg.f() : arg.fooVar } package struct PkgStruct { // PkgStruct.fooVar.getter - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (PkgStruct) -> Int { // CHECK-COMMON-DAG: [[PKG_GET:%.*]] = struct_element_addr {{.*}} : $*PkgStruct, #PkgStruct.fooVar // CHECK-RES-DAG: load [[PKG_GET]] : $*Int // CHECK-NONRES-DAG = struct_extract {{.*}} : $PkgStruct, #PkgStruct.fooVar // PkgStruct.fooVar.setter - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () { // CHECK-COMMON-DAG: [[PKG_SET:%.*]] = struct $PkgStruct // CHECK-RES-DAG: store [[PKG_SET]] to {{.*}} : $*PkgStruct // CHECK-NONRES-DAG: store [[PKG_SET]] to [trivial] {{.*}} : $*PkgStruct // PkgStruct.fooVar.modify - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivM : $@yield_once @convention(method) (@inout PkgStruct) -> @yields @inout Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructV6fooVarSivM : $@yield_once @convention(method) (@inout PkgStruct) -> @yields @inout Int { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib9PkgStructV6fooVarSivM : $@yield_once @convention(method) (@inout PkgStruct) -> @yields @inout Int { package var fooVar: Int + package static var pkgStaticVar: String { "StaticPkgVar" } + package static var pkgStaticSimpleFuncPtr: (Int) -> (Int) = runPubSimple + package static var pkgStaticFuncPtr: (PkgStruct) -> (Int) = runPkg + package static var pkgStaticSimpleClosurePtr: (Int) -> (Int) = { return $0 } + package static var pkgStaticClosurePtr: (PkgStruct) -> (Int) = { return $0.fooVar } + package init(_ arg: Int) { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> @out PkgStruct { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> @out PkgStruct { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> PkgStruct { // CHECK-COMMON-DAG: [[PKG_INIT:%.*]] = struct $PkgStruct // CHECK-RES-DAG: store [[PKG_INIT]] to {{.*}} : $*PkgStruct @@ -317,14 +409,14 @@ package struct PkgStruct { fooVar = arg } package func f() -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib9PkgStructV1fSiyF : $@convention(method) (@in_guaranteed PkgStruct) -> Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib9PkgStructV1fSiyF : $@convention(method) (@in_guaranteed PkgStruct) -> Int { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib9PkgStructV1fSiyF : $@convention(method) (PkgStruct) -> Int { return fooVar > 19 ? fooVar : fooVar + 23 } } package func runPkg(_ arg: PkgStruct) -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib6runPkgySiAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib6runPkgySiAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> Int { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib6runPkgySiAA0C6StructVF : $@convention(thin) (PkgStruct) -> Int { return arg.f() > arg.fooVar ? arg.f() : arg.fooVar } @@ -335,36 +427,35 @@ public protocol PubProto { } public class PubKlass: PubProto { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PubProto) (@in_guaranteed PubKlass) -> Int { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PubProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PubProto) (Int, @inout PubKlass) -> () { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PubProto) (@in_guaranteed PubKlass) -> Int { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PubProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PubProto) (Int, @inout PubKlass) -> () { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PubProto) (@in_guaranteed PubKlass) -> Int { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PubProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PubProto) (Int, @inout PubKlass) -> () { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassC4dataSivg : $@convention(method) (@guaranteed PubKlass) -> Int + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassC4dataSivg : $@convention(method) (@guaranteed PubKlass) -> Int // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib8PubKlassC4dataSivg : $@convention(method) (@guaranteed PubKlass) -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { public var data: Int public init(_ arg: Int = 1) { - // FIXME: default argument 0 of PubKlass.init(_:) gets non_abi so is not considered - // for package serialization, but should it? - // sil non_abi [serialized] [canonical] @$s3Lib8PubKlassCyACSicfcfA_ : $@convention(thin) () -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassCyACSicfc : $@convention(method) (Int, @owned PubKlass) -> @owned PubKlass { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [exact_self_class] [canonical] @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassCfD : $@convention(method) (@owned PubKlass) -> () { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassCfd : $@convention(method) (@guaranteed PubKlass) -> @owned Builtin.NativeObject { // default argument 0 of PubKlass.init(_:) + // CHECK-RES-DAG: sil non_abi [serialized] [canonical] @$s3Lib8PubKlassCyACSicfcfA_ : $@convention(thin) () -> Int { // CHECK-NONRES-DAG: sil non_abi [serialized] [canonical] @$s3Lib8PubKlassCyACSicfcfA_ : $@convention(thin) () -> Int { + + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassCyACSicfc : $@convention(method) (Int, @owned PubKlass) -> @owned PubKlass { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCyACSicfc : $@convention(method) (Int, @owned PubKlass) -> @owned PubKlass { + // CHECK-RES-DAG: sil [serialized] [exact_self_class] [canonical] @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { // CHECK-NONRES-DAG: sil [serialized] [exact_self_class] [canonical] @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassCfD : $@convention(method) (@owned PubKlass) -> () { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCfD : $@convention(method) (@owned PubKlass) -> () { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassCfd : $@convention(method) (@guaranteed PubKlass) -> @owned Builtin.NativeObject { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCfd : $@convention(method) (@guaranteed PubKlass) -> @owned Builtin.NativeObject { self.data = arg } public func pubfunc(_ arg: Int) -> Int { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW : $@convention(witness_method: PubProto) (Int, @in_guaranteed PubKlass) -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib8PubKlassC7pubfuncyS2iF : $@convention(method) (Int, @guaranteed PubKlass) -> Int { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW : $@convention(witness_method: PubProto) (Int, @in_guaranteed PubKlass) -> Int { + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib8PubKlassC7pubfuncyS2iF : $@convention(method) (Int, @guaranteed PubKlass) -> Int { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW : $@convention(witness_method: PubProto) (Int, @in_guaranteed PubKlass) -> Int { // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassC7pubfuncyS2iF : $@convention(method) (Int, @guaranteed PubKlass) -> Int { return data + arg @@ -372,7 +463,7 @@ public class PubKlass: PubProto { } public func runPubKlass(_ arg: PubKlass) -> Int { - // CHECK-RES-DAG: sil [serialized] [serialized_for_package] [canonical] @$s3Lib11runPubKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> Int + // CHECK-RES-DAG: sil [serialized_for_package] [canonical] @$s3Lib11runPubKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> Int // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib11runPubKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> Int { arg.data += 29 return arg.pubfunc(31) @@ -380,6 +471,8 @@ public func runPubKlass(_ arg: PubKlass) -> Int { final public class FinalPubKlass { public var data = 1 + // FinalPubKlass.__allocating_init(_:) + // CHECK-RES-DAG: sil [serialized] [exact_self_class] [canonical] @$s3Lib13FinalPubKlassCyACSicfC : $@convention(method) (Int, @thick FinalPubKlass.Type) -> @owned FinalPubKlass { public init(_ arg: Int) { data = arg } @@ -394,38 +487,40 @@ package protocol PkgProto { } package class PkgKlass: PkgProto { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PkgProto) (@in_guaranteed PkgKlass) -> Int { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PkgProto) (Int, @inout PkgKlass) -> () { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PkgProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PkgProto) (@in_guaranteed PkgKlass) -> Int { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PkgProto) (Int, @inout PkgKlass) -> () { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PkgProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PkgProto) (@in_guaranteed PkgKlass) -> Int { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PkgProto) (Int, @inout PkgKlass) -> () { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PkgProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivM : $@yield_once @convention(method) (@guaranteed PkgKlass) -> @yields @inout Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivM : $@yield_once @convention(method) (@guaranteed PkgKlass) -> @yields @inout Int { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivM : $@yield_once @convention(method) (@guaranteed PkgKlass) -> @yields @inout Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivg : $@convention(method) (@guaranteed PkgKlass) -> Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivg : $@convention(method) (@guaranteed PkgKlass) -> Int { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivg : $@convention(method) (@guaranteed PkgKlass) -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { package var data: Int package init(_ arg: Int = 1) { - // FIXME: package -> package_non_abi for default argument 0 of PkgKlass.init(_:) - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassCyACSicfcfA_ : $@convention(thin) () -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassCyACSicfc : $@convention(method) (Int, @owned PkgKlass) -> @owned PkgKlass { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [exact_self_class] [canonical] @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassCfd : $@convention(method) (@guaranteed PkgKlass) -> @owned Builtin.NativeObject { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassCfD : $@convention(method) (@owned PkgKlass) -> () + // default argument 0 of PkgKlass.init(_:) + // FIXME: package -> package_non_abi here? Also should this be [serialized] instead? + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassCyACSicfcfA_ : $@convention(thin) () -> Int { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCyACSicfcfA_ : $@convention(thin) () -> Int { + + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassCyACSicfc : $@convention(method) (Int, @owned PkgKlass) -> @owned PkgKlass { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCyACSicfc : $@convention(method) (Int, @owned PkgKlass) -> @owned PkgKlass { + // CHECK-RES-DAG: sil package [serialized_for_package] [exact_self_class] [canonical] @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { // CHECK-NONRES-DAG: sil package [serialized] [exact_self_class] [canonical] @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassCfd : $@convention(method) (@guaranteed PkgKlass) -> @owned Builtin.NativeObject { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCfd : $@convention(method) (@guaranteed PkgKlass) -> @owned Builtin.NativeObject { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassCfD : $@convention(method) (@owned PkgKlass) -> () // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCfD : $@convention(method) (@owned PkgKlass) -> () self.data = arg } package func pkgfunc(_ arg: Int) -> Int { - // CHECK-RES-DAG: sil shared [transparent] [serialized] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW : $@convention(witness_method: PkgProto) (Int, @in_guaranteed PkgKlass) -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib8PkgKlassC7pkgfuncyS2iF : $@convention(method) (Int, @guaranteed PkgKlass) -> Int { + // CHECK-RES-DAG: sil shared [transparent] [serialized_for_package] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW : $@convention(witness_method: PkgProto) (Int, @in_guaranteed PkgKlass) -> Int { + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib8PkgKlassC7pkgfuncyS2iF : $@convention(method) (Int, @guaranteed PkgKlass) -> Int { // CHECK-NONRES-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW : $@convention(witness_method: PkgProto) (Int, @in_guaranteed PkgKlass) -> Int { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassC7pkgfuncyS2iF : $@convention(method) (Int, @guaranteed PkgKlass) -> Int { return data + arg @@ -433,7 +528,7 @@ package class PkgKlass: PkgProto { } package func runPkgKlass(_ arg: PkgKlass) -> Int { - // CHECK-RES-DAG: sil package [serialized] [serialized_for_package] [canonical] @$s3Lib11runPkgKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> Int + // CHECK-RES-DAG: sil package [serialized_for_package] [canonical] @$s3Lib11runPkgKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> Int // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib11runPkgKlassySiAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> Int { arg.data += 37 return arg.pkgfunc(41) @@ -450,7 +545,8 @@ final package class FinalPkgKlass { } } -// CHECK-COMMON-LABEL: sil_vtable [serialized] PubKlass { +// CHECK-RES-LABEL: sil_vtable [serialized_for_package] PubKlass { +// CHECK-NONRES-LABEL: sil_vtable [serialized] PubKlass { // CHECK-COMMON-NEXT: #PubKlass.data!getter: (PubKlass) -> () -> Int : @$s3Lib8PubKlassC4dataSivg // CHECK-COMMON-NEXT: #PubKlass.data!setter: (PubKlass) -> (Int) -> () : @$s3Lib8PubKlassC4dataSivs // CHECK-COMMON-NEXT: #PubKlass.data!modify: (PubKlass) -> () -> () : @$s3Lib8PubKlassC4dataSivM @@ -458,11 +554,13 @@ final package class FinalPkgKlass { // CHECK-COMMON-NEXT: #PubKlass.pubfunc: (PubKlass) -> (Int) -> Int : @$s3Lib8PubKlassC7pubfuncyS2iF // CHECK-COMMON-NEXT: #PubKlass.deinit!deallocator: @$s3Lib8PubKlassCfD -// CHECK-COMMON-LABEL: sil_vtable [serialized] FinalPubKlass { +// CHECK-RES-LABEL: sil_vtable [serialized_for_package] FinalPubKlass { +// CHECK-NONRES-LABEL: sil_vtable [serialized] FinalPubKlass { // CHECK-COMMON-NEXT: #FinalPubKlass.init!allocator: (FinalPubKlass.Type) -> (Int) -> FinalPubKlass : @$s3Lib13FinalPubKlassCyACSicfC // CHECK-COMMON-NEXT: #FinalPubKlass.deinit!deallocator: @$s3Lib13FinalPubKlassCfD -// CHECK-COMMON-LABEL: sil_vtable [serialized] PkgKlass { +// CHECK-RES-LABEL: sil_vtable [serialized_for_package] PkgKlass { +// CHECK-NONRES-LABEL: sil_vtable [serialized] PkgKlass { // CHECK-COMMON-NEXT: #PkgKlass.data!getter: (PkgKlass) -> () -> Int : @$s3Lib8PkgKlassC4dataSivg // CHECK-COMMON-NEXT: #PkgKlass.data!setter: (PkgKlass) -> (Int) -> () : @$s3Lib8PkgKlassC4dataSivs // CHECK-COMMON-NEXT: #PkgKlass.data!modify: (PkgKlass) -> () -> () : @$s3Lib8PkgKlassC4dataSivM @@ -470,37 +568,21 @@ final package class FinalPkgKlass { // CHECK-COMMON-NEXT: #PkgKlass.pkgfunc: (PkgKlass) -> (Int) -> Int : @$s3Lib8PkgKlassC7pkgfuncyS2iF // CHECK-COMMON-NEXT: #PkgKlass.deinit!deallocator: @$s3Lib8PkgKlassCfD -// CHECK-COMMON-LABEL: sil_vtable [serialized] FinalPkgKlass { +// CHECK-RES-LABEL: sil_vtable [serialized_for_package] FinalPkgKlass { +// CHECK-NONRES-LABEL: sil_vtable [serialized] FinalPkgKlass { // CHECK-COMMON-NEXT: #FinalPkgKlass.init!allocator: (FinalPkgKlass.Type) -> (Int) -> FinalPkgKlass : @$s3Lib13FinalPkgKlassCyACSicfC // CHECK-COMMON-NEXT: #FinalPkgKlass.deinit!deallocator: @$s3Lib13FinalPkgKlassCfD -// CHECK-COMMON-LABEL: sil_witness_table [serialized] PubKlass: PubProto module Lib { +// CHECK-RES-LABEL: sil_witness_table [serialized_for_package] PubKlass: PubProto module Lib { +// CHECK-NONRES-LABEL: sil_witness_table [serialized] PubKlass: PubProto module Lib { // CHECK-COMMON-NEXT: method #PubProto.data!getter: (Self) -> () -> Int : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW // CHECK-COMMON-NEXT: method #PubProto.data!setter: (inout Self) -> (Int) -> () : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW // CHECK-COMMON-NEXT: method #PubProto.data!modify: (inout Self) -> () -> () : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW // CHECK-COMMON-NEXT: method #PubProto.pubfunc: (Self) -> (Int) -> Int : @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW -// CHECK-COMMON-LABEL: sil_witness_table package [serialized] PkgKlass: PkgProto module Lib { +// CHECK-RES-LABEL: sil_witness_table package [serialized_for_package] PkgKlass: PkgProto module Lib { +// CHECK-NONRES-LABEL: sil_witness_table package [serialized] PkgKlass: PkgProto module Lib { // CHECK-COMMON-NEXT: method #PkgProto.data!getter: (Self) -> () -> Int : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW // CHECK-COMMON-NEXT: method #PkgProto.data!setter: (inout Self) -> (Int) -> () : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW // CHECK-COMMON-NEXT: method #PkgProto.data!modify: (inout Self) -> () -> () : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW // CHECK-COMMON-NEXT: method #PkgProto.pkgfunc: (Self) -> (Int) -> Int : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW - -public struct Something { - public init() {} - - public func f() -> Int { - return 7 - } -} - -@usableFromInline -func use(_ c: () -> Int) { } - -// Don't crash on this example -@inlinable -public func reproduce(_ e: Something) { - use { - return e.f() - } -} diff --git a/test/SILOptimizer/package-cmo-serialize-tables.swift b/test/SILOptimizer/package-cmo-serialize-tables.swift index 1f0e72a1fa9c1..3fc12110fb9cc 100644 --- a/test/SILOptimizer/package-cmo-serialize-tables.swift +++ b/test/SILOptimizer/package-cmo-serialize-tables.swift @@ -1,3 +1,5 @@ +/// This tests serializing v-table and witness-table in non-resilient mode Package-CMO. +/// // RUN: %empty-directory(%t) // RUN: split-file %s %t