Skip to content

Commit 199e76d

Browse files
committed
Fixes for a lookup of functions by name
Among other things it fixes a bug in the function signature optimization where it would use an already existing mangled name for a different function
1 parent e4af4e1 commit 199e76d

File tree

11 files changed

+66
-31
lines changed

11 files changed

+66
-31
lines changed

include/swift/SIL/SILModule.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,19 @@ class SILModule {
430430
bool linkFunction(StringRef Name,
431431
LinkingMode LinkAll = LinkingMode::LinkNormal);
432432

433-
/// Check if a given function exists in the module,
434-
/// i.e. it can be linked by linkFunction.
433+
/// Check if a given function exists in any of the modules with a
434+
/// required linkage, i.e. it can be linked by linkFunction.
435+
///
436+
/// If linkage parameter is none, then the linkage of the function
437+
/// with a given name does not matter.
435438
///
436439
/// \return null if this module has no such function. Otherwise
437440
/// the declaration of a function.
438-
SILFunction *hasFunction(StringRef Name, SILLinkage Linkage);
441+
SILFunction *findFunction(StringRef Name, Optional<SILLinkage> Linkage);
442+
443+
/// Check if a given function exists in the module,
444+
/// i.e. it can be linked by linkFunction.
445+
bool hasFunction(StringRef Name);
439446

440447
/// Link in all Witness Tables in the module.
441448
void linkAllWitnessTables();

include/swift/Serialization/SerializedSILLoader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ class SerializedSILLoader {
9292
SILFunction *lookupSILFunction(SILFunction *Callee);
9393
SILFunction *
9494
lookupSILFunction(StringRef Name, bool declarationOnly = false,
95-
SILLinkage linkage = SILLinkage::Private);
96-
bool hasSILFunction(StringRef Name, SILLinkage linkage = SILLinkage::Private);
95+
Optional<SILLinkage> linkage = None);
96+
bool hasSILFunction(StringRef Name, Optional<SILLinkage> linkage = None);
9797
SILVTable *lookupVTable(Identifier Name);
9898
SILVTable *lookupVTable(const ClassDecl *C) {
9999
return lookupVTable(C->getName());

lib/SIL/Linker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ SILFunction *SILLinkerVisitor::lookupFunction(StringRef Name,
117117
}
118118

119119
/// Process Decl, recursively deserializing any thing Decl may reference.
120-
bool SILLinkerVisitor::hasFunction(StringRef Name, SILLinkage Linkage) {
120+
bool SILLinkerVisitor::hasFunction(StringRef Name,
121+
Optional<SILLinkage> Linkage) {
121122
return Loader->hasSILFunction(Name, Linkage);
122123
}
123124

lib/SIL/Linker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class SILLinkerVisitor : public SILInstructionVisitor<SILLinkerVisitor, bool> {
6060

6161
/// Process Name, try to check if there is a declaration of a function
6262
/// with this Name.
63-
bool hasFunction(StringRef Name, SILLinkage Linkage);
63+
bool hasFunction(StringRef Name, Optional<SILLinkage> Linkage = None);
6464

6565
/// Deserialize the VTable mapped to C if it exists and all SIL the VTable
6666
/// transitively references.

lib/SIL/SILModule.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -499,23 +499,39 @@ bool SILModule::linkFunction(StringRef Name, SILModule::LinkingMode Mode) {
499499
return SILLinkerVisitor(*this, getSILLoader(), Mode).processFunction(Name);
500500
}
501501

502-
SILFunction *SILModule::hasFunction(StringRef Name, SILLinkage Linkage) {
503-
assert((Linkage == SILLinkage::Public ||
504-
Linkage == SILLinkage::PublicExternal) &&
505-
"Only a lookup of public functions is supported currently");
502+
/// Check if a given SIL linkage matches the required linkage.
503+
/// If the required linkage is Private, then anything matches it.
504+
static bool isMatchingLinkage(SILLinkage ActualLinkage,
505+
Optional<SILLinkage> Linkage) {
506+
if (!Linkage)
507+
return true;
508+
return ActualLinkage == Linkage;
509+
}
510+
511+
bool SILModule::hasFunction(StringRef Name) {
512+
if (lookUpFunction(Name))
513+
return true;
514+
SILLinkerVisitor Visitor(*this, getSILLoader(),
515+
SILModule::LinkingMode::LinkNormal);
516+
return Visitor.hasFunction(Name);
517+
}
518+
519+
SILFunction *SILModule::findFunction(StringRef Name,
520+
Optional<SILLinkage> Linkage) {
506521

507522
SILFunction *F = nullptr;
523+
SILLinkage RequiredLinkage = Linkage ? *Linkage : SILLinkage::Private;
508524

509525
// First, check if there is a function with a required name in the
510526
// current module.
511527
SILFunction *CurF = lookUpFunction(Name);
512528

513529
// Nothing to do if the current module has a required function
514530
// with a proper linkage already.
515-
if (CurF && CurF->getLinkage() == Linkage) {
531+
if (CurF && isMatchingLinkage(CurF->getLinkage(), Linkage)) {
516532
F = CurF;
517533
} else {
518-
assert((!CurF || CurF->getLinkage() != Linkage) &&
534+
assert((!CurF || CurF->getLinkage() != RequiredLinkage) &&
519535
"hasFunction should be only called for functions that are not "
520536
"contained in the SILModule yet or do not have a required linkage");
521537
}
@@ -528,7 +544,7 @@ SILFunction *SILModule::hasFunction(StringRef Name, SILLinkage Linkage) {
528544
// name is present in the current module.
529545
// This is done to reduce the amount of IO from the
530546
// swift module file.
531-
if (!Visitor.hasFunction(Name, Linkage))
547+
if (!Visitor.hasFunction(Name, RequiredLinkage))
532548
return nullptr;
533549
// The function in the current module will be changed.
534550
F = CurF;
@@ -538,13 +554,14 @@ SILFunction *SILModule::hasFunction(StringRef Name, SILLinkage Linkage) {
538554
// or if it is known to exist, perform a lookup.
539555
if (!F) {
540556
// Try to load the function from other modules.
541-
F = Visitor.lookupFunction(Name, Linkage);
557+
F = Visitor.lookupFunction(Name, RequiredLinkage);
542558
// Bail if nothing was found and we are not sure if
543559
// this function exists elsewhere.
544560
if (!F)
545561
return nullptr;
546562
assert(F && "SILFunction should be present in one of the modules");
547-
assert(F->getLinkage() == Linkage && "SILFunction has a wrong linkage");
563+
assert(isMatchingLinkage(F->getLinkage(), Linkage) &&
564+
"SILFunction has a wrong linkage");
548565
}
549566
}
550567

@@ -556,9 +573,19 @@ SILFunction *SILModule::hasFunction(StringRef Name, SILLinkage Linkage) {
556573
SILOptions::SILOptMode::Optimize) {
557574
F->convertToDeclaration();
558575
}
559-
if (F->isExternalDeclaration())
576+
if (F->isExternalDeclaration()) {
560577
F->setFragile(IsFragile_t::IsNotFragile);
561-
F->setLinkage(Linkage);
578+
if (isAvailableExternally(F->getLinkage()) &&
579+
!hasPublicVisibility(F->getLinkage()) && !Linkage) {
580+
// We were just asked if a given function exists anywhere.
581+
// It is not going to be used by the current module.
582+
// Since external non-public function declarations should not
583+
// exist, strip the "external" part from the linkage.
584+
F->setLinkage(stripExternalFromLinkage(F->getLinkage()));
585+
}
586+
}
587+
if (Linkage)
588+
F->setLinkage(RequiredLinkage);
562589
return F;
563590
}
564591

lib/SILOptimizer/IPO/EagerSpecializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ class EagerDispatch {
287287
substConv(ReInfo.getSubstitutedType(), GenericFunc->getModule()),
288288
Builder(*GenericFunc), Loc(GenericFunc->getLocation()) {
289289
Builder.setCurrentDebugScope(GenericFunc->getDebugScope());
290-
IsClassF = Builder.getModule().hasFunction(
290+
IsClassF = Builder.getModule().findFunction(
291291
"_swift_isClassOrObjCExistentialType", SILLinkage::PublicExternal);
292292
assert(IsClassF);
293293
}

lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static SILInstruction *findOnlyApply(SILFunction *F) {
9393
///
9494
/// TODO: we should teach the demangler to understand this suffix.
9595
static std::string getUniqueName(std::string Name, SILModule &M) {
96-
if (!M.lookUpFunction(Name))
96+
if (!M.hasFunction(Name))
9797
return Name;
9898
return getUniqueName(Name + "_unique_suffix", M);
9999
}
@@ -372,7 +372,7 @@ std::string FunctionSignatureTransform::createOptimizedSILFunctionName() {
372372
do {
373373
New = NewFM.mangle(UniqueID);
374374
++UniqueID;
375-
} while (M.lookUpFunction(New));
375+
} while (M.hasFunction(New));
376376

377377
return NewMangling::selectMangling(Old, New);
378378
}

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ static SILFunction *lookupExistingSpecialization(SILModule &M,
11801180
// Only check that this function exists, but don't read
11811181
// its body. It can save some compile-time.
11821182
if (isWhitelistedSpecialization(FunctionName))
1183-
return M.hasFunction(FunctionName, SILLinkage::PublicExternal);
1183+
return M.findFunction(FunctionName, SILLinkage::PublicExternal);
11841184

11851185
return nullptr;
11861186
}

lib/Serialization/DeserializeSIL.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ SILFunction *SILDeserializer::lookupSILFunction(SILFunction *InFunc) {
19931993
/// This function is modeled after readSILFunction. But it does not
19941994
/// create a SILFunction object.
19951995
bool SILDeserializer::hasSILFunction(StringRef Name,
1996-
SILLinkage Linkage) {
1996+
Optional<SILLinkage> Linkage) {
19971997
if (!FuncTable)
19981998
return false;
19991999
auto iter = FuncTable->find(Name);
@@ -2006,8 +2006,7 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
20062006
auto &cacheEntry = Funcs[FID-1];
20072007
if (cacheEntry.isFullyDeserialized() ||
20082008
(cacheEntry.isDeserialized()))
2009-
return cacheEntry.get()->getLinkage() == Linkage ||
2010-
Linkage == SILLinkage::Private;
2009+
return !Linkage || cacheEntry.get()->getLinkage() == *Linkage;
20112010

20122011
BCOffsetRAII restoreOffset(SILCursor);
20132012
SILCursor.JumpToBit(cacheEntry.getOffset());
@@ -2046,7 +2045,7 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
20462045
}
20472046

20482047
// Bail if it is not a required linkage.
2049-
if (linkage.getValue() != Linkage && Linkage != SILLinkage::Private)
2048+
if (Linkage && linkage.getValue() != *Linkage)
20502049
return false;
20512050

20522051
DEBUG(llvm::dbgs() << "Found SIL Function: " << Name << "\n");

lib/Serialization/DeserializeSIL.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ namespace swift {
118118
SILFunction *lookupSILFunction(SILFunction *InFunc);
119119
SILFunction *lookupSILFunction(StringRef Name,
120120
bool declarationOnly = false);
121-
bool hasSILFunction(StringRef Name, SILLinkage Linkage);
121+
bool hasSILFunction(StringRef Name, Optional<SILLinkage> Linkage = None);
122122
SILVTable *lookupVTable(Identifier Name);
123123
SILWitnessTable *lookupWitnessTable(SILWitnessTable *wt);
124124
SILDefaultWitnessTable *

lib/Serialization/SerializedSILLoader.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ SILFunction *SerializedSILLoader::lookupSILFunction(SILFunction *Callee) {
5959

6060
SILFunction *SerializedSILLoader::lookupSILFunction(StringRef Name,
6161
bool declarationOnly,
62-
SILLinkage Linkage) {
62+
Optional<SILLinkage> Linkage) {
6363
// It is possible that one module has a declaration of a SILFunction, while
6464
// another has the full definition.
6565
SILFunction *retVal = nullptr;
6666
for (auto &Des : LoadedSILSections) {
6767
if (auto Func = Des->lookupSILFunction(Name, declarationOnly)) {
6868
DEBUG(llvm::dbgs() << "Deserialized " << Func->getName() << " from "
6969
<< Des->getModuleIdentifier().str() << "\n");
70-
if (Linkage != SILLinkage::Private) {
70+
if (Linkage) {
7171
// This is not the linkage we are looking for.
72-
if (Func->getLinkage() != Linkage) {
72+
if (Func->getLinkage() != *Linkage) {
7373
DEBUG(llvm::dbgs()
7474
<< "Wrong linkage for Function: " << Func->getName() << " : "
7575
<< (int)Func->getLinkage() << "\n");
@@ -86,7 +86,8 @@ SILFunction *SerializedSILLoader::lookupSILFunction(StringRef Name,
8686
return retVal;
8787
}
8888

89-
bool SerializedSILLoader::hasSILFunction(StringRef Name, SILLinkage Linkage) {
89+
bool SerializedSILLoader::hasSILFunction(StringRef Name,
90+
Optional<SILLinkage> Linkage) {
9091
// It is possible that one module has a declaration of a SILFunction, while
9192
// another has the full definition.
9293
SILFunction *retVal = nullptr;

0 commit comments

Comments
 (0)