@@ -60,11 +60,15 @@ class CrossModuleOptimization {
6060 // / avoid code size increase.
6161 bool conservative;
6262
63+ // / True if CMO should serialize literally everything in the module,
64+ // / regardless of linkage.
65+ bool everything;
66+
6367 typedef llvm::DenseMap<SILFunction *, bool > FunctionFlags;
6468
6569public:
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) { }
6872
6973 void serializeFunctionsInModule ();
7074
@@ -164,9 +168,10 @@ void CrossModuleOptimization::serializeFunctionsInModule() {
164168
165169 // Start with public functions.
166170 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 )) {
169173 serializeFunction (&F, canSerializeFlags);
174+ }
170175 }
171176 }
172177}
@@ -189,6 +194,11 @@ bool CrossModuleOptimization::canSerializeFunction(
189194 // it to true at the end of this function.
190195 canSerializeFlags[function] = false ;
191196
197+ if (everything) {
198+ canSerializeFlags[function] = true ;
199+ return true ;
200+ }
201+
192202 if (DeclContext *funcCtxt = function->getDeclContext ()) {
193203 if (!canUseFromInline (funcCtxt))
194204 return false ;
@@ -392,6 +402,9 @@ static bool couldBeLinkedStatically(DeclContext *funcCtxt, SILModule &module) {
392402
393403// / Returns true if the \p declCtxt can be used from a serialized function.
394404bool CrossModuleOptimization::canUseFromInline (DeclContext *declCtxt) {
405+ if (everything)
406+ return true ;
407+
395408 if (!M.getSwiftModule ()->canBeUsedForCrossModuleOptimization (declCtxt))
396409 return false ;
397410
@@ -410,6 +423,9 @@ bool CrossModuleOptimization::canUseFromInline(DeclContext *declCtxt) {
410423
411424// / Returns true if the function \p func can be used from a serialized function.
412425bool CrossModuleOptimization::canUseFromInline (SILFunction *function) {
426+ if (everything)
427+ return true ;
428+
413429 if (DeclContext *funcCtxt = function->getDeclContext ()) {
414430 if (!canUseFromInline (funcCtxt))
415431 return false ;
@@ -439,14 +455,12 @@ bool CrossModuleOptimization::shouldSerialize(SILFunction *function) {
439455 if (function->isSerialized ())
440456 return false ;
441457
458+ if (everything)
459+ return true ;
460+
442461 if (function->hasSemanticsAttr (" optimize.no.crossmodule" ))
443462 return false ;
444463
445- // In embedded Swift we serialize everything.
446- if (SerializeEverything ||
447- function->getASTContext ().LangOpts .hasFeature (Feature::Embedded))
448- return true ;
449-
450464 if (!conservative) {
451465 // The basic heuristic: serialize all generic functions, because it makes a
452466 // huge difference if generic functions can be specialized or not.
@@ -652,23 +666,29 @@ class CrossModuleOptimizationPass: public SILModuleTransform {
652666 return ;
653667 if (!M.isWholeModule ())
654668 return ;
655-
669+
656670 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 ;
669689 }
670690
671- CrossModuleOptimization CMO (M, conservative);
691+ CrossModuleOptimization CMO (M, conservative, everything );
672692 CMO.serializeFunctionsInModule ();
673693 }
674694};
0 commit comments