Skip to content

Commit 01865c0

Browse files
authored
Merge pull request #39018 from eeckstein/fix-cmo-5.5
[5.5] Fix two cross-module-optimization bugs
2 parents d907986 + ca68185 commit 01865c0

File tree

13 files changed

+65
-19
lines changed

13 files changed

+65
-19
lines changed

include/swift/AST/Module.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,9 +645,10 @@ class ModuleDecl : public DeclContext, public TypeDecl {
645645
/// This assumes that \p module was imported.
646646
bool isImportedImplementationOnly(const ModuleDecl *module) const;
647647

648-
/// Returns true if a function, which is using \p nominal, can be serialized
649-
/// by cross-module-optimization.
650-
bool canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const;
648+
/// Returns true if decl context or its content can be serialized by
649+
/// cross-module-optimization.
650+
/// The \p ctxt can e.g. be a NominalType or the context of a function.
651+
bool canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const;
651652

652653
/// Finds all top-level decls of this module.
653654
///

lib/AST/Module.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,14 +2179,15 @@ bool ModuleDecl::isImportedImplementationOnly(const ModuleDecl *module) const {
21792179
}
21802180

21812181
bool ModuleDecl::
2182-
canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const {
2183-
ModuleDecl *moduleOfNominal = nominal->getParentModule();
2182+
canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const {
2183+
ModuleDecl *moduleOfCtxt = ctxt->getParentModule();
21842184

2185-
// If the nominal is defined in the same module, it's fine.
2186-
if (moduleOfNominal == this)
2185+
// If the context defined in the same module - or is the same module, it's
2186+
// fine.
2187+
if (moduleOfCtxt == this)
21872188
return true;
21882189

2189-
// See if nominal is imported in a "regular" way, i.e. not with
2190+
// See if context is imported in a "regular" way, i.e. not with
21902191
// @_implementationOnly or @_spi.
21912192
ModuleDecl::ImportFilter filter = {
21922193
ModuleDecl::ImportFilterKind::Exported,
@@ -2196,7 +2197,7 @@ canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const {
21962197

21972198
auto &imports = getASTContext().getImportCache();
21982199
for (auto &desc : results) {
2199-
if (imports.isImportedBy(moduleOfNominal, desc.importedModule))
2200+
if (imports.isImportedBy(moduleOfCtxt, desc.importedModule))
22002201
return true;
22012202
}
22022203
return false;

lib/SILOptimizer/IPO/CrossModuleSerializationSetup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ bool CrossModuleSerializationSetup::canUseFromInline(SILFunction *func,
386386
if (!func)
387387
return false;
388388

389+
if (DeclContext *funcCtxt = func->getDeclContext()) {
390+
if (!M.getSwiftModule()->canBeUsedForCrossModuleOptimization(funcCtxt))
391+
return false;
392+
}
393+
389394
switch (func->getLinkage()) {
390395
case SILLinkage::PublicNonABI:
391396
return func->isSerialized() != IsNotSerialized;

lib/Serialization/DeserializeSIL.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,14 @@ SILFunction *SILDeserializer::getFuncForReference(StringRef name,
406406
// SIL.
407407
SourceLoc sourceLoc;
408408
SILSerializationFunctionBuilder builder(SILMod);
409-
return builder.createDeclaration(name, type, RegularLocation(sourceLoc));
409+
fn = builder.createDeclaration(name, type,
410+
RegularLocation(sourceLoc));
411+
// The function is not really de-serialized, but it's important to call
412+
// `didDeserialize` on every new function. Otherwise some Analysis might miss
413+
// `notifyAddedOrModifiedFunction` notifications.
414+
if (Callback)
415+
Callback->didDeserialize(MF->getAssociatedModule(), fn);
416+
return fn;
410417
}
411418

412419
/// Helper function to find a SILFunction, given its name and type.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
#include "c-module.h"
3+
4+
long privateCFunc() {
5+
return 123;
6+
}
7+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
long privateCFunc();
3+

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Submodule
22
@_implementationOnly import PrivateSubmodule
3+
@_implementationOnly import PrivateCModule
34

45
private enum PE<T> {
56
case A
@@ -268,11 +269,19 @@ public func callUnrelated<T>(_ t: T) -> T {
268269
return t
269270
}
270271

271-
public func callImplementationOnly<T>(_ t: T) -> T {
272+
public func callImplementationOnlyType<T>(_ t: T) -> T {
272273
let p = PrivateStr(i: 27)
273274
print(p.test())
274275
return t
275276
}
276277

278+
public func callImplementationOnlyFunc<T>(_ t: T) -> Int {
279+
return privateFunc()
280+
}
281+
282+
public func callCImplementationOnly<T>(_ t: T) -> Int {
283+
return Int(privateCFunc())
284+
}
285+
277286

278287
public let globalLet = 529387

test/SILOptimizer/Inputs/cross-private-submodule.swift renamed to test/SILOptimizer/Inputs/cross-module/cross-private-submodule.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ public struct PrivateStr {
1212
}
1313
}
1414

15+
public func privateFunc() -> Int {
16+
return 40
17+
}

0 commit comments

Comments
 (0)