Skip to content

Commit ba150e9

Browse files
authored
Merge pull request #16786 from huonw/tbdgen
More TBDGen: force-load, conformance witness details, test header clean-up, more purposeful handling of accessors.
2 parents f8658fc + 33db2af commit ba150e9

File tree

16 files changed

+287
-112
lines changed

16 files changed

+287
-112
lines changed

include/swift/IRGen/Linking.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,9 @@ class LinkInfo {
880880
llvm::GlobalValue::VisibilityTypes Visibility,
881881
llvm::GlobalValue::DLLStorageClassTypes DLLStorage);
882882
};
883+
884+
StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
885+
StringRef name);
883886
}
884887
}
885888

@@ -910,5 +913,4 @@ template <> struct llvm::DenseMapInfo<swift::irgen::LinkEntity> {
910913
LHS.SecondaryPointer == RHS.SecondaryPointer && LHS.Data == RHS.Data;
911914
}
912915
};
913-
914916
#endif

include/swift/TBDGen/TBDGen.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,23 @@ namespace swift {
2323
class FileUnit;
2424
class ModuleDecl;
2525

26+
/// \brief Options for controlling the exact set of symbols included in the TBD
27+
/// output.
28+
struct TBDGenOptions {
29+
/// \brief Whether this compilation has multiple IRGen instances.
30+
bool HasMultipleIGMs;
31+
/// \brief The install-name used for the compilation.
32+
llvm::StringRef InstallName;
33+
/// \brief The module link name (for force loading).
34+
llvm::StringRef ModuleLinkName;
35+
};
36+
2637
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
27-
bool hasMultipleIGMs);
38+
TBDGenOptions &opts);
2839
void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
29-
bool hasMultipleIGMs);
40+
TBDGenOptions &opts);
3041

31-
void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, bool hasMultipleIGMs,
32-
llvm::StringRef installName);
42+
void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, TBDGenOptions &opts);
3343

3444
} // end namespace swift
3545

lib/FrontendTool/FrontendTool.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "swift/SILOptimizer/PassManager/Passes.h"
6262
#include "swift/Syntax/Serialization/SyntaxSerialization.h"
6363
#include "swift/Syntax/SyntaxNodes.h"
64+
#include "swift/TBDGen/TBDGen.h"
6465

6566
// FIXME: We're just using CompilerInstance::createOutputFile.
6667
// This API should be sunk down to LLVM.
@@ -764,20 +765,24 @@ static void emitReferenceDependenciesForAllPrimaryInputsIfNeeded(
764765

765766
static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
766767
CompilerInstance &Instance) {
767-
if (!Invocation.getFrontendOptions().InputsAndOutputs.hasTBDPath())
768+
const auto &frontendOpts = Invocation.getFrontendOptions();
769+
if (!frontendOpts.InputsAndOutputs.hasTBDPath())
768770
return false;
769771

770772
const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
771773
assert(!TBDPath.empty() &&
772774
"If not WMO, getTBDPathForWholeModule should have failed");
773775

774-
auto installName = Invocation.getFrontendOptions().TBDInstallName.empty()
776+
auto installName = frontendOpts.TBDInstallName.empty()
775777
? "lib" + Invocation.getModuleName().str() + ".dylib"
776-
: Invocation.getFrontendOptions().TBDInstallName;
778+
: frontendOpts.TBDInstallName;
777779

778-
return writeTBD(Instance.getMainModule(),
779-
Invocation.getSILOptions().hasMultipleIGMs(), TBDPath,
780-
installName);
780+
TBDGenOptions opts;
781+
opts.InstallName = installName;
782+
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
783+
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
784+
785+
return writeTBD(Instance.getMainModule(), TBDPath, opts);
781786
}
782787

783788
static std::deque<PostSILGenInputs>
@@ -1138,7 +1143,8 @@ static bool validateTBDIfNeeded(CompilerInvocation &Invocation,
11381143
!inputFileKindCanHaveTBDValidated(Invocation.getInputKind()))
11391144
return false;
11401145

