Skip to content

Commit 7a5467f

Browse files
authored
Merge pull request swiftlang#15956 from slavapestov/reapply-mandatory-sil-linker-pass
Re-apply "Mandatory linking pass"
2 parents 095623b + 1b79b74 commit 7a5467f

File tree

12 files changed

+64
-39
lines changed

12 files changed

+64
-39
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ PASS(LateReleaseHoisting, "late-release-hoisting",
226226
"Late SIL release Hoisting Preserving Epilogues")
227227
IRGEN_PASS(LoadableByAddress, "loadable-address",
228228
"SIL Large Loadable type by-address lowering.")
229+
PASS(MandatorySILLinker, "mandatory-linker",
230+
"Deserialize all referenced SIL functions that are shared or transparent")
231+
PASS(PerformanceSILLinker, "performance-linker",
232+
"Deserialize all referenced SIL functions")
229233
PASS(RemovePins, "remove-pins",
230234
"Remove SIL pin/unpin pairs")
231235
PASS(TempRValueOpt, "temp-rvalue-opt",
@@ -238,8 +242,6 @@ PASS(SILCombine, "sil-combine",
238242
"Combine SIL Instructions via Peephole Optimization")
239243
PASS(SILDebugInfoGenerator, "sil-debuginfo-gen",
240244
"Generate Debug Information with Source Locations into Textual SIL")
241-
PASS(SILLinker, "linker",
242-
"Link all SIL Referenced within the Module via Deserialization")
243245
PASS(SROA, "sroa",
244246
"Scalar Replacement of Aggregate Stack Objects")
245247
PASS(SROABBArgs, "sroa-bb-args",

lib/SIL/Linker.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,21 @@ void SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F) {
5555
if (!F->isExternalDeclaration())
5656
return;
5757

58-
if (isLinkAll() || hasSharedVisibility(F->getLinkage()))
58+
// In the performance pipeline, we deserialize all reachable functions.
59+
if (isLinkAll())
60+
return addFunctionToWorklist(F);
61+
62+
// Otherwise, make sure to deserialize shared functions; we need to
63+
// emit them into the client binary since they're not available
64+
// externally.
65+
if (hasSharedVisibility(F->getLinkage()))
66+
return addFunctionToWorklist(F);
67+
68+
// Functions with PublicNonABI linkage are deserialized as having
69+
// HiddenExternal linkage when they are declarations, then they
70+
// become SharedExternal after the body has been deserialized.
71+
// So try deserializing HiddenExternal functions too.
72+
if (F->getLinkage() == SILLinkage::HiddenExternal)
5973
return addFunctionToWorklist(F);
6074
}
6175

lib/SIL/SILVerifier.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,14 +1418,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
14181418

14191419
SILFunction *RefF = FRI->getReferencedFunction();
14201420

1421-
// A direct reference to a shared_external declaration is an error; we
1422-
// should have deserialized a body.
1423-
if (RefF->isExternalDeclaration()) {
1424-
require(SingleFunction ||
1425-
!hasSharedVisibility(RefF->getLinkage()) ||
1426-
RefF->hasForeignBody(),
1427-
"external declarations of SILFunctions with shared visibility is "
1428-
"not allowed");
1421+
// In canonical SIL, direct reference to a shared_external declaration
1422+
// is an error; we should have deserialized a body. In raw SIL, we may
1423+
// not have deserialized the body yet.
1424+
if (F.getModule().getStage() >= SILStage::Canonical) {
1425+
if (RefF->isExternalDeclaration()) {
1426+
require(SingleFunction ||
1427+
!hasSharedVisibility(RefF->getLinkage()) ||
1428+
RefF->hasForeignBody(),
1429+
"external declarations of SILFunctions with shared visibility is "
1430+
"not allowed");
1431+
}
14291432
}
14301433

14311434
// A direct reference to a non-public or shared but not fragile function

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -404,17 +404,22 @@ static SILFunction *getCalleeFunction(
404404
return nullptr;
405405
}
406406

407-
// If CalleeFunction is a declaration, see if we can load it. If we fail to
408-
// load it, bail.
409-
if (CalleeFunction->empty()
410-
&& !AI.getModule().linkFunction(CalleeFunction, Mode))
411-
return nullptr;
412-
413407
// If the CalleeFunction is a not-transparent definition, we can not process
414408
// it.
415409
if (CalleeFunction->isTransparent() == IsNotTransparent)
416410
return nullptr;
417411

412+
// If CalleeFunction is a declaration, see if we can load it.
413+
if (CalleeFunction->empty()) {
414+
// FIXME: Remove 'Mode'
415+
if (Mode != SILOptions::LinkingMode::LinkNone)
416+
AI.getModule().loadFunction(CalleeFunction);
417+
}
418+
419+
// If we fail to load it, bail.
420+
if (CalleeFunction->empty())
421+
return nullptr;
422+
418423
if (F->isSerialized() &&
419424
!CalleeFunction->hasValidLinkageForFragileInline()) {
420425
if (!CalleeFunction->hasValidLinkageForFragileRef()) {
@@ -653,15 +658,6 @@ class MandatoryInlining : public SILModuleTransform {
653658
SetFactory, SetFactory.getEmptySet(), CHA);
654659
}
655660

656-
// Make sure that we de-serialize all transparent functions,
657-
// even if we didn't inline them for some reason.
658-
// Transparent functions are not available externally, so we
659-
// have to generate code for them.
660-
for (auto &F : *M) {
661-
if (F.isTransparent())
662-
M->linkFunction(&F, Mode);
663-
}
664-
665661
if (!ShouldCleanup)
666662
return;
667663

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ static void addMandatoryOptPipeline(SILPassPipelinePlan &P,
9090
P.addDefiniteInitialization();
9191
P.addOwnershipModelEliminator();
9292
P.addMandatoryInlining();
93+
P.addMandatorySILLinker();
9394
P.addPredictableMemoryOptimizations();
9495

9596
// Diagnostic ConstantPropagation must be rerun on deserialized functions
@@ -314,7 +315,7 @@ void addSSAPasses(SILPassPipelinePlan &P, OptimizationLevelKind OpLevel) {
314315

315316
static void addPerfDebugSerializationPipeline(SILPassPipelinePlan &P) {
316317
P.startPipeline("Performance Debug Serialization");
317-
P.addSILLinker();
318+
P.addPerformanceSILLinker();
318319
}
319320

320321
static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
@@ -324,7 +325,7 @@ static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
324325
// we do not spend time optimizing them.
325326
P.addDeadFunctionElimination();
326327
// Start by cloning functions from stdlib.
327-
P.addSILLinker();
328+
P.addPerformanceSILLinker();
328329

329330
// Cleanup after SILGen: remove trivial copies to temporaries.
330331
P.addTempRValueOpt();
@@ -344,7 +345,7 @@ static void addHighLevelEarlyLoopOptPipeline(SILPassPipelinePlan &P) {
344345
static void addMidModulePassesStackPromotePassPipeline(SILPassPipelinePlan &P) {
345346
P.startPipeline("MidModulePasses+StackPromote");
346347
P.addDeadFunctionElimination();
347-
P.addSILLinker();
348+
P.addPerformanceSILLinker();
348349
P.addDeadObjectElimination();
349350
P.addGlobalPropertyOpt();
350351

lib/SILOptimizer/UtilityPasses/Link.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,26 @@ namespace {
2525
/// Copies code from the standard library into the user program to enable
2626
/// optimizations.
2727
class SILLinker : public SILModuleTransform {
28+
SILModule::LinkingMode LinkMode;
29+
30+
public:
31+
explicit SILLinker(SILModule::LinkingMode LinkMode) : LinkMode(LinkMode) {}
2832

2933
void run() override {
3034
SILModule &M = *getModule();
3135
for (auto &Fn : M)
32-
if (M.linkFunction(&Fn, SILModule::LinkingMode::LinkAll))
36+
if (M.linkFunction(&Fn, LinkMode))
3337
invalidateAnalysis(&Fn, SILAnalysis::InvalidationKind::Everything);
3438
}
3539

3640
};
3741
} // end anonymous namespace
3842

3943

40-
SILTransform *swift::createSILLinker() {
41-
return new SILLinker();
44+
SILTransform *swift::createMandatorySILLinker() {
45+
return new SILLinker(SILModule::LinkingMode::LinkNormal);
46+
}
47+
48+
SILTransform *swift::createPerformanceSILLinker() {
49+
return new SILLinker(SILModule::LinkingMode::LinkAll);
4250
}

test/SIL/Serialization/deserialize_generic.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
// RUN: %empty-directory(%t)
33
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic.swift
4-
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
4+
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-linker -I %t %s | %FileCheck %s
55

66
// Make sure that SILFunctionType with GenericSignature can match up with
77
// SILFunctionType deserialized from module.

test/SIL/Serialization/deserialize_generic_marker.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
// RUN: %empty-directory(%t)
33
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic_marker.swift
4-
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
4+
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-linker -I %t %s | %FileCheck %s
55

66
// Make sure that SILFunctionType with GenericSignature can match up with
77
// SILFunctionType deserialized from module.

test/SIL/Serialization/function_param_convention.sil

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 -parse-sil -sil-inline-threshold 0 %S/Inputs/function_param_convention_input.sil -o %t/FunctionInput.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-name FunctionInput -O
3-
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -I %t -linker %s -o - | %FileCheck %s
3+
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -I %t -performance-linker %s -o - | %FileCheck %s
44

55
import Swift
66
import FunctionInput

test/SIL/Serialization/public_non_abi.sil

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 -o %t %S/Inputs/def_public_non_abi.sil
3-
// RUN: %target-sil-opt -linker -I %t %s | %FileCheck %s
3+
// RUN: %target-sil-opt -performance-linker -I %t %s | %FileCheck %s
44

55
sil_stage raw
66

0 commit comments

Comments
 (0)