Skip to content

Commit f03956b

Browse files
committed
Cross-module-optimization: Serialize immediately after CrossModuleSerializationSetup
Otherwise it can happen that e.g. specialization runs between CrossModuleSerializationSetup and serialization, resulting that an inlinable function references a shared function (which doesn't have a public linkage). The solution is to move serialization right after CrossModuleSerializationSetup. But only do that if cross-module-optimization is enabled (it would be a disruptive change to move serialization in general).
1 parent a6168a9 commit f03956b

File tree

5 files changed

+43
-2
lines changed

5 files changed

+43
-2
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ PASS(SimplifyUnreachableContainingBlocks, "simplify-unreachable-containing-block
311311
"Utility pass. Removes all non-term insts from blocks with unreachable terms")
312312
PASS(SerializeSILPass, "serialize-sil",
313313
"Utility pass. Serializes the current SILModule")
314+
PASS(CMOSerializeSILPass, "cmo-serialize-sil",
315+
"Utility pass. Serializes the current SILModule for cross-module-optimization")
314316
PASS(NonInlinableFunctionSkippingChecker, "check-non-inlinable-function-skipping",
315317
"Utility pass to ensure -experimental-skip-non-inlinable-function-bodies "
316318
"skips everything it should")

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@ static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
413413
P.addOutliner();
414414

415415
P.addCrossModuleSerializationSetup();
416+
417+
// In case of cross-module-optimization, we need to serialize right after
418+
// CrossModuleSerializationSetup. Eventually we want to serialize early
419+
// anyway, but for now keep the SerializeSILPass at the later stage of the
420+
// pipeline in case cross-module-optimization is not enabled.
421+
P.addCMOSerializeSILPass();
416422
}
417423

418424
static void addHighLevelEarlyLoopOptPipeline(SILPassPipelinePlan &P) {

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ void updateOpaqueArchetypes(SILFunction &F) {
391391
/// A utility pass to serialize a SILModule at any place inside the optimization
392392
/// pipeline.
393393
class SerializeSILPass : public SILModuleTransform {
394+
395+
bool onlyForCrossModuleOptimization;
396+
394397
/// Removes [serialized] from all functions. This allows for more
395398
/// optimizations and for a better dead function elimination.
396399
void removeSerializedFlagFromAllFunctions(SILModule &M) {
@@ -422,12 +425,19 @@ class SerializeSILPass : public SILModuleTransform {
422425
}
423426

424427
public:
425-
SerializeSILPass() {}
428+
SerializeSILPass(bool onlyForCrossModuleOptimization)
429+
: onlyForCrossModuleOptimization(onlyForCrossModuleOptimization)
430+
{ }
431+
426432
void run() override {
427433
auto &M = *getModule();
428434
// Nothing to do if the module was serialized already.
429435
if (M.isSerialized())
430436
return;
437+
438+
if (onlyForCrossModuleOptimization &&
439+
!M.getOptions().CrossModuleOptimization)
440+
return;
431441

432442
// Mark all reachable functions as "anchors" so that they are not
433443
// removed later by the dead function elimination pass. This
@@ -449,5 +459,9 @@ class SerializeSILPass : public SILModuleTransform {
449459
};
450460

451461
SILTransform *swift::createSerializeSILPass() {
452-
return new SerializeSILPass();
462+
return new SerializeSILPass(/* onlyForCrossModuleOptimization */ false);
463+
}
464+
465+
SILTransform *swift::createCMOSerializeSILPass() {
466+
return new SerializeSILPass(/* onlyForCrossModuleOptimization */ true);
453467
}

test/SILOptimizer/Inputs/cross-module.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,14 @@ public func useClassKeypath<T>(_ t: T) -> Int {
236236
return c[keyPath: getClassKeypath(t)]
237237
}
238238

239+
@inline(never)
240+
func unrelated<U>(_ u: U) {
241+
print(u)
242+
}
243+
244+
@inline(never)
245+
public func callUnrelated<T>(_ t: T) -> T {
246+
unrelated(43)
247+
return t
248+
}
249+

test/SILOptimizer/cross-module-optimization.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,18 @@ func testKeypath() {
113113
print(useClassKeypath(0))
114114
}
115115

116+
func testMisc() {
117+
// CHECK-OUTPUT: 43
118+
// CHECK-OUTPUT: 42
119+
// CHECK-SIL-DAG: sil shared {{.*}} @$s4Test13callUnrelatedyxxlFSi_Tg5
120+
print(callUnrelated(42))
121+
}
122+
116123
testNestedTypes()
117124
testClass()
118125
testError()
119126
testProtocolsAndClasses()
120127
testSubModule()
121128
testClosures()
122129
testKeypath()
130+
testMisc()

0 commit comments

Comments
 (0)