1141-
const auto mode = Invocation.getFrontendOptions().ValidateTBDAgainstIR;
1146+
const auto &frontendOpts = Invocation.getFrontendOptions();
1147+
const auto mode = frontendOpts.ValidateTBDAgainstIR;
11421148
// Ensure all cases are covered by using a switch here.
11431149
switch (mode) {
11441150
case FrontendOptions::TBDValidationMode::None:
@@ -1147,12 +1153,14 @@ static bool validateTBDIfNeeded(CompilerInvocation &Invocation,
11471153
case FrontendOptions::TBDValidationMode::MissingFromTBD:
11481154
break;
11491155
}
1150-
const auto hasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
1156+
TBDGenOptions opts;
1157+
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
1158+
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
1159+
11511160
const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
1152-
return MSF.is<SourceFile *>() ? validateTBD(MSF.get<SourceFile *>(), IRModule,
1153-
hasMultipleIGMs, allSymbols)
1154-
: validateTBD(MSF.get<ModuleDecl *>(), IRModule,
1155-
hasMultipleIGMs, allSymbols);
1161+
return MSF.is<SourceFile *>()
1162+
? validateTBD(MSF.get<SourceFile *>(), IRModule, opts, allSymbols)
1163+
: validateTBD(MSF.get<ModuleDecl *>(), IRModule, opts, allSymbols);
11561164
}
11571165

11581166
static bool generateCode(CompilerInvocation &Invocation,

lib/FrontendTool/TBD.cpp

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

41-
bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIGMs,
42-
StringRef OutputFilename, StringRef installName) {
41+
bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename,
42+
TBDGenOptions &Opts) {
4343
std::error_code EC;
4444
llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
4545
if (EC) {
@@ -48,7 +48,7 @@ bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIGMs,
4848
return true;
4949
}
5050

51-
writeTBDFile(M, OS, hasMultipleIGMs, installName);
51+
writeTBDFile(M, OS, Opts);
5252

5353
return false;
5454
}
@@ -117,18 +117,18 @@ static bool validateSymbolSet(DiagnosticEngine &diags,
117117
}
118118

119119
bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
120-
bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
120+
TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
121121
llvm::StringSet<> symbols;
122-
enumeratePublicSymbols(M, symbols, hasMultipleIGMs);
122+
enumeratePublicSymbols(M, symbols, opts);
123123

124124
return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
125125
diagnoseExtraSymbolsInTBD);
126126
}
127127

128128
bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
129-
bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
129+
TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
130130
llvm::StringSet<> symbols;
131-
enumeratePublicSymbols(file, symbols, hasMultipleIGMs);
131+
enumeratePublicSymbols(file, symbols, opts);
132132

133133
return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
134134
symbols, IRModule, diagnoseExtraSymbolsInTBD);

lib/FrontendTool/TBD.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ namespace swift {
2323
class ModuleDecl;
2424
class FileUnit;
2525
class FrontendOptions;
26+
struct TBDGenOptions;
2627

27-
bool writeTBD(ModuleDecl *M, bool hasMultipleIGMs, StringRef OutputFilename,
28-
llvm::StringRef installName);
28+
bool writeTBD(ModuleDecl *M, StringRef OutputFilename, TBDGenOptions &Opts);
2929
bool inputFileKindCanHaveTBDValidated(InputFileKind kind);
30-
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, bool hasMultipleIGMs,
30+
bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, TBDGenOptions &opts,
3131
bool diagnoseExtraSymbolsInTBD);
32-
bool validateTBD(FileUnit *M, llvm::Module &IRModule, bool hasMultipleIGMs,
32+
bool validateTBD(FileUnit *M, llvm::Module &IRModule, TBDGenOptions &opts,
3333
bool diagnoseExtraSymbolsInTBD);
3434
}
3535

lib/IRGen/IRGenModule.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,9 @@ static void appendEncodedName(llvm::SmallVectorImpl<char> &buf,
793793
appendEncodedName(os, name);
794794
}
795795

