Skip to content

Commit 9e9a0a0

Browse files
authored
Merge pull request #8596 from huonw/symbol-list-3
Use IRGen's LinkInfo in TBDGen.
2 parents 2240f44 + c0f1dce commit 9e9a0a0

File tree

10 files changed

+118
-81
lines changed

10 files changed

+118
-81
lines changed

include/swift/IRGen/Linking.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,25 @@
2323
#include "llvm/ADT/DenseMapInfo.h"
2424
#include "llvm/IR/GlobalValue.h"
2525

26+
namespace llvm {
27+
class Triple;
28+
}
29+
2630
namespace swift {
2731
namespace irgen {
2832
class IRGenModule;
2933

34+
/// Determine if the triple uses the DLL storage.
35+
bool useDllStorage(const llvm::Triple &triple);
36+
3037
class UniversalLinkageInfo {
3138
public:
32-
bool IsELFObject, UseDLLStorage, HasMultipleIGMs, IsWholeModule,
33-
IsWholeModuleSerialized;
39+
bool IsELFObject, UseDLLStorage, HasMultipleIGMs, IsWholeModule;
3440

3541
UniversalLinkageInfo(IRGenModule &IGM);
42+
43+
UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
44+
bool isWholeModule);
3645
};
3746

3847
/// Selector for type metadata symbol kinds.
@@ -572,8 +581,7 @@ class LinkEntity {
572581
/// Returns true if this function or global variable may be inlined into
573582
/// another module.
574583
///
575-
bool isFragile(ForDefinition_t isDefinition,
576-
bool wholeModuleSerialized) const;
584+
bool isFragile(ForDefinition_t isDefinition) const;
577585

578586
const ValueDecl *getDecl() const {
579587
assert(isDeclKind(getKind()));

include/swift/TBDGen/TBDGen.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
namespace swift {
1818
class FileUnit;
1919

20-
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols);
20+
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
21+
bool hasMultipleIRGenThreads, bool isWholeModule);
2122
} // end namespace swift
2223

2324
#endif

lib/FrontendTool/FrontendTool.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,9 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
550550
}
551551

552552
if (Action == FrontendOptions::EmitTBD) {
553-
return writeTBD(Instance->getMainModule(), opts.getSingleOutputFilename());
553+
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
554+
return writeTBD(Instance->getMainModule(), hasMultipleIRGenThreads,
555+
opts.getSingleOutputFilename());
554556
}
555557

556558
assert(Action >= FrontendOptions::EmitSILGen &&
@@ -795,10 +797,15 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
795797
}
796798

797799
if (opts.ValidateTBDAgainstIR) {
798-
bool validationError =
799-
PrimarySourceFile ? validateTBD(PrimarySourceFile, *IRModule)
800-
: validateTBD(Instance->getMainModule(), *IRModule);
801-
if (validationError)
800+
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
801+
bool error;
802+
if (PrimarySourceFile)
803+
error =
804+
validateTBD(PrimarySourceFile, *IRModule, hasMultipleIRGenThreads);
805+
else
806+
error = validateTBD(Instance->getMainModule(), *IRModule,
807+
hasMultipleIRGenThreads);
808+
if (error)
802809
return true;
803810
}
804811

lib/FrontendTool/TBD.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ static std::vector<StringRef> sortSymbols(llvm::StringSet<> &symbols) {
3838
return sorted;
3939
}
4040

41-
bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename) {
41+
bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
42+
StringRef OutputFilename) {
4243
std::error_code EC;
4344
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
4445
if (EC) {
@@ -48,7 +49,8 @@ bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename) {
4849
}
4950
llvm::StringSet<> symbols;
5051
for (auto file : M->getFiles())
51-
enumeratePublicSymbols(file, symbols);
52+
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
53+
/*isWholeModule=*/true);
5254

5355
// Ensure the order is stable.
5456
for (auto &symbol : sortSymbols(symbols)) {
@@ -103,17 +105,21 @@ static bool validateSymbolSet(DiagnosticEngine &diags,
103105
return error;
104106
}
105107

106-
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule) {
108+
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
109+
bool hasMultipleIRGenThreads) {
107110
llvm::StringSet<> symbols;
108111
for (auto file : M->getFiles())
109-
enumeratePublicSymbols(file, symbols);
112+
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
113+
/*isWholeModule=*/true);
110114

