@@ -189,6 +189,10 @@ static bool isPackageOrPublic(AccessLevel accessLevel, SILOptions options) {
189
189
return accessLevel == AccessLevel::Public;
190
190
}
191
191
192
+ static bool isPackageCMOEnabled (ModuleDecl *mod) {
193
+ return mod->isResilient () && mod->serializePackageEnabled ();
194
+ }
195
+
192
196
// / Checks wither this function is [serialized_for_package] due to Package CMO
193
197
// / or [serialized] with non-package CMO. The [serialized_for_package] attribute
194
198
// / 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) {
201
205
// / is the correct behavior.
202
206
static bool isSerializedWithRightKind (const SILModule &mod,
203
207
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 ();
207
214
}
208
215
static bool isSerializedWithRightKind (const SILModule &mod,
209
216
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 ();
213
219
}
214
220
static 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;
218
223
}
219
224
220
225
static bool isSerializeCandidate (SILFunction *F, SILOptions options) {
@@ -286,24 +291,28 @@ void CrossModuleOptimization::serializeTablesInModule() {
286
291
// This should not be necessary but is added to ensure all applicable
287
292
// symbols are serialized. Whether serialized or not is cached so
288
293
// 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
+ });
292
299
std::vector<SILFunction *> classMethodsToSerialize;
293
300
llvm::transform (unserializedClassMethodRange,
294
301
std::back_inserter (classMethodsToSerialize),
295
- [&](auto entry) {
296
- return entry.getImplementation ();
297
- });
302
+ [&](const SILVTableEntry & entry) {
303
+ return entry.getImplementation ();
304
+ });
298
305
trySerializeFunctions (classMethodsToSerialize);
299
306
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
+ });
307
316
if (!containsInternal)
308
317
vt->setSerializedKind (getRightSerializedKind (M));
309
318
}
@@ -318,25 +327,31 @@ void CrossModuleOptimization::serializeTablesInModule() {
318
327
// This should not be necessary but is added to ensure all applicable
319
328
// symbols are serialized. Whether serialized or not is cached so
320
329
// 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
+ });
325
336
std::vector<SILFunction *> wtMethodsToSerialize;
326
337
llvm::transform (unserializedWTMethodRange,
327
338
std::back_inserter (wtMethodsToSerialize),
328
- [&](auto entry) {
329
- return entry.getMethodWitness ().Witness ;
330
- });
339
+ [&](const SILWitnessTable::Entry & entry) {
340
+ return entry.getMethodWitness ().Witness ;
341
+ });
331
342
trySerializeFunctions (wtMethodsToSerialize);
332
343
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
+ });
340
355
if (!containsInternal)
341
356
wt.setSerializedKind (getRightSerializedKind (M));
342
357
}
@@ -485,17 +500,29 @@ bool CrossModuleOptimization::canSerializeInstruction(
485
500
[&](SILDeclRef method) {
486
501
if (method.isForeign )
487
502
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
+ }
488
511
});
489
512
return canUse;
490
513
}
491
514
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.
494
517
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;
499
526
}
500
527
if (auto *REAI = dyn_cast<RefElementAddrInst>(inst)) {
501
528
// In conservative mode, we don't support class field accesses of non-public
@@ -737,7 +764,9 @@ void CrossModuleOptimization::serializeInstruction(SILInstruction *inst,
737
764
if (canSerializeGlobal (global)) {
738
765
serializeGlobal (global);
739
766
}
740
- if (!hasPublicOrPackageVisibility (global->getLinkage (), M.getSwiftModule ()->serializePackageEnabled ())) {
767
+ if (!hasPublicOrPackageVisibility (
768
+ global->getLinkage (),
769
+ M.getSwiftModule ()->serializePackageEnabled ())) {
741
770
global->setLinkage (SILLinkage::Public);
742
771
}
743
772
return ;
0 commit comments