796-
static StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
797-
StringRef name) {
796+
StringRef
797+
swift::irgen::encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
798+
StringRef name) {
798799
llvm::raw_svector_ostream os{buf};
799800
os << "_swift_FORCE_LOAD_$";
800801
appendEncodedName(os, name);

lib/TBDGen/TBDGen.cpp

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -92,28 +92,32 @@ void TBDGenVisitor::addConformances(DeclContext *DC) {
9292

9393
auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
9494
normalConformance);
95-
auto addSymbolIfNecessary = [&](SILDeclRef declRef) {
96-
auto witnessLinkage = declRef.getLinkage(ForDefinition);
95+
auto addSymbolIfNecessary = [&](ValueDecl *requirementDecl,
96+
ValueDecl *witnessDecl) {
97+
auto witnessLinkage = SILDeclRef(witnessDecl).getLinkage(ForDefinition);
9798
if (conformanceIsFixed &&
9899
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
99100
Mangle::ASTMangler Mangler;
100-
addSymbol(Mangler.mangleWitnessThunk(normalConformance,
101-
declRef.getDecl()));
101+
addSymbol(
102+
Mangler.mangleWitnessThunk(normalConformance, requirementDecl));
102103
}
103104
};
104-
normalConformance->forEachValueWitness(nullptr, [&](ValueDecl *valueReq,
105-
Witness witness) {
106-
if (isa<AbstractFunctionDecl>(valueReq)) {
107-
addSymbolIfNecessary(SILDeclRef(valueReq));
108-
} else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
109-
if (auto *getter = storage->getGetter())
110-
addSymbolIfNecessary(SILDeclRef(getter));
111-
if (auto *setter = storage->getGetter())
112-
addSymbolIfNecessary(SILDeclRef(setter));
113-
if (auto *materializeForSet = storage->getMaterializeForSetFunc())
114-
addSymbolIfNecessary(SILDeclRef(materializeForSet));
115-
}
116-
});
105+
normalConformance->forEachValueWitness(
106+
nullptr, [&](ValueDecl *valueReq, Witness witness) {
107+
auto witnessDecl = witness.getDecl();
108+
if (isa<AbstractFunctionDecl>(valueReq)) {
109+
addSymbolIfNecessary(valueReq, witnessDecl);
110+
} else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
111+
auto witnessStorage = cast<AbstractStorageDecl>(witnessDecl);
112+
if (auto *getter = storage->getGetter())
113+
addSymbolIfNecessary(getter, witnessStorage->getGetter());
114+
if (auto *setter = storage->getSetter())
115+
addSymbolIfNecessary(setter, witnessStorage->getSetter());
116+
if (auto *materializeForSet = storage->getMaterializeForSetFunc())
117+
addSymbolIfNecessary(materializeForSet,
118+
witnessStorage->getMaterializeForSetFunc());
119+
}
120+
});
117121
}
118122
}
119123

@@ -146,6 +150,22 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
146150
}
147151
}
148152

153+
void TBDGenVisitor::visitAccessorDecl(AccessorDecl *AD) {
154+
// Do nothing: accessors are always nested within the storage decl, but
155+
// sometimes appear outside it too. To avoid double-walking them, we
156+
// explicitly visit them as members of the storage and ignore them when we
157+
// visit them as part of the main walk, here.
158+
}
159+
160+
void TBDGenVisitor::visitAbstractStorageDecl(AbstractStorageDecl *ASD) {
161+
// Explicitly look at each accessor here: see visitAccessorDecl.
162+
SmallVector<Decl *, 8> accessors;
163+
ASD->getAllAccessorFunctions(accessors);
164+
for (auto accessor : accessors) {
165+
visitAbstractFunctionDecl(cast<AbstractFunctionDecl>(accessor));
166+
}
167+
}
168+
149169
void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
150170
// statically/globally stored variables have some special handling.
151171
if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
@@ -158,6 +178,8 @@ void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
158178
if (!FileHasEntryPoint || VD->isStatic())
159179
addSymbol(SILDeclRef(VD, SILDeclRef::Kind::GlobalAccessor));
160180
}
181+
182+
visitAbstractStorageDecl(VD);
161183
}
162184

163185
void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
@@ -332,18 +354,28 @@ void TBDGenVisitor::visitEnumDecl(EnumDecl *ED) {
332354
}
333355
}
334356