111115
return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule);
112116
}
113117

114-
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule) {
118+
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
119+
bool hasMultipleIRGenThreads) {
115120
llvm::StringSet<> symbols;
116-
enumeratePublicSymbols(file, symbols);
121+
enumeratePublicSymbols(file, symbols, hasMultipleIRGenThreads,
122+
/*isWholeModule=*/false);
117123

118124
return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
119125
symbols, IRModule);

lib/FrontendTool/TBD.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ class Module;
2020
namespace swift {
2121
class ModuleDecl;
2222
class FileUnit;
23+
class FrontendOptions;
2324

24-
bool writeTBD(ModuleDecl *M, llvm::StringRef OutputFilename);
25-
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule);
26-
bool validateTBD(FileUnit *M, llvm::Module &IRModule);
25+
bool writeTBD(ModuleDecl *M, bool hasMultipleIRGenThreads,
26+
llvm::StringRef OutputFilename);
27+
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule,
28+
bool hasMultipleIRGenThreads);
29+
bool validateTBD(FileUnit *M, llvm::Module &IRModule,
30+
bool hasMultipleIRGenThreads);
2731
}
2832

2933
#endif

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,14 +1083,8 @@ static SILLinkage getNonUniqueSILLinkage(FormalLinkage linkage,
10831083
SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
10841084
// For when `this` is a protocol conformance of some kind.
10851085
auto getLinkageAsConformance = [&] {
1086-
auto linkage = getLinkageForProtocolConformance(
1086+
return getLinkageForProtocolConformance(
10871087
getProtocolConformance()->getRootNormalConformance(), forDefinition);
1088-
1089-
// A hidden-external conformance doesn't make sense: we can't refer to
1090-
// it. Thus, the only way to end up in that situation is if the linkage is
1091-
// actually public.
1092-
return linkage == SILLinkage::HiddenExternal ? SILLinkage::PublicExternal
1093-
: linkage;
10941088
};
10951089

10961090
switch (getKind()) {
@@ -1282,8 +1276,7 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
12821276
llvm_unreachable("bad link entity kind");
12831277
}
12841278

1285-
bool LinkEntity::isFragile(ForDefinition_t isDefinition,
1286-
bool wholeModuleSerialized) const {
1279+
bool LinkEntity::isFragile(ForDefinition_t isDefinition) const {
12871280
switch (getKind()) {
12881281
case Kind::SILFunction:
12891282
return getSILFunction()->isSerialized();
@@ -1305,16 +1298,14 @@ bool LinkEntity::isFragile(ForDefinition_t isDefinition,
13051298
}
13061299
if (isProtocolConformanceKind(getKind())) {
13071300
auto conformance = getProtocolConformance();
1308-
SILLinkage L = getLinkageForProtocolConformance(
1309-
conformance->getRootNormalConformance(), isDefinition);
13101301

1311-
// We don't deserialize the fragile attribute correctly. But we know that
1312-
// if the witness table was deserialized (= available externally) and it's
1313-
// not public, it must be fragile.
1314-
if (swift::isAvailableExternally(L) && !hasPublicVisibility(L))
1315-
return true;
1302+
auto conformanceModule = conformance->getDeclContext()->getParentModule();
1303+
auto isCompletelySerialized = conformanceModule->getResilienceStrategy() ==
1304+
ResilienceStrategy::Fragile;
13161305

1317-
return wholeModuleSerialized || conformance->hasFixedLayout();
1306+
// The conformance is fragile if it is in a -sil-serialize-all module, or
1307+
// has a fully publicly determined layout.
1308+
return isCompletelySerialized || conformance->hasFixedLayout();
13181309
}
13191310
return false;
13201311
}
@@ -1437,11 +1428,10 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
14371428
// TODO: there are probably cases where we can avoid redoing the
14381429
// entire linkage computation.
14391430
UniversalLinkageInfo linkInfo(IGM);
1440-
auto linkage = getIRLinkage(
1441-
linkInfo, entity.getLinkage(ForDefinition),
1442-
entity.isFragile(ForDefinition, linkInfo.IsWholeModuleSerialized),
1443-
entity.isSILOnly(), ForDefinition,
1444-
entity.isWeakImported(IGM.getSwiftModule()));
1431+
auto linkage =
1432+
getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
1433+
entity.isFragile(ForDefinition), entity.isSILOnly(),
1434+
ForDefinition, entity.isWeakImported(IGM.getSwiftModule()));
14451435
global->setLinkage(std::get<0>(linkage));
14461436
global->setVisibility(std::get<1>(linkage));
14471437
global->setDLLStorageClass(std::get<2>(linkage));
@@ -1471,10 +1461,9 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
14711461
entity.mangle(result.Name);
14721462

14731463
std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
1474-
getIRLinkage(
1475-
linkInfo, entity.getLinkage(isDefinition),
1476-
entity.isFragile(isDefinition, linkInfo.IsWholeModuleSerialized),
1477-
entity.isSILOnly(), isDefinition, entity.isWeakImported(swiftModule));
1464+
getIRLinkage(linkInfo, entity.getLinkage(isDefinition),
1465+
entity.isFragile(isDefinition), entity.isSILOnly(),
1466+
isDefinition, entity.isWeakImported(swiftModule));
14781467

14791468
result.ForDefinition = isDefinition;
14801469

lib/IRGen/IRGenModule.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,6 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context,
119119
return ClangCodeGen;
120120
}
121121

122-
/// A helper for determining if the triple uses the DLL storage
123-
static bool useDllStorage(const llvm::Triple &Triple) {
124-
return Triple.isOSBinFormatCOFF() && !Triple.isOSCygMing();
125-
}
126-
127122
IRGenModule::IRGenModule(IRGenerator &irgen,
128123
std::unique_ptr<llvm::TargetMachine> &&target,
129124
SourceFile *SF, llvm::LLVMContext &LLVMContext,

lib/IRGen/Linking.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,27 @@
2222
#include "clang/AST/Attr.h"
2323
#include "clang/AST/Decl.h"
2424
#include "clang/AST/DeclObjC.h"
25+
#include "llvm/ADT/Triple.h"
2526
#include "llvm/Support/Compiler.h"
2627
#include "llvm/Support/raw_ostream.h"
2728

2829
using namespace swift;
2930
using namespace irgen;
3031

32+
bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
33+
return triple.isOSBinFormatCOFF() && !triple.isOSCygMing();
34+
}
35+
3136
UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
32-
: IsELFObject(IGM.TargetInfo.OutputObjectFormat == llvm::Triple::ELF),
33-
UseDLLStorage(IGM.useDllStorage()),
34-
HasMultipleIGMs(IGM.IRGen.hasMultipleIGMs()),
35-
IsWholeModule(IGM.getSILModule().isWholeModule()),
36-
IsWholeModuleSerialized(IGM.getSILModule().isWholeModuleSerialized()) {}
37+
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
38+
IGM.getSILModule().isWholeModule()) {}
39+
40+
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
41+
bool hasMultipleIGMs,
42+
bool isWholeModule)
43+
: IsELFObject(triple.isOSBinFormatELF()),
44+
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
45+
IsWholeModule(isWholeModule) {}
3746

