Skip to content

Commit 27e1220

Browse files
committed
CMO: fix handling of static globals with function references
Referenced functions within the initializer of a SILGlobalVariable must be handled like referenced functions in other functions. Fixes an assert crash when compiling with -cross-module-optimization
1 parent 737962e commit 27e1220

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

lib/SILOptimizer/IPO/CrossModuleSerializationSetup.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,14 @@ class CrossModuleSerializationSetup {
6363

6464
bool canSerialize(SILInstruction *inst, bool lookIntoThunks);
6565

66+
bool canSerialize(SILGlobalVariable *global);
67+
6668
bool canSerialize(SILType type);
6769

6870
void setUpForSerialization(SILFunction *F);
6971

72+
void setUpForSerialization(SILGlobalVariable *global);
73+
7074
void prepareInstructionForSerialization(SILInstruction *inst);
7175

7276
void handleReferencedFunction(SILFunction *F);
@@ -241,9 +245,6 @@ static void makeFunctionUsableFromInline(SILFunction *F) {
241245
/// referenced function onto the worklist.
242246
void CrossModuleSerializationSetup::
243247
prepareInstructionForSerialization(SILInstruction *inst) {
244-
// Make all types of the instruction usable from inline.
245-
InstructionVisitor::visitInst(inst, *this);
246-
247248
// Put callees onto the worklist if they should be serialized as well.
248249
if (auto *FRI = dyn_cast<FunctionRefBaseInst>(inst)) {
249250
SILFunction *callee = FRI->getReferencedFunctionOrNull();
@@ -252,8 +253,11 @@ prepareInstructionForSerialization(SILInstruction *inst) {
252253
return;
253254
}
254255
if (auto *GAI = dyn_cast<GlobalAddrInst>(inst)) {
255-
GAI->getReferencedGlobal()->setSerialized(IsSerialized);
256-
GAI->getReferencedGlobal()->setLinkage(SILLinkage::Public);
256+
SILGlobalVariable *gl = GAI->getReferencedGlobal();
257+
if (canSerialize(gl)) {
258+
setUpForSerialization(gl);
259+
}
260+
gl->setLinkage(SILLinkage::Public);
257261
return;
258262
}
259263
if (auto *MI = dyn_cast<MethodInst>(inst)) {
@@ -353,6 +357,15 @@ bool CrossModuleSerializationSetup::canSerialize(SILInstruction *inst,
353357
return true;
354358
}
355359

360+
bool CrossModuleSerializationSetup::canSerialize(SILGlobalVariable *global) {
361+
for (const SILInstruction &initInst : *global) {
362+
if (!canSerialize(const_cast<SILInstruction *>(&initInst),
363+
/*lookIntoThunks*/ true))
364+
return false;
365+
}
366+
return true;
367+
}
368+
356369
bool CrossModuleSerializationSetup::canSerialize(SILType type) {
357370
auto iter = typesChecked.find(type);
358371
if (iter != typesChecked.end())
@@ -421,6 +434,9 @@ void CrossModuleSerializationSetup::setUpForSerialization(SILFunction *F) {
421434
// for serialization.
422435
for (SILBasicBlock &block : *F) {
423436
for (SILInstruction &inst : block) {
437+
// Make all types of the instruction usable from inline.
438+
InstructionVisitor::visitInst(&inst, *this);
439+
424440
prepareInstructionForSerialization(&inst);
425441
}
426442
}
@@ -439,6 +455,14 @@ void CrossModuleSerializationSetup::setUpForSerialization(SILFunction *F) {
439455
}
440456
}
441457

458+
void CrossModuleSerializationSetup::
459+
setUpForSerialization(SILGlobalVariable *global) {
460+
for (const SILInstruction &initInst : *global) {
461+
prepareInstructionForSerialization(const_cast<SILInstruction *>(&initInst));
462+
}
463+
global->setSerialized(IsSerialized);
464+
}
465+
442466
/// Select functions in the module which should be serialized.
443467
void CrossModuleSerializationSetup::scanModule() {
444468

test/SILOptimizer/Inputs/cross-module/cross-module.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,8 @@ public func callCImplementationOnly<T>(_ t: T) -> Int {
285285

286286

287287
public let globalLet = 529387
288+
289+
public struct StructWithClosure {
290+
public static let c = { (x: Int) -> Int in return x }
291+
}
292+

test/SILOptimizer/cross-module-optimization.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ func testGlobal() {
140140
// CHECK-OUTPUT: 529387
141141
// CHECK-SIL2: integer_literal $Builtin.Int{{[0-9]+}}, 529387
142142
print(globalLet)
143+
// CHECK-OUTPUT: 41
144+
print(StructWithClosure.c(41))
143145
// CHECK-SIL2: } // end sil function '$s4Main10testGlobalyyF'
144146
}
145147

0 commit comments

Comments
 (0)