@@ -31,6 +31,11 @@ STATISTIC(NumDeadGlobals, "Number of dead global variables eliminated");
31
31
32
32
namespace {
33
33
34
+ static bool loweredFunctionHasGenericArguments (const SILFunction *f) {
35
+ auto s = f->getLoweredFunctionType ()->getInvocationGenericSignature ();
36
+ return s && !s->areAllParamsConcrete ();
37
+ }
38
+
34
39
class DeadFunctionAndGlobalElimination {
35
40
// / Represents a function which is implementing a vtable or witness table
36
41
// / method.
@@ -90,6 +95,8 @@ class DeadFunctionAndGlobalElimination {
90
95
91
96
bool keepExternalWitnessTablesAlive;
92
97
98
+ bool removeUnspecializedFunctionsInEmbeddedSwift;
99
+
93
100
// / Checks is a function is alive, e.g. because it is visible externally.
94
101
bool isAnchorFunction (SILFunction *F) {
95
102
@@ -422,7 +429,15 @@ class DeadFunctionAndGlobalElimination {
422
429
findAnchorsInTables ();
423
430
424
431
for (SILFunction &F : *Module) {
425
- if (isAnchorFunction (&F)) {
432
+ // In embedded Swift, generic functions, even public ones cannot be used
433
+ // externally and are not anchors.
434
+ bool embedded =
435
+ Module->getASTContext ().LangOpts .hasFeature (Feature::Embedded);
436
+ bool generic = loweredFunctionHasGenericArguments (&F);
437
+ bool ignoreAnchor =
438
+ embedded && generic && removeUnspecializedFunctionsInEmbeddedSwift;
439
+
440
+ if (isAnchorFunction (&F) && !ignoreAnchor) {
426
441
LLVM_DEBUG (llvm::dbgs () << " anchor function: " << F.getName () <<" \n " );
427
442
ensureAlive (&F);
428
443
}
@@ -433,7 +448,7 @@ class DeadFunctionAndGlobalElimination {
433
448
[this ](SILFunction *targetFun) { ensureAlive (targetFun); });
434
449
435
450
bool retainBecauseFunctionIsNoOpt = !F.shouldOptimize ();
436
- if (Module-> getASTContext (). LangOpts . hasFeature (Feature::Embedded) )
451
+ if (embedded )
437
452
retainBecauseFunctionIsNoOpt = false ;
438
453
439
454
if (retainBecauseFunctionIsNoOpt) {
@@ -692,13 +707,16 @@ class DeadFunctionAndGlobalElimination {
692
707
}
693
708
694
709
public:
695
- DeadFunctionAndGlobalElimination (SILModule *module ,
696
- bool keepExternalWitnessTablesAlive) :
697
- Module (module ),
698
- keepExternalWitnessTablesAlive (keepExternalWitnessTablesAlive) {}
710
+ DeadFunctionAndGlobalElimination (
711
+ SILModule *module , bool keepExternalWitnessTablesAlive,
712
+ bool removeUnspecializedFunctionsInEmbeddedSwift)
713
+ : Module(module ),
714
+ keepExternalWitnessTablesAlive (keepExternalWitnessTablesAlive),
715
+ removeUnspecializedFunctionsInEmbeddedSwift(
716
+ removeUnspecializedFunctionsInEmbeddedSwift) {}
699
717
700
- // / The main entry point of the optimization.
701
- void eliminateFunctionsAndGlobals (SILModuleTransform *DFEPass) {
718
+ // / The main entry point of the optimization.
719
+ void eliminateFunctionsAndGlobals (SILModuleTransform *DFEPass) {
702
720
703
721
LLVM_DEBUG (llvm::dbgs () << " running dead function elimination\n " );
704
722
findAliveFunctions ();
@@ -779,8 +797,10 @@ class DeadFunctionAndGlobalEliminationPass : public SILModuleTransform {
779
797
// can eliminate such functions.
780
798
getModule ()->invalidateSILLoaderCaches ();
781
799
782
- DeadFunctionAndGlobalElimination deadFunctionElimination (getModule (),
783
- /* keepExternalWitnessTablesAlive*/ !isLateDFE);
800
+ DeadFunctionAndGlobalElimination deadFunctionElimination (
801
+ getModule (),
802
+ /* keepExternalWitnessTablesAlive*/ !isLateDFE,
803
+ /* removeUnspecializedFunctionsInEmbeddedSwift*/ isLateDFE);
784
804
deadFunctionElimination.eliminateFunctionsAndGlobals (this );
785
805
}
786
806
};
0 commit comments