3847
/// Mangle this entity into the given buffer.
3948
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {

lib/TBDGen/TBDGen.cpp

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
#include "swift/IRGen/Linking.h"
2424
#include "swift/SIL/FormalLinkage.h"
2525
#include "swift/SIL/SILDeclRef.h"
26+
#include "swift/SIL/TypeLowering.h"
2627
#include "llvm/ADT/StringSet.h"
2728

2829
using namespace swift;
30+
using namespace swift::irgen;
2931
using StringSet = llvm::StringSet<>;
3032

3133
static bool isPrivateDecl(ValueDecl *VD) {
@@ -35,23 +37,38 @@ static bool isPrivateDecl(ValueDecl *VD) {
3537
namespace {
3638
class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
3739
StringSet &Symbols;
40+
const UniversalLinkageInfo &UniversalLinkInfo;
41+
ModuleDecl *SwiftModule;
3842

3943
void addSymbol(StringRef name) {
4044
auto isNewValue = Symbols.insert(name).second;
4145
(void)isNewValue;
4246
assert(isNewValue && "already inserted");
4347
}
4448

49+
void addSymbol(LinkEntity entity) {
50+
auto linkage =
51+
LinkInfo::get(UniversalLinkInfo, SwiftModule, entity, ForDefinition);
52+
53+
auto externallyVisible =
54+
llvm::GlobalValue::isExternalLinkage(linkage.getLinkage()) &&
55+
linkage.getVisibility() != llvm::GlobalValue::HiddenVisibility;
56+
57+
if (externallyVisible)
58+
addSymbol(linkage.getName());
59+
}
60+
4561
void visitValueTypeDecl(NominalTypeDecl *NTD) {
4662
assert(isa<StructDecl>(NTD) || isa<EnumDecl>(NTD));
47-
if (isPrivateDecl(NTD))
48-
return;
49-
5063
visitNominalTypeDecl(NTD);
5164
}
5265

5366
public:
54-
TBDGenVisitor(StringSet &symbols) : Symbols(symbols) {}
67+
TBDGenVisitor(StringSet &symbols,
68+
const UniversalLinkageInfo &universalLinkInfo,
69+
ModuleDecl *swiftModule)
70+
: Symbols(symbols), UniversalLinkInfo(universalLinkInfo),
71+
SwiftModule(swiftModule) {}
5572

5673
void visitMembers(Decl *D) {
5774
SmallVector<Decl *, 4> members;
@@ -83,36 +100,34 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
83100
void visitNominalTypeDecl(NominalTypeDecl *NTD) {
84101
auto declaredType = NTD->getDeclaredType()->getCanonicalType();
85102

86-
auto ntDescriptor = irgen::LinkEntity::forNominalTypeDescriptor(NTD);
87-
addSymbol(ntDescriptor.mangleAsString());
103+
addSymbol(LinkEntity::forNominalTypeDescriptor(NTD));
88104

89-
auto tmd = irgen::LinkEntity::forTypeMetadata(
90-
declaredType, irgen::TypeMetadataAddress::AddressPoint,
91-
/*isPattern=*/false);
92-
addSymbol(tmd.mangleAsString());
93-
auto tmda = irgen::LinkEntity::forTypeMetadataAccessFunction(declaredType);
94-
addSymbol(tmda.mangleAsString());
105+
addSymbol(LinkEntity::forTypeMetadata(declaredType,
106+
TypeMetadataAddress::AddressPoint,
107+
/*isPattern=*/false));
108+
addSymbol(LinkEntity::forTypeMetadataAccessFunction(declaredType));
95109

96-
if (isPrivateDecl(NTD))
97-
return;
110+
// There are symbols associated with any protocols this type conforms to.
111+
for (auto conformance : NTD->getLocalConformances()) {
112+
auto needsWTable = Lowering::TypeConverter::protocolRequiresWitnessTable(
113+
conformance->getProtocol());
114+
if (!needsWTable)
115+
continue;
116+
117+
addSymbol(LinkEntity::forDirectProtocolWitnessTable(conformance));
118+
addSymbol(LinkEntity::forProtocolWitnessTableAccessFunction(conformance));
119+
}
98120

99121
visitMembers(NTD);
100122
}
101123
void visitClassDecl(ClassDecl *CD) {
102-
if (isPrivateDecl(CD))
103-
return;
104-
105124
visitNominalTypeDecl(CD);
106125
}
107126

108127
void visitStructDecl(StructDecl *SD) { visitValueTypeDecl(SD); }
109128
void visitEnumDecl(EnumDecl *ED) { visitValueTypeDecl(ED); }
110129
void visitProtocolDecl(ProtocolDecl *PD) {
111-
if (isPrivateDecl(PD))
112-
return;
113-
114-
auto pDescriptor = irgen::LinkEntity::forProtocolDescriptor(PD);
115-
addSymbol(pDescriptor.mangleAsString());
130+
addSymbol(LinkEntity::forProtocolDescriptor(PD));
116131

117132
// There's no relevant information about members of a protocol at individual
118133
// protocols, each conforming type has to handle them individually.
@@ -145,11 +160,16 @@ void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
145160
visitMembers(VD);
146161
}
147162

148-
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols) {
163+
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
164+
bool hasMultipleIRGenThreads,
165+
bool isWholeModule) {
166+
UniversalLinkageInfo linkInfo(file->getASTContext().LangOpts.Target,
167+
hasMultipleIRGenThreads, isWholeModule);
168+
149169
SmallVector<Decl *, 16> decls;
150170
file->getTopLevelDecls(decls);
151171

152-
TBDGenVisitor visitor(symbols);
172+
TBDGenVisitor visitor(symbols, linkInfo, file->getParentModule());
153173
for (auto d : decls)
154174
visitor.visit(d);
155175
}

0 commit comments

Comments
 (0)