Skip to content

Commit 5b7b6ef

Browse files
authored
Merge pull request #15930 from slavapestov/mandatory-sil-linker-pass
Mandatory SIL linker pass
2 parents 1da70a0 + 8cf0869 commit 5b7b6ef

File tree

11 files changed

+53
-31
lines changed

11 files changed

+53
-31
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
@@ -58,7 +58,21 @@ bool SILLinkerVisitor::maybeAddFunctionToWorklist(SILFunction *F) {
5858
if (!F->isExternalDeclaration())
5959
return false;
6060

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

6478
return false;

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

test/SIL/Serialization/shared_function_serialization.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 %S/Inputs/shared_function_serialization_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -O
3-
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -I %t -linker -inline %s -o - | %FileCheck %s
3+
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -I %t -performance-linker -inline %s -o - | %FileCheck %s
44

55
// CHECK: sil private @top_level_code
66
// CHECK: sil public_external [serialized] @$Ss1XVABycfC{{.*}}

test/SIL/Serialization/vtable_deserialization.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ Class.firstMethod()
1919
// The other two methods should not be deserialized in the mandatory
2020
// pipeline.
2121

22-
// CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
22+
// FIXME: Temporary regression
23+
// CHECK-LABEL: sil public_external [serialized] @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
2324
// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
2425

25-
// CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
26+
// CHECK-LABEL: sil public_external [serialized] @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
2627
// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
2728

2829
// Make sure we deserialized the vtable.

0 commit comments

Comments
 (0)