@@ -60,11 +60,15 @@ class CrossModuleOptimization {
60
60
// / avoid code size increase.
61
61
bool conservative;
62
62
63
+ // / True if CMO should serialize literally everything in the module,
64
+ // / regardless of linkage.
65
+ bool everything;
66
+
63
67
typedef llvm::DenseMap<SILFunction *, bool > FunctionFlags;
64
68
65
69
public:
66
- CrossModuleOptimization (SILModule &M, bool conservative)
67
- : M(M), conservative(conservative) { }
70
+ CrossModuleOptimization (SILModule &M, bool conservative, bool everything )
71
+ : M(M), conservative(conservative), everything(everything) { }
68
72
69
73
void serializeFunctionsInModule ();
70
74
@@ -164,9 +168,10 @@ void CrossModuleOptimization::serializeFunctionsInModule() {
164
168
165
169
// Start with public functions.
166
170
for (SILFunction &F : M) {
167
- if (F.getLinkage () == SILLinkage::Public) {
168
- if (canSerializeFunction (&F, canSerializeFlags, /* maxDepth*/ 64 ))
171
+ if (F.getLinkage () == SILLinkage::Public || everything ) {
172
+ if (canSerializeFunction (&F, canSerializeFlags, /* maxDepth*/ 64 )) {
169
173
serializeFunction (&F, canSerializeFlags);
174
+ }
170
175
}
171
176
}
172
177
}
@@ -189,6 +194,11 @@ bool CrossModuleOptimization::canSerializeFunction(
189
194
// it to true at the end of this function.
190
195
canSerializeFlags[function] = false ;
191
196
197
+ if (everything) {
198
+ canSerializeFlags[function] = true ;
199
+ return true ;
200
+ }
201
+
192
202
if (DeclContext *funcCtxt = function->getDeclContext ()) {
193
203
if (!canUseFromInline (funcCtxt))
194
204
return false ;
@@ -392,6 +402,9 @@ static bool couldBeLinkedStatically(DeclContext *funcCtxt, SILModule &module) {
392
402
393
403
// / Returns true if the \p declCtxt can be used from a serialized function.
394
404
bool CrossModuleOptimization::canUseFromInline (DeclContext *declCtxt) {
405
+ if (everything)
406
+ return true ;
407
+
395
408
if (!M.getSwiftModule ()->canBeUsedForCrossModuleOptimization (declCtxt))
396
409
return false ;
397
410
@@ -410,6 +423,9 @@ bool CrossModuleOptimization::canUseFromInline(DeclContext *declCtxt) {
410
423
411
424
// / Returns true if the function \p func can be used from a serialized function.
412
425
bool CrossModuleOptimization::canUseFromInline (SILFunction *function) {
426
+ if (everything)
427
+ return true ;
428
+
413
429
if (DeclContext *funcCtxt = function->getDeclContext ()) {
414
430
if (!canUseFromInline (funcCtxt))
415
431
return false ;
@@ -439,14 +455,12 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) {
439
455
if (function->isSerialized ())
440
456
return false ;
441
457
458
+ if (everything)
459
+ return true ;
460
+
442
461
if (function->hasSemanticsAttr (" optimize.no.crossmodule" ))
443
462
return false ;
444
463
445
- // In embedded Swift we serialize everything.
446
- if (SerializeEverything ||
447
- function->getASTContext ().LangOpts .hasFeature (Feature::Embedded))
448
- return true ;
449
-
450
464
if (!conservative) {
451
465
// The basic heuristic: serialize all generic functions, because it makes a
452
466
// huge difference if generic functions can be specialized or not.
@@ -652,23 +666,29 @@ class CrossModuleOptimizationPass: public SILModuleTransform {
652
666
return ;
653
667
if (!M.isWholeModule ())
654
668
return ;
655
-
669
+
656
670
bool conservative = false ;
657
- // In embedded Swift we serialize everything.
658
- if (!M.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
659
- switch (M.getOptions ().CMOMode ) {
660
- case swift::CrossModuleOptimizationMode::Off:
661
- return ;
662
- case swift::CrossModuleOptimizationMode::Default:
663
- conservative = true ;
664
- break ;
665
- case swift::CrossModuleOptimizationMode::Aggressive:
666
- conservative = false ;
667
- break ;
668
- }
671
+ bool everything = SerializeEverything;
672
+ switch (M.getOptions ().CMOMode ) {
673
+ case swift::CrossModuleOptimizationMode::Off:
674
+ break ;
675
+ case swift::CrossModuleOptimizationMode::Default:
676
+ conservative = true ;
677
+ break ;
678
+ case swift::CrossModuleOptimizationMode::Aggressive:
679
+ conservative = false ;
680
+ break ;
681
+ case swift::CrossModuleOptimizationMode::Everything:
682
+ everything = true ;
683
+ break ;
684
+ }
685
+
686
+ if (!everything &&
687
+ M.getOptions ().CMOMode == swift::CrossModuleOptimizationMode::Off) {
688
+ return ;
669
689
}
670
690
671
- CrossModuleOptimization CMO (M, conservative);
691
+ CrossModuleOptimization CMO (M, conservative, everything );
672
692
CMO.serializeFunctionsInModule ();
673
693
}
674
694
};
0 commit comments