@@ -189,6 +189,10 @@ static bool isPackageOrPublic(AccessLevel accessLevel, SILOptions options) {
189189 return accessLevel == AccessLevel::Public;
190190}
191191
192+ static bool isPackageCMOEnabled (ModuleDecl *mod) {
193+ return mod->isResilient () && mod->serializePackageEnabled ();
194+ }
195+
192196// / Checks wither this function is [serialized_for_package] due to Package CMO
193197// / or [serialized] with non-package CMO. The [serialized_for_package] attribute
194198// / is used to indicate that a function is serialized because of Package CMO, which
@@ -201,20 +205,21 @@ static bool isPackageOrPublic(AccessLevel accessLevel, SILOptions options) {
201205// / is the correct behavior.
202206static bool isSerializedWithRightKind (const SILModule &mod,
203207 SILFunction *f) {
204- return mod.getSwiftModule ()->serializePackageEnabled () &&
205- mod.getSwiftModule ()->isResilient () ?
206- f->isSerializedForPackage () : f->isSerialized ();
208+ // If Package CMO is enabled in resilient mode, return
209+ // true if the function is [serialized] due to @inlinable
210+ // (or similar) or [serialized_for_pkg] due to this
211+ // optimization.
212+ return isPackageCMOEnabled (mod.getSwiftModule ()) ? f->isAnySerialized ()
213+ : f->isSerialized ();
207214}
208215static bool isSerializedWithRightKind (const SILModule &mod,
209216 SILGlobalVariable *g) {
210- return mod.getSwiftModule ()->serializePackageEnabled () &&
211- mod.getSwiftModule ()->isResilient () ?
212- g->isSerializedForPackage () : g->isSerialized ();
217+ return isPackageCMOEnabled (mod.getSwiftModule ()) ? g->isAnySerialized ()
218+ : g->isSerialized ();
213219}
214220static SerializedKind_t getRightSerializedKind (const SILModule &mod) {
215- return mod.getSwiftModule ()->serializePackageEnabled () &&
216- mod.getSwiftModule ()->isResilient () ?
217- IsSerializedForPackage : IsSerialized;
221+ return isPackageCMOEnabled (mod.getSwiftModule ()) ? IsSerializedForPackage
222+ : IsSerialized;
218223}
219224
220225static bool isSerializeCandidate (SILFunction *F, SILOptions options) {
@@ -286,24 +291,28 @@ void CrossModuleOptimization::serializeTablesInModule() {
286291 // This should not be necessary but is added to ensure all applicable
287292 // symbols are serialized. Whether serialized or not is cached so
288293 // this check shouldn't be expensive.
289- auto unserializedClassMethodRange = llvm::make_filter_range (vt->getEntries (), [&](auto &entry) {
290- return entry.getImplementation ()->getSerializedKind () != getRightSerializedKind (M);
291- });
294+ auto unserializedClassMethodRange = llvm::make_filter_range (
295+ vt->getEntries (), [&](const SILVTableEntry &entry) {
296+ return entry.getImplementation ()->getSerializedKind () !=
297+ getRightSerializedKind (M);
298+ });
292299 std::vector<SILFunction *> classMethodsToSerialize;
293300 llvm::transform (unserializedClassMethodRange,
294301 std::back_inserter (classMethodsToSerialize),
295- [&](auto entry) {
296- return entry.getImplementation ();
297- });
302+ [&](const SILVTableEntry & entry) {
303+ return entry.getImplementation ();
304+ });
298305 trySerializeFunctions (classMethodsToSerialize);
299306
300- bool containsInternal = llvm::any_of (classMethodsToSerialize, [&](auto &method) {
301- // If the entry is internal, vtable should not be serialized.
302- // However, if the entry is not serialized but has the right
303- // visibility, it can still be referenced, thus the vtable
304- // should serialized.
305- return !method->hasValidLinkageForFragileRef (getRightSerializedKind (M));
306- });
307+ bool containsInternal =
308+ llvm::any_of (vt->getEntries (), [&](const SILVTableEntry &entry) {
309+ // If the entry is internal, vtable should not be serialized.
310+ // However, if the entry is not serialized but has the right
311+ // visibility, it can still be referenced, thus the vtable
312+ // should serialized.
313+ return !entry.getImplementation ()->hasValidLinkageForFragileRef (
314+ getRightSerializedKind (M));
315+ });
307316 if (!containsInternal)
308317 vt->setSerializedKind (getRightSerializedKind (M));
309318 }
@@ -318,25 +327,31 @@ void CrossModuleOptimization::serializeTablesInModule() {
318327 // This should not be necessary but is added to ensure all applicable
319328 // symbols are serialized. Whether serialized or not is cached so
320329 // this check shouldn't be expensive.
321- auto unserializedWTMethodRange = llvm::make_filter_range (wt.getEntries (), [&](auto &entry) {
322- return entry.getKind () == SILWitnessTable::Method &&
323- entry.getMethodWitness ().Witness ->getSerializedKind () != getRightSerializedKind (M);
324- });
330+ auto unserializedWTMethodRange = llvm::make_filter_range (
331+ wt.getEntries (), [&](const SILWitnessTable::Entry &entry) {
332+ return entry.getKind () == SILWitnessTable::Method &&
333+ entry.getMethodWitness ().Witness ->getSerializedKind () !=
334+ getRightSerializedKind (M);
335+ });
325336 std::vector<SILFunction *> wtMethodsToSerialize;
326337 llvm::transform (unserializedWTMethodRange,
327338 std::back_inserter (wtMethodsToSerialize),
328- [&](auto entry) {
329- return entry.getMethodWitness ().Witness ;
330- });
339+ [&](const SILWitnessTable::Entry & entry) {
340+ return entry.getMethodWitness ().Witness ;
341+ });
331342 trySerializeFunctions (wtMethodsToSerialize);
332343
333- bool containsInternal = llvm::any_of (wtMethodsToSerialize, [&](auto &method) {
334- // If the entry is internal, wtable should not be serialized.
335- // However, if the entry is not serialized but has the right
336- // visibility, it can still be referenced, thus the vtable
337- // should serialized.
338- return !method->hasValidLinkageForFragileRef (getRightSerializedKind (M));
339- });
344+ bool containsInternal = llvm::any_of (
345+ wt.getEntries (), [&](const SILWitnessTable::Entry &entry) {
346+ // If the entry is internal, wtable should not be serialized.
347+ // However, if the entry is not serialized but has the right
348+ // visibility, it can still be referenced, thus the vtable
349+ // should serialized.
350+ return entry.getKind () == SILWitnessTable::Method &&
351+ !entry.getMethodWitness ()
352+ .Witness ->hasValidLinkageForFragileRef (
353+ getRightSerializedKind (M));
354+ });
340355 if (!containsInternal)
341356 wt.setSerializedKind (getRightSerializedKind (M));
342357 }
@@ -485,17 +500,29 @@ bool CrossModuleOptimization::canSerializeInstruction(
485500 [&](SILDeclRef method) {
486501 if (method.isForeign )
487502 canUse = false ;
503+ else if (isPackageCMOEnabled (method.getModuleContext ())) {
504+ // If the referenced keypath is internal, do not
505+ // serialize.
506+ auto methodScope = method.getDecl ()->getFormalAccessScope (
507+ nullptr ,
508+ /* treatUsableFromInlineAsPublic*/ true );
509+ canUse = methodScope.isPublicOrPackage ();
510+ }
488511 });
489512 return canUse;
490513 }
491514 if (auto *MI = dyn_cast<MethodInst>(inst)) {
492- // If a class_method or witness_method is internal, it can't
493- // be serialized.
515+ // If a class_method or witness_method is internal,
516+ // it can't be serialized.
494517 auto member = MI->getMember ();
495- auto methodAccessScope = member.getDecl ()->getFormalAccessScope (nullptr ,
496- /* treatUsableFromInlineAsPublic*/ true );
497- return methodAccessScope.isPublicOrPackage () &&
498- !member.isForeign ;
518+ auto canUse = !member.isForeign ;
519+ if (canUse && isPackageCMOEnabled (member.getModuleContext ())) {
520+ auto methodScope = member.getDecl ()->getFormalAccessScope (
521+ nullptr ,
522+ /* treatUsableFromInlineAsPublic*/ true );
523+ canUse = methodScope.isPublicOrPackage ();
524+ }
525+ return canUse;
499526 }
500527 if (auto *REAI = dyn_cast<RefElementAddrInst>(inst)) {
501528 // In conservative mode, we don't support class field accesses of non-public
@@ -737,7 +764,9 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst,
737764 if (canSerializeGlobal (global)) {
738765 serializeGlobal (global);
739766 }
740- if (!hasPublicOrPackageVisibility (global->getLinkage (), M.getSwiftModule ()->serializePackageEnabled ())) {
767+ if (!hasPublicOrPackageVisibility (
768+ global->getLinkage (),
769+ M.getSwiftModule ()->serializePackageEnabled ())) {
741770 global->setLinkage (SILLinkage::Public);
742771 }
743772 return ;
0 commit comments