diff --git a/include/swift/SIL/SILBridgingImpl.h b/include/swift/SIL/SILBridgingImpl.h index 06b4f70b38f..3537eda4021 100644 --- a/include/swift/SIL/SILBridgingImpl.h +++ b/include/swift/SIL/SILBridgingImpl.h @@ -718,7 +718,7 @@ bool BridgedFunction::isSerialized() const { } bool BridgedFunction::hasValidLinkageForFragileRef() const { - return getFunction()->hasValidLinkageForFragileRef(); + return getFunction()->hasValidLinkageForFragileRef(swift::SerializedKind_t::IsSerialized); } bool BridgedFunction::needsStackProtection() const { diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index ab1688ff852..dfc94cb42ce 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -874,10 +874,8 @@ public: void setLinkage(SILLinkage linkage) { Linkage = unsigned(linkage); } /// Checks if this (callee) function body can be inlined into the caller -/// by comparing their SerializedKind_t values. +/// 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`, @@ -894,21 +892,13 @@ public: /// ``` /// /// \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; + bool canBeInlinedIntoCaller(SerializedKind_t callerSerializedKind) const; /// Returns true if this function can be referenced from a fragile function /// body. /// \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; + bool hasValidLinkageForFragileRef(SerializedKind_t callerSerializedKind) 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 @@ -1165,11 +1155,9 @@ public: bool isSerialized() const { return SerializedKind_t(SerializedKind) == IsSerialized; } - bool isSerializedForPackage() const { - return SerializedKind_t(SerializedKind) == IsSerializedForPackage; - } - bool isNotSerialized() const { - return SerializedKind_t(SerializedKind) == IsNotSerialized; + bool isAnySerialized() const { + return SerializedKind_t(SerializedKind) == IsSerialized || + SerializedKind_t(SerializedKind) == IsSerializedForPackage; } /// Get this function's serialized attribute. diff --git a/include/swift/SIL/SILGlobalVariable.h b/include/swift/SIL/SILGlobalVariable.h index 217ec338409..2b507d465d7 100644 --- a/include/swift/SIL/SILGlobalVariable.h +++ b/include/swift/SIL/SILGlobalVariable.h @@ -154,11 +154,10 @@ public: /// 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; + + /// Check if this global variable is [serialized] or [serialized_for_package]. + bool isAnySerialized() const; + /// Get this global variable's serialized attribute. SerializedKind_t getSerializedKind() const; void setSerializedKind(SerializedKind_t isSerialized); diff --git a/include/swift/SIL/SILMoveOnlyDeinit.h b/include/swift/SIL/SILMoveOnlyDeinit.h index d126c67bcd5..538a0d56272 100644 --- a/include/swift/SIL/SILMoveOnlyDeinit.h +++ b/include/swift/SIL/SILMoveOnlyDeinit.h @@ -66,8 +66,9 @@ public: return funcImpl; } - bool isNotSerialized() const { - return SerializedKind_t(serialized) == IsNotSerialized; + bool isAnySerialized() const { + return SerializedKind_t(serialized) == IsSerialized || + SerializedKind_t(serialized) == IsSerializedForPackage; } SerializedKind_t getSerializedKind() const { return SerializedKind_t(serialized); diff --git a/include/swift/SIL/SILProperty.h b/include/swift/SIL/SILProperty.h index 877a95b7d74..f89e8c0e4a2 100644 --- a/include/swift/SIL/SILProperty.h +++ b/include/swift/SIL/SILProperty.h @@ -53,7 +53,10 @@ public: AbstractStorageDecl *Decl, std::optional Component); - bool isNotSerialized() const { return SerializedKind_t(Serialized) == IsNotSerialized; } + bool isAnySerialized() const { + return SerializedKind_t(Serialized) == IsSerialized || + SerializedKind_t(Serialized) == IsSerializedForPackage; + } SerializedKind_t getSerializedKind() const { return SerializedKind_t(Serialized); } diff --git a/include/swift/SIL/SILVTable.h b/include/swift/SIL/SILVTable.h index 8977bd5e95a..aa012b743fd 100644 --- a/include/swift/SIL/SILVTable.h +++ b/include/swift/SIL/SILVTable.h @@ -158,11 +158,10 @@ public: bool isSerialized() const { return SerializedKind_t(SerializedKind) == IsSerialized; } - bool isSerializedForPackage() const { - return SerializedKind_t(SerializedKind) == IsSerializedForPackage; - } - bool isNotSerialized() const { - return SerializedKind_t(SerializedKind) == IsNotSerialized; + + bool isAnySerialized() const { + return SerializedKind_t(SerializedKind) == IsSerialized || + SerializedKind_t(SerializedKind) == IsSerializedForPackage; } SerializedKind_t getSerializedKind() const { diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h index 78f6b24c097..45a5821262e 100644 --- a/include/swift/SIL/SILWitnessTable.h +++ b/include/swift/SIL/SILWitnessTable.h @@ -255,12 +255,12 @@ public: bool isSerialized() const { return SerializedKind_t(SerializedKind) == IsSerialized; } - bool isSerializedForPackage() const { - return SerializedKind_t(SerializedKind) == IsSerializedForPackage; - } - bool isNotSerialized() const { - return SerializedKind_t(SerializedKind) == IsNotSerialized; + + bool isAnySerialized() const { + return SerializedKind_t(SerializedKind) == IsSerialized || + SerializedKind_t(SerializedKind) == IsSerializedForPackage; } + SerializedKind_t getSerializedKind() const { return SerializedKind_t(SerializedKind); } diff --git a/lib/SIL/IR/Linker.cpp b/lib/SIL/IR/Linker.cpp index ecb2431a321..916d158c721 100644 --- a/lib/SIL/IR/Linker.cpp +++ b/lib/SIL/IR/Linker.cpp @@ -87,7 +87,7 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) { return; } - assert(F->isNotSerialized() == Mod.isSerialized() && + assert(!F->isAnySerialized() == Mod.isSerialized() && "the de-serializer did set the wrong serialized flag"); F->setBare(IsBare); @@ -186,8 +186,8 @@ void SILLinkerVisitor::linkInVTable(ClassDecl *D) { // for processing. for (auto &entry : Vtbl->getEntries()) { SILFunction *impl = entry.getImplementation(); - if (!Vtbl->isSerialized() || - impl->hasValidLinkageForFragileRef()) { + if (!Vtbl->isAnySerialized() || + impl->hasValidLinkageForFragileRef(Vtbl->getSerializedKind())) { // Deserialize and recursively walk any vtable entries that do not have // bodies yet. maybeAddFunctionToWorklist(impl, diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 84bff5fa10c..54b870f2fb7 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -875,7 +875,6 @@ SerializedKind_t SILDeclRef::getSerializedKind() 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 c58d1e3ef5f..6ca75bbc372 100644 --- a/lib/SIL/IR/SILFunction.cpp +++ b/lib/SIL/IR/SILFunction.cpp @@ -920,8 +920,6 @@ bool SILFunction::hasName(const char *Name) const { 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 @@ -934,22 +932,13 @@ 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(); - +bool SILFunction::canBeInlinedIntoCaller(SerializedKind_t callerSerializedKind) const { 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; + return callerSerializedKind == IsNotSerialized; // If Package-CMO is enabled, we serialize package, public, // and @usableFromInline decls as [serialized_for_package]. @@ -962,8 +951,7 @@ bool SILFunction::canBeInlinedIntoCaller( // 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; + return callerSerializedKind != IsSerialized; case IsSerialized: return true; } @@ -972,16 +960,18 @@ bool SILFunction::canBeInlinedIntoCaller( /// Returns true if this function can be referenced from a fragile function /// body. -bool SILFunction::hasValidLinkageForFragileRef( - std::optional callerSerializedKind, - bool assumeFragileCaller) const { +bool SILFunction::hasValidLinkageForFragileRef(SerializedKind_t callerSerializedKind) const { // Fragile functions can reference 'static inline' functions imported // from C. if (hasForeignBody()) return true; + // The call site of this function must have checked that + // caller.isAnySerialized() is true, as indicated by the + // function name itself (contains 'ForFragileRef'). + assert(callerSerializedKind != IsNotSerialized); // If we can inline it, we can reference it. - if (canBeInlinedIntoCaller(callerSerializedKind, assumeFragileCaller)) + if (canBeInlinedIntoCaller(callerSerializedKind)) return true; // If the containing module has been serialized already, we no longer diff --git a/lib/SIL/IR/SILGlobalVariable.cpp b/lib/SIL/IR/SILGlobalVariable.cpp index 2f568c9a729..ef4fc1388e8 100644 --- a/lib/SIL/IR/SILGlobalVariable.cpp +++ b/lib/SIL/IR/SILGlobalVariable.cpp @@ -78,11 +78,10 @@ bool SILGlobalVariable::shouldBePreservedForDebugger() const { 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; + +bool SILGlobalVariable::isAnySerialized() const { + return SerializedKind_t(Serialized) == IsSerialized || + SerializedKind_t(Serialized) == IsSerializedForPackage; } /// Get this global variable's fragile attribute. diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 4a03935251c..7a63c133ed5 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -158,7 +158,7 @@ namespace { template bool checkResilience(DeclType *D, ModuleDecl *accessingModule, ResilienceExpansion expansion, - bool isSerializedForPackage) { + SerializedKind_t serializedKind) { auto declModule = D->getModuleContext(); // For DEBUGGING: this check looks up @@ -174,7 +174,7 @@ bool checkResilience(DeclType *D, ModuleDecl *accessingModule, // from a client module should be allowed. if (accessingModule != declModule && expansion == ResilienceExpansion::Maximal && - isSerializedForPackage) + serializedKind == IsSerializedForPackage) return false; return D->isResilient(accessingModule, expansion); @@ -184,7 +184,7 @@ template bool checkResilience(DeclType *D, const SILFunction &f) { return checkResilience(D, f.getModule().getSwiftModule(), f.getResilienceExpansion(), - f.isSerializedForPackage()); + f.getSerializedKind()); } bool checkTypeABIAccessible(SILFunction const &F, SILType ty) { @@ -218,7 +218,7 @@ namespace { /// Verify invariants on a key path component. void verifyKeyPathComponent(SILModule &M, TypeExpansionContext typeExpansionContext, - bool isSerializedForPackage, + SerializedKind_t serializedKind, llvm::function_ref require, CanType &baseTy, CanType leafTy, @@ -327,7 +327,7 @@ void verifyKeyPathComponent(SILModule &M, "as the component"); require(property->hasStorage(), "property must be stored"); require(!checkResilience(property, M.getSwiftModule(), - expansion, isSerializedForPackage), + expansion, serializedKind), "cannot access storage of resilient property"); auto propertyTy = loweredBaseTy.getFieldType(property, M, typeExpansionContext); @@ -360,7 +360,8 @@ void verifyKeyPathComponent(SILModule &M, { auto getter = component.getComputedPropertyGetter(); if (expansion == ResilienceExpansion::Minimal) { - require(getter->hasValidLinkageForFragileRef(), + require(serializedKind != IsNotSerialized && + getter->hasValidLinkageForFragileRef(serializedKind), "Key path in serialized function should not reference " "less visible getters"); } @@ -406,7 +407,8 @@ void verifyKeyPathComponent(SILModule &M, auto setter = component.getComputedPropertySetter(); if (expansion == ResilienceExpansion::Minimal) { - require(setter->hasValidLinkageForFragileRef(), + require(serializedKind != IsNotSerialized && + setter->hasValidLinkageForFragileRef(serializedKind), "Key path in serialized function should not reference " "less visible setters"); } @@ -2449,11 +2451,9 @@ public: // 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()) { + if (F.isAnySerialized()) { require((SingleFunction && RefF->isExternalDeclaration()) || - RefF->hasValidLinkageForFragileRef(), + RefF->hasValidLinkageForFragileRef(F.getSerializedKind()), "function_ref inside fragile function cannot " "reference a private or hidden symbol"); } @@ -5736,7 +5736,7 @@ public: verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(), - F.isSerializedForPackage(), + F.getSerializedKind(), [&](bool reqt, StringRef message) { _require(reqt, message); }, baseTy, leafTy, @@ -7040,7 +7040,7 @@ public: SILModule &mod = F->getModule(); bool embedded = mod.getASTContext().LangOpts.hasFeature(Feature::Embedded); - require(F->isNotSerialized() || !mod.isSerialized() || mod.isParsedAsSerializedSIL(), + require(!F->isAnySerialized() || !mod.isSerialized() || mod.isParsedAsSerializedSIL(), "cannot have a serialized function after the module has been serialized"); switch (F->getLinkage()) { @@ -7054,25 +7054,25 @@ public: case SILLinkage::PackageNonABI: require(F->isDefinition(), "alwaysEmitIntoClient function must have a body"); - require(!F->isNotSerialized() || mod.isSerialized(), + require(F->isAnySerialized() || 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->isNotSerialized() || embedded, + require(!F->isAnySerialized() || embedded, "internal/private function cannot be serialized or serializable"); break; case SILLinkage::PublicExternal: require(F->isExternalDeclaration() || - !F->isNotSerialized() || + F->isAnySerialized() || mod.isSerialized(), "public-external function definition must be serialized"); break; case SILLinkage::PackageExternal: require(F->isExternalDeclaration() || - !F->isNotSerialized() || + F->isAnySerialized() || mod.isSerialized(), "package-external function definition must be serialized"); break; @@ -7247,7 +7247,7 @@ void SILProperty::verify(const SILModule &M) const { ResilienceExpansion::Maximal); verifyKeyPathComponent(const_cast(M), typeExpansionContext, - /* isSerializedForPackage */ false, // SILProperty doesn't get serialized + getSerializedKind(), require, baseTy, leafTy, @@ -7409,8 +7409,8 @@ void SILWitnessTable::verify(const SILModule &M) const { if (F) { // If a SILWitnessTable is going to be serialized, it must only // reference public or serializable functions. - if (isSerialized()) { - assert(F->hasValidLinkageForFragileRef() && + if (isAnySerialized()) { + assert(F->hasValidLinkageForFragileRef(getSerializedKind()) && "Fragile witness tables should not reference " "less visible functions."); } @@ -7436,7 +7436,7 @@ void SILDefaultWitnessTable::verify(const SILModule &M) const { #if 0 // FIXME: For now, all default witnesses are private. - assert(F->hasValidLinkageForFragileRef() && + assert(F->hasValidLinkageForFragileRef(IsSerialized) && "Default witness tables should not reference " "less visible functions."); #endif diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index 0b0bc197a5b..1eb85c5cc61 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -1123,7 +1123,7 @@ void SILGenModule::emitNonCopyableTypeDeinitTable(NominalTypeDecl *nom) { 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()) // pcmo TODO: isFragile()? + if (nomIsPublic && !nom->isResilient()) serialized = IsSerialized; SILMoveOnlyDeinit::create(f->getModule(), nom, serialized, f); } diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index eb1a5c3d7ba..d3d2e0f5110 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -1310,10 +1310,7 @@ 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->canBeInlinedIntoCaller()) + if (!ApplyCallee->canBeInlinedIntoCaller(Caller->getSerializedKind())) 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 3156d25ed7e..0984c08f2c7 100644 --- a/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp +++ b/lib/SILOptimizer/IPO/CrossModuleOptimization.cpp @@ -199,15 +199,19 @@ static bool isPackageOrPublic(AccessLevel accessLevel, SILOptions options) { /// is the correct behavior. static bool isSerializedWithRightKind(const SILModule &mod, SILFunction *f) { + // If Package CMO is enabled in resilient mode, return + // true if the function is [serialized] due to @inlinable + // (or similar) or [serialized_for_pkg] due to this + // optimization. return mod.getSwiftModule()->serializePackageEnabled() && mod.getSwiftModule()->isResilient() ? - f->isSerializedForPackage() : f->isSerialized(); + f->isAnySerialized() : f->isSerialized(); } static bool isSerializedWithRightKind(const SILModule &mod, SILGlobalVariable *g) { return mod.getSwiftModule()->serializePackageEnabled() && mod.getSwiftModule()->isResilient() ? - g->isSerializedForPackage() : g->isSerialized(); + g->isAnySerialized() : g->isSerialized(); } static SerializedKind_t getRightSerializedKind(const SILModule &mod) { return mod.getSwiftModule()->serializePackageEnabled() && @@ -271,19 +275,19 @@ void CrossModuleOptimization::serializeTablesInModule() { return; for (const auto &vt : M.getVTables()) { - if (vt->isNotSerialized() && + if (!vt->isAnySerialized() && vt->getClass()->getEffectiveAccess() >= AccessLevel::Package) { vt->setSerializedKind(getRightSerializedKind(M)); } } for (auto &wt : M.getWitnessTables()) { - if (wt.isNotSerialized() && + if (!wt.isAnySerialized() && 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->isNotSerialized() && + !entry.getMethodWitness().Witness->isAnySerialized() && isSerializeCandidate(entry.getMethodWitness().Witness, M.getOptions())) { entry.getMethodWitness().Witness->setSerializedKind(getRightSerializedKind(M)); @@ -322,8 +326,7 @@ bool CrossModuleOptimization::canSerializeFunction( return false; } - if (function->isSerialized() || - isSerializedWithRightKind(M, function)) { + if (function->isAnySerialized()) { canSerializeFlags[function] = true; return true; } @@ -615,13 +618,6 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) { /// marked in \p canSerializeFlags. void CrossModuleOptimization::serializeFunction(SILFunction *function, 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; diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 3f0b2de21cb..b236bbfc003 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -753,11 +753,9 @@ 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->canBeInlinedIntoCaller()) { - if (!CalleeFunction->hasValidLinkageForFragileRef()) { + if (!CalleeFunction->canBeInlinedIntoCaller(F->getSerializedKind())) { + if (F->isAnySerialized() && + !CalleeFunction->hasValidLinkageForFragileRef(F->getSerializedKind())) { llvm::errs() << "caller: " << F->getName() << "\n"; llvm::errs() << "callee: " << CalleeFunction->getName() << "\n"; llvm_unreachable("Should never be inlining a resilient function into " diff --git a/lib/SILOptimizer/UtilityPasses/SILSkippingChecker.cpp b/lib/SILOptimizer/UtilityPasses/SILSkippingChecker.cpp index 84510ecddc8..9481690f36c 100644 --- a/lib/SILOptimizer/UtilityPasses/SILSkippingChecker.cpp +++ b/lib/SILOptimizer/UtilityPasses/SILSkippingChecker.cpp @@ -32,7 +32,7 @@ static bool shouldHaveSkippedFunction(const SILFunction &F) { // First, we only care about functions that haven't been marked serialized. // If they've been marked serialized, they will end up in the final module // and we needed to SILGen them. - if (F.isSerialized()) + if (F.isAnySerialized()) return false; // Next, we're looking for functions that shouldn't have a body, but do. If diff --git a/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp b/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp index bd478503f96..353dd584f89 100644 --- a/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp +++ b/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp @@ -426,7 +426,7 @@ class SerializeSILPass : public SILModuleTransform { /// optimizations and for a better dead function elimination. void removeSerializedFlagFromAllFunctions(SILModule &M) { for (auto &F : M) { - bool wasSerialized = !F.isNotSerialized(); + bool wasSerialized = F.isAnySerialized(); F.setSerializedKind(IsNotSerialized); // We are removing [serialized] from the function. This will change how diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp index e56ed4ff75c..908feba5e54 100644 --- a/lib/SILOptimizer/Utils/CastOptimizer.cpp +++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp @@ -530,8 +530,8 @@ findBridgeToObjCFunc(SILOptFunctionBuilder &functionBuilder, bridgedFunc->setParentModule( resultDecl->getDeclContext()->getParentModule()); - if (dynamicCast.getFunction()->isSerialized() && - !bridgedFunc->hasValidLinkageForFragileRef()) + if (dynamicCast.getFunction()->isAnySerialized() && + !bridgedFunc->hasValidLinkageForFragileRef(dynamicCast.getFunction()->getSerializedKind())) return std::nullopt; if (bridgedFunc->getLoweredFunctionType() diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp index 1c188e8b9b4..d96aafdfae4 100644 --- a/lib/SILOptimizer/Utils/Devirtualize.cpp +++ b/lib/SILOptimizer/Utils/Devirtualize.cpp @@ -719,11 +719,11 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd, return false; } - // pcmo TODO: check for tri-state serialized kind - if (applySite.getFunction()->isSerialized()) { + if (applySite.getFunction()->isAnySerialized()) { // function_ref inside fragile function cannot reference a private or // hidden symbol. - if (!f->hasValidLinkageForFragileRef()) + if (!f->hasValidLinkageForFragileRef( + applySite.getFunction()->getSerializedKind())) return false; } @@ -1168,13 +1168,11 @@ 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. - if (!f->hasValidLinkageForFragileRef()) - return false; - } + // function_ref inside fragile function cannot reference a private or + // hidden symbol. + if (applySite.getFunction()->isAnySerialized() && + !f->hasValidLinkageForFragileRef(applySite.getFunction()->getSerializedKind())) + return false; // devirtualizeWitnessMethod below does not support this case. It currently // assumes it can try_apply call the target. diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index 33e814cf9b0..93ec3842399 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -3140,12 +3140,10 @@ void swift::trySpecializeApplyOfGeneric( // callee either. bool needSetLinkage = false; if (isMandatory) { - // pcmo TODO: remove F->isSerialiezd() and pass its kind to - // canBeInlinedIntoCaller instead. - if (F->isSerialized() && !RefF->canBeInlinedIntoCaller()) + if (!RefF->canBeInlinedIntoCaller(F->getSerializedKind())) needSetLinkage = true; } else { - if (F->isSerialized() && !RefF->canBeInlinedIntoCaller()) + if (!RefF->canBeInlinedIntoCaller(F->getSerializedKind())) return; if (shouldNotSpecialize(RefF, F)) @@ -3265,22 +3263,22 @@ void swift::trySpecializeApplyOfGeneric( return; } - // pcmo TODO: remove F->isSerialiezd() and pass its kind to - // canBeInlinedIntoCaller instead. if (needSetLinkage) { - assert(F->isSerialized() && !RefF->canBeInlinedIntoCaller()); + assert(F->isAnySerialized() && + !RefF->canBeInlinedIntoCaller(F->getSerializedKind())); // 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->setSerializedKind(IsNotSerialized); - } else if (F->isSerialized() && !SpecializedF->canBeInlinedIntoCaller()) { + } else if (F->isAnySerialized() && + !SpecializedF->canBeInlinedIntoCaller(F->getSerializedKind())) { // 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->setSerializedKind(IsSerialized); - assert(SpecializedF->canBeInlinedIntoCaller()); + // but now it's called from a serialized function, we need to mark it the + // same as its SerializedKind. + SpecializedF->setSerializedKind(F->getSerializedKind()); + assert(SpecializedF->canBeInlinedIntoCaller(F->getSerializedKind())); // ... 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 c10e83edcca..30d10cc7715 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->isNotSerialized()) { + if (hasPrivateVisibility(linkage) && !f->isAnySerialized()) { // 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 00b027e2938..fe177898f4a 100644 --- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp +++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp @@ -846,11 +846,9 @@ 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->canBeInlinedIntoCaller()) { - if (!Callee->hasValidLinkageForFragileRef()) { + if (!Callee->canBeInlinedIntoCaller(Caller->getSerializedKind())) { + if (Caller->isAnySerialized() && + !Callee->hasValidLinkageForFragileRef(Caller->getSerializedKind())) { llvm::errs() << "caller: " << Caller->getName() << "\n"; llvm::errs() << "callee: " << Callee->getName() << "\n"; llvm_unreachable("Should never be inlining a resilient function into " diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index b42a330f465..dadf6344001 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -657,27 +657,13 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, 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 (SerializedKind_t(serializedKind) == IsSerializedForPackage && - loadedModule->isResilient() && - loadedModule != SILMod.getSwiftModule() && - loadedModule->serializePackageEnabled() && - loadedModule->inSamePackage(SILMod.getSwiftModule())) - 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 // correctly update the linkage for forward declarations to entities defined // in another file of the same module – we want to ensure the linkage // reflects the fact that the entity isn't really external and shouldn't be // dropped from the resulting merged module. - if (loadedModule == SILMod.getSwiftModule()) + if (getFile()->getParentModule() == SILMod.getSwiftModule()) fn->setLinkage(linkage); // Don't override the transparency or linkage of a function with @@ -981,7 +967,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn, Callback->didDeserializeFunctionBody(MF->getAssociatedModule(), fn); if (!MF->isSIB() && !SILMod.isSerialized()) { - assert((!fn->isNotSerialized() || fn->empty()) && + assert((fn->isAnySerialized() || fn->empty()) && "deserialized function must have the IsSerialized or IsSerializedForPackage flag set"); } return fn; diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 537bc16bee4..98660b08095 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -278,7 +278,7 @@ namespace { void writeSILGlobalVar(const SILGlobalVariable &g); void writeSILWitnessTable(const SILWitnessTable &wt); void writeSILWitnessTableEntry(const SILWitnessTable::Entry &entry, - std::optional serializedKind = std::nullopt); + SerializedKind_t serializedKind); void writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt); void writeSILDifferentiabilityWitness(const SILDifferentiabilityWitness &dw); @@ -376,8 +376,7 @@ void SILSerializer::addReferencedSILFunction(const SILFunction *F, } if (F->getLinkage() == SILLinkage::Shared) { - assert(!F->isNotSerialized() || - F->hasForeignBody()); + assert(F->isAnySerialized() || F->hasForeignBody()); FuncsToEmit[F] = false; functionWorklist.push_back(F); @@ -495,7 +494,6 @@ 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"); @@ -2879,7 +2877,7 @@ void SILSerializer::writeSILGlobalVar(const SILGlobalVariable &g) { TyID, dID); // Don't emit the initializer instructions if not marked as "serialized". - if (g.isNotSerialized()) + if (!g.isAnySerialized()) return; ValueIDs.clear(); @@ -2926,8 +2924,8 @@ void SILSerializer::writeSILVTable(const SILVTable &vt) { SILFunction *impl = entry.getImplementation(); if (ShouldSerializeAll || - impl->hasValidLinkageForFragileRef(vt.getSerializedKind(), - /*assumeFragileCaller*/ false)) { + (vt.isAnySerialized() && + impl->hasValidLinkageForFragileRef(vt.getSerializedKind()))) { handleSILDeclRef(S, entry.getMethod(), ListOfValues); addReferencedSILFunction(impl, true); // Each entry is a pair of SILDeclRef and SILFunction. @@ -2950,7 +2948,7 @@ void SILSerializer::writeSILMoveOnlyDeinit(const SILMoveOnlyDeinit &deinit) { return; SILFunction *impl = deinit.getImplementation(); - if (!ShouldSerializeAll && !impl->hasValidLinkageForFragileRef()) + if (!ShouldSerializeAll && !impl->hasValidLinkageForFragileRef(IsSerialized)) return; // Use the mangled name of the class as a key to distinguish between classes @@ -3026,7 +3024,7 @@ void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) { void SILSerializer::writeSILWitnessTableEntry( const SILWitnessTable::Entry &entry, - std::optional serializedKind) { + SerializedKind_t serializedKind) { if (entry.getKind() == SILWitnessTable::BaseProtocol) { auto &baseWitness = entry.getBaseProtocolWitness(); @@ -3068,8 +3066,8 @@ void SILSerializer::writeSILWitnessTableEntry( IdentifierID witnessID = 0; SILFunction *witness = methodWitness.Witness; if (witness && - witness->hasValidLinkageForFragileRef(serializedKind, - /*assumeFragileCaller*/ false)) { + serializedKind != IsNotSerialized && + witness->hasValidLinkageForFragileRef(serializedKind)) { addReferencedSILFunction(witness, true); witnessID = S.addUniquedStringRef(witness->getName()); } @@ -3102,7 +3100,7 @@ writeSILDefaultWitnessTable(const SILDefaultWitnessTable &wt) { SILAbbrCodes[DefaultWitnessTableNoEntryLayout::Code]); continue; } - writeSILWitnessTableEntry(entry); + writeSILWitnessTableEntry(entry, IsNotSerialized); } } @@ -3174,8 +3172,7 @@ 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->isNotSerialized() && - !hasSharedVisibility(F->getLinkage())) + if (F->isAnySerialized() && !hasSharedVisibility(F->getLinkage())) return true; return false; @@ -3237,13 +3234,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->isNotSerialized()) && + if ((ShouldSerializeAll || vt->isAnySerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(vt->getClass())) writeSILVTable(*vt); } for (const auto &deinit : SILMod->getMoveOnlyDeinits()) { - if ((ShouldSerializeAll || !deinit->isNotSerialized()) && + if ((ShouldSerializeAll || deinit->isAnySerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( deinit->getNominalDecl())) writeSILMoveOnlyDeinit(*deinit); @@ -3251,7 +3248,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Write out property descriptors. for (const SILProperty &prop : SILMod->getPropertyList()) { - if ((ShouldSerializeAll || !prop.isNotSerialized()) && + if ((ShouldSerializeAll || prop.isAnySerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( prop.getDecl()->getInnermostDeclContext())) writeSILProperty(prop); @@ -3259,7 +3256,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { // Write out fragile WitnessTables. for (const SILWitnessTable &wt : SILMod->getWitnessTables()) { - if ((ShouldSerializeAll || !wt.isNotSerialized()) && + if ((ShouldSerializeAll || wt.isAnySerialized()) && SILMod->shouldSerializeEntitiesAssociatedWithDeclContext( wt.getConformance()->getDeclContext())) writeSILWitnessTable(wt); @@ -3276,7 +3273,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.isNotSerialized() || ShouldSerializeAll) + if (g.isAnySerialized() || ShouldSerializeAll) addReferencedGlobalVariable(&g); } @@ -3322,7 +3319,6 @@ 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);