Skip to content

Commit e8b00a1

Browse files
authored
Merge pull request #29472 from eeckstein/delete-dead-wt
DeadFunctionElimination: remove externally available witness tables at the end of the pipeline
2 parents e3b511d + 03b0a6c commit e8b00a1

File tree

6 files changed

+41
-10
lines changed

6 files changed

+41
-10
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ PASS(LICM, "licm",
200200
"Loop Invariant Code Motion")
201201
PASS(LateCodeMotion, "late-codemotion",
202202
"Late Code Motion with Release Hoisting")
203+
PASS(LateDeadFunctionElimination, "late-deadfuncelim",
204+
"Late Dead Function Elimination")
203205
PASS(LateInliner, "late-inline",
204206
"Late Function Inlining")
205207
PASS(LoopCanonicalizer, "loop-canonicalizer",

lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class FunctionLivenessComputation {
9090

9191
llvm::SmallPtrSet<void *, 32> AliveFunctionsAndTables;
9292

93+
bool keepExternalWitnessTablesAlive;
94+
9395
/// Checks is a function is alive, e.g. because it is visible externally.
9496
bool isAnchorFunction(SILFunction *F) {
9597

@@ -148,6 +150,11 @@ class FunctionLivenessComputation {
148150
/// Marks all contained functions and witness tables of a witness table as
149151
/// alive.
150152
void makeAlive(SILWitnessTable *WT) {
153+
if (isAvailableExternally(WT->getLinkage()) &&
154+
!keepExternalWitnessTablesAlive) {
155+
return;
156+
}
157+
151158
LLVM_DEBUG(llvm::dbgs() << " scan witness table " << WT->getName()
152159
<< '\n');
153160

@@ -393,8 +400,10 @@ class FunctionLivenessComputation {
393400
}
394401

395402
public:
396-
FunctionLivenessComputation(SILModule *module) :
397-
Module(module) {}
403+
FunctionLivenessComputation(SILModule *module,
404+
bool keepExternalWitnessTablesAlive) :
405+
Module(module),
406+
keepExternalWitnessTablesAlive(keepExternalWitnessTablesAlive) {}
398407

399408
/// The main entry point of the optimization.
400409
bool findAliveFunctions() {
@@ -635,8 +644,8 @@ class DeadFunctionElimination : FunctionLivenessComputation {
635644
}
636645

637646
public:
638-
DeadFunctionElimination(SILModule *module)
639-
: FunctionLivenessComputation(module) {}
647+
DeadFunctionElimination(SILModule *module, bool keepExternalWitnessTablesAlive)
648+
: FunctionLivenessComputation(module, keepExternalWitnessTablesAlive) {}
640649

641650
/// The main entry point of the optimization.
642651
void eliminateFunctions(SILModuleTransform *DFEPass) {
@@ -693,6 +702,13 @@ class DeadFunctionElimination : FunctionLivenessComputation {
693702
namespace {
694703

695704
class SILDeadFuncElimination : public SILModuleTransform {
705+
706+
private:
707+
bool isLateDFE;
708+
709+
public:
710+
SILDeadFuncElimination(bool isLateDFE) : isLateDFE(isLateDFE) { }
711+
696712
void run() override {
697713
LLVM_DEBUG(llvm::dbgs() << "Running DeadFuncElimination\n");
698714

@@ -703,15 +719,20 @@ class SILDeadFuncElimination : public SILModuleTransform {
703719
// can eliminate such functions.
704720
getModule()->invalidateSILLoaderCaches();
705721

706-
DeadFunctionElimination deadFunctionElimination(getModule());
722+
DeadFunctionElimination deadFunctionElimination(getModule(),
723+
/*keepExternalWitnessTablesAlive*/ !isLateDFE);
707724
deadFunctionElimination.eliminateFunctions(this);
708725
}
709726
};
710727

711728
} // end anonymous namespace
712729

713730
SILTransform *swift::createDeadFunctionElimination() {
714-
return new SILDeadFuncElimination();
731+
return new SILDeadFuncElimination(/*isLateDFE*/ false);
732+
}
733+
734+
SILTransform *swift::createLateDeadFunctionElimination() {
735+
return new SILDeadFuncElimination(/*isLateDFE*/ true);
715736
}
716737

717738
void swift::performSILDeadFunctionElimination(SILModule *M) {

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,9 @@ static void addLateLoopOptPassPipeline(SILPassPipelinePlan &P) {
522522
P.startPipeline("LateLoopOpt");
523523

524524
// Delete dead code and drop the bodies of shared functions.
525-
P.addDeadFunctionElimination();
525+
// Also, remove externally available witness tables. They are not needed
526+
// anymore after the last devirtualizer run.
527+
P.addLateDeadFunctionElimination();
526528

527529
// Perform the final lowering transformations.
528530
P.addCodeSinking();

test/SIL/Serialization/init_existential_inst_deserializes_witness_tables.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -sil-inline-threshold 0 %S/Inputs/init_existential_inst_deserializes_witness_tables_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -O
3-
// RUN: %target-swift-frontend -I %t -O %s -emit-sil -o - | %FileCheck %s
3+
// RUN: %target-swift-frontend -I %t -O %s -Xllvm -sil-disable-pass=late-deadfuncelim -emit-sil -o - | %FileCheck %s
44

55
// CHECK: sil_witness_table public_external X: P module Swift {
66

test/SILOptimizer/devirt_opaque_witness.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/opaque_conformance.swiftmodule -primary-file %S/Inputs/opaque_conformance.swift
3-
// RUN: %target-swift-frontend -O -emit-sil -primary-file %s -I %t | %FileCheck %s
3+
// RUN: %target-swift-frontend -O -emit-sil -primary-file %s -I %t -Xllvm -sil-disable-pass=late-deadfuncelim | %FileCheck %s
44

55
import opaque_conformance
66

test/SILOptimizer/sil_witness_tables_external_witnesstable.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module %S/Inputs/sil_witness_tables_external_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -module-link-name swiftCore
3-
// RUN: %target-swift-frontend -O -I %t %s -emit-sil | %FileCheck %s
3+
// RUN: %target-swift-frontend -O -I %t %s -Xllvm -sil-disable-pass=late-deadfuncelim -emit-sil | %FileCheck %s
4+
// RUN: %target-swift-frontend -O -I %t %s -emit-sil | %FileCheck -check-prefix=CHECK-DFE %s
45

56
import Swift
67

78
// Make sure the specializer produces an external witness table.
89
//
910
// CHECK: sil_witness_table public_external X: P module Swift {
1011

12+
// Also check that late dead-function-elimination is removing externally
13+
// available witness tables.
14+
//
15+
// CHECK-DFE-NOT: sil_witness_table public_external
16+
1117
func doSomething<T : P>(_ t : T) -> Y {
1218
return t.doSomething()
1319
}

0 commit comments

Comments
 (0)