357+
void TBDGenVisitor::addFirstFileSymbols() {
358+
if (!Opts.ModuleLinkName.empty()) {
359+
SmallString<32> buf;
360+
addSymbol(irgen::encodeForceLoadSymbolName(buf, Opts.ModuleLinkName));
361+
}
362+
}
363+
335364
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
336365
StringSet &symbols,
337-
bool hasMultipleIGMs,
338366
llvm::raw_ostream *os,
339-
StringRef installName) {
367+
TBDGenOptions &opts) {
340368
auto isWholeModule = singleFile == nullptr;
341369
const auto &target = M->getASTContext().LangOpts.Target;
342-
UniversalLinkageInfo linkInfo(target, hasMultipleIGMs, isWholeModule);
370+
UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, isWholeModule);
343371

344-
TBDGenVisitor visitor(symbols, target, linkInfo, M, installName);
372+
TBDGenVisitor visitor(symbols, target, linkInfo, M, opts);
345373

346374
auto visitFile = [&](FileUnit *file) {
375+
if (file == M->getFiles()[0]) {
376+
visitor.addFirstFileSymbols();
377+
}
378+
347379
SmallVector<Decl *, 16> decls;
348380
file->getTopLevelDecls(decls);
349381

@@ -376,18 +408,16 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
376408
}
377409

378410
void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
379-
bool hasMultipleIGMs) {
411+
TBDGenOptions &opts) {
380412
enumeratePublicSymbolsAndWrite(file->getParentModule(), file, symbols,
381-
hasMultipleIGMs, nullptr, StringRef());
413+
nullptr, opts);
382414
}
383415
void swift::enumeratePublicSymbols(ModuleDecl *M, StringSet &symbols,
384-
bool hasMultipleIGMs) {
385-
enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, nullptr,
386-
StringRef());
416+
TBDGenOptions &opts) {
417+
enumeratePublicSymbolsAndWrite(M, nullptr, symbols, nullptr, opts);
387418
}
388419
void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
389-
bool hasMultipleIGMs, StringRef installName) {
420+
TBDGenOptions &opts) {
390421
StringSet symbols;
391-
enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, &os,
392-
installName);
422+
enumeratePublicSymbolsAndWrite(M, nullptr, symbols, &os, opts);
393423
}

lib/TBDGen/TBDGenVisitor.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ using namespace swift::irgen;
3333
using StringSet = llvm::StringSet<>;
3434

3535
namespace swift {
36+
37+
struct TBDGenOptions;
38+
3639
namespace tbdgen {
3740

3841
class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
@@ -41,7 +44,7 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
4144
const llvm::Triple &Triple;
4245
const UniversalLinkageInfo &UniversalLinkInfo;
4346
ModuleDecl *SwiftModule;
44-
StringRef InstallName;
47+
TBDGenOptions &Opts;
4548

4649
private:
4750
bool FileHasEntryPoint = false;
@@ -73,9 +76,9 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
7376
public:
7477
TBDGenVisitor(StringSet &symbols, const llvm::Triple &triple,
7578
const UniversalLinkageInfo &universalLinkInfo,
76-
ModuleDecl *swiftModule, StringRef installName)
79+
ModuleDecl *swiftModule, TBDGenOptions &opts)
7780
: Symbols(symbols), Triple(triple), UniversalLinkInfo(universalLinkInfo),
78-
SwiftModule(swiftModule), InstallName(installName) {}
81+
SwiftModule(swiftModule), Opts(opts) {}
7982

8083
void setFileHasEntryPoint(bool hasEntryPoint) {
8184
FileHasEntryPoint = hasEntryPoint;
@@ -84,10 +87,15 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
8487
addSymbol("main");
8588
}
8689

90+
/// \brief Adds the global symbols associated with the first file.
91+
void addFirstFileSymbols();
92+
8793
void visitPatternBindingDecl(PatternBindingDecl *PBD);
8894

8995
void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD);
9096

97+
void visitAccessorDecl(AccessorDecl *AD);
98+
9199
void visitNominalTypeDecl(NominalTypeDecl *NTD);
92100

93101
void visitClassDecl(ClassDecl *CD);
@@ -98,6 +106,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
98106

99107
void visitProtocolDecl(ProtocolDecl *PD);
100108

109+
void visitAbstractStorageDecl(AbstractStorageDecl *ASD);
110+
101111
void visitVarDecl(VarDecl *VD);
102112

103113
void visitEnumDecl(EnumDecl *ED);

0 commit comments

Comments
 (0)