Skip to content

Commit 96f3b87

Browse files
committed
Introduce SymbolSourceMapRequest
Add a request that leverages the TBDGenVisitor to produce a mapping from a mangled symbol name to the SIL or IR entity that emits it. This will be used to enable lazy compilation where only a specific set of symbols need to be emitted.
1 parent f6976d8 commit 96f3b87

File tree

6 files changed

+182
-27
lines changed

6 files changed

+182
-27
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SWIFT_TYPEID(Requirement)
2828
SWIFT_TYPEID(ResilienceExpansion)
2929
SWIFT_TYPEID(FragileFunctionKind)
3030
SWIFT_TYPEID(TangentPropertyInfo)
31+
SWIFT_TYPEID(SymbolSourceMap)
3132
SWIFT_TYPEID(Type)
3233
SWIFT_TYPEID(TypePair)
3334
SWIFT_TYPEID(TypeWitnessAndDecl)

include/swift/AST/ASTTypeIDs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Requirement;
6060
enum class ResilienceExpansion : unsigned;
6161
struct FragileFunctionKind;
6262
class SourceFile;
63+
class SymbolSourceMap;
6364
struct TangentPropertyInfo;
6465
class Type;
6566
class TypeAliasDecl;

include/swift/AST/TBDGenRequests.h

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "swift/AST/ASTTypeIDs.h"
2121
#include "swift/AST/SimpleRequest.h"
22+
#include "swift/IRGen/Linking.h"
23+
#include "swift/SIL/SILDeclRef.h"
2224
#include "swift/TBDGen/TBDGen.h"
2325

2426
namespace llvm {
@@ -118,6 +120,123 @@ class PublicSymbolsRequest
118120
evaluate(Evaluator &evaluator, TBDGenDescriptor desc) const;
119121
};
120122

123+
/// Describes the origin of a particular symbol, including the stage of
124+
/// compilation it is introduced, as well as information on what decl introduces
125+
/// it.
126+
class SymbolSource {
127+
public:
128+
enum class Kind {
129+
/// A symbol introduced when emitting a SIL decl.
130+
SIL,
131+
132+
/// A symbol introduced when emitting LLVM IR.
133+
IR,
134+
135+
/// A symbol used to customize linker behavior, introduced by TBDGen.
136+
LinkerDirective,
137+
138+
/// A symbol with an unknown origin.
139+
// FIXME: This should be eliminated.
140+
Unknown
141+
};
142+
Kind kind;
143+
144+
private:
145+
union {
146+
SILDeclRef silDeclRef;
147+
irgen::LinkEntity irEntity;
148+
};
149+
150+
explicit SymbolSource(SILDeclRef ref) : kind(Kind::SIL) {
151+
silDeclRef = ref;
152+
}
153+
explicit SymbolSource(irgen::LinkEntity entity) : kind(Kind::IR) {
154+
irEntity = entity;
155+
}
156+
explicit SymbolSource(Kind kind) : kind(kind) {
157+
assert(kind == Kind::LinkerDirective || kind == Kind::Unknown);
158+
}
159+
160+
public:
161+
static SymbolSource forSILDeclRef(SILDeclRef ref) {
162+
return SymbolSource{ref};
163+
}
164+
static SymbolSource forIRLinkEntity(irgen::LinkEntity entity) {
165+
return SymbolSource{entity};
166+
}
167+
static SymbolSource forLinkerDirective() {
168+
return SymbolSource{Kind::LinkerDirective};
169+
}
170+
static SymbolSource forUnknown() {
171+
return SymbolSource{Kind::Unknown};
172+
}
173+
174+
bool isLinkerDirective() const {
175+
return kind == Kind::LinkerDirective;
176+
}
177+
178+
SILDeclRef getSILDeclRef() const {
179+
assert(kind == Kind::SIL);
180+
return silDeclRef;
181+
}
182+
irgen::LinkEntity getIRLinkEntity() const {
183+
assert(kind == Kind::IR);
184+
return irEntity;
185+
}
186+
};
187+
188+
/// Maps a symbol back to its source for lazy compilation.
189+
class SymbolSourceMap {
190+
friend class SymbolSourceMapRequest;
191+
192+
using Storage = llvm::StringMap<SymbolSource>;
193+
const Storage *storage;
194+
195+
explicit SymbolSourceMap(const Storage *storage) : storage(storage) {
196+
assert(storage);
197+
}
198+
199+
public:
200+
Optional<SymbolSource> find(StringRef symbol) const {
201+
auto result = storage->find(symbol);
202+
if (result == storage->end())
203+
return None;
204+
return result->second;
205+
}
206+
207+
friend bool operator==(const SymbolSourceMap &lhs,
208+
const SymbolSourceMap &rhs) {
209+
return lhs.storage == rhs.storage;
210+
}
211+
friend bool operator!=(const SymbolSourceMap &lhs,
212+
const SymbolSourceMap &rhs) {
213+
return !(lhs == rhs);
214+
}
215+
216+
friend void simple_display(llvm::raw_ostream &out, const SymbolSourceMap &) {
217+
out << "(symbol storage map)";
218+
}
219+
};
220+
221+
/// Computes a map of symbols to their SymbolSource for a file or module.
222+
class SymbolSourceMapRequest
223+
: public SimpleRequest<SymbolSourceMapRequest,
224+
SymbolSourceMap(TBDGenDescriptor),
225+
RequestFlags::Cached> {
226+
public:
227+
using SimpleRequest::SimpleRequest;
228+
229+
private:
230+
friend SimpleRequest;
231+
232+
// Evaluation.
233+
SymbolSourceMap evaluate(Evaluator &evaluator, TBDGenDescriptor desc) const;
234+
235+
public:
236+
// Cached.
237+
bool isCached() const { return true; }
238+
};
239+
121240
/// Report that a request of the given kind is being evaluated, so it
122241
/// can be recorded by the stats reporter.
123242
template <typename Request>

include/swift/AST/TBDGenTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ SWIFT_REQUEST(TBDGen, GenerateTBDRequest, TBDFile(TBDGenDescriptor),
1919
SWIFT_REQUEST(TBDGen, PublicSymbolsRequest,
2020
std::vector<std::string>(TBDGenDescriptor),
2121
Uncached, NoLocationInfo)
22+
SWIFT_REQUEST(TBDGen, SymbolSourceMapRequest,
23+
SymbolSourceMap(TBDGenDescriptor),
24+
Cached, NoLocationInfo)

lib/TBDGen/TBDGen.cpp

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,9 @@ TBDGenVisitor::TBDGenVisitor(const TBDGenDescriptor &desc,
6767
desc.getParentModule(), desc.getOptions(),
6868
symbolCallback) {}
6969

70-
void TBDGenVisitor::addSymbolInternal(StringRef name,
71-
llvm::MachO::SymbolKind kind,
72-
bool isLinkerDirective) {
73-
if (!isLinkerDirective && Opts.LinkerDirectivesOnly)
70+
void TBDGenVisitor::addSymbolInternal(StringRef name, SymbolKind kind,
71+
SymbolSource source) {
72+
if (!source.isLinkerDirective() && Opts.LinkerDirectivesOnly)
7473
return;
7574

7675
#ifndef NDEBUG
@@ -81,7 +80,7 @@ void TBDGenVisitor::addSymbolInternal(StringRef name,
8180
}
8281
}
8382
#endif
84-
SymbolCallback(name, kind);
83+
SymbolCallback(name, kind, source);
8584
}
8685

8786
static std::vector<OriginallyDefinedInAttr::ActiveVersion>
@@ -337,8 +336,8 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(StringRef name,
337336
OS << IntroVer->getMajor() << "." << getMinor(IntroVer->getMinor()) << "$";
338337
OS << Ver.Version.getMajor() << "." << getMinor(Ver.Version.getMinor()) << "$";
339338
OS << name << "$";
340-
addSymbolInternal(OS.str(), llvm::MachO::SymbolKind::GlobalSymbol,
341-
/*LinkerDirective*/true);
339+
addSymbolInternal(OS.str(), SymbolKind::GlobalSymbol,
340+
SymbolSource::forLinkerDirective());
342341
}
343342
}
344343

@@ -383,18 +382,19 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
383382
llvm::SmallString<64> Buffer;
384383
llvm::raw_svector_ostream OS(Buffer);
385384
OS << "$ld$hide$os" << CurMaj << "." << CurMin << "$" << name;
386-
addSymbolInternal(OS.str(), llvm::MachO::SymbolKind::GlobalSymbol,
387-
/*LinkerDirective*/true);
385+
addSymbolInternal(OS.str(), SymbolKind::GlobalSymbol,
386+
SymbolSource::forLinkerDirective());
388387
}
389388
}
390389
}
391390

392-
void TBDGenVisitor::addSymbol(StringRef name, SymbolKind kind) {
391+
void TBDGenVisitor::addSymbol(StringRef name, SymbolSource source,
392+
SymbolKind kind) {
393393
// The linker expects to see mangled symbol names in TBD files, so make sure
394394
// to mangle before inserting the symbol.
395395
SmallString<32> mangled;
396396
llvm::Mangler::getNameWithPrefix(mangled, name, DataLayout);
397-
addSymbolInternal(mangled, kind);
397+
addSymbolInternal(mangled, kind, source);
398398
if (previousInstallNameMap) {
399399
addLinkerDirectiveSymbolsLdPrevious(mangled, kind);
400400
} else {
@@ -407,7 +407,7 @@ void TBDGenVisitor::addSymbol(SILDeclRef declRef) {
407407
declRef.getLinkage(ForDefinition),
408408
declRef.getSubclassScope());
409409
if (linkage == SILLinkage::Public)
410-
addSymbol(declRef.mangle());
410+
addSymbol(declRef.mangle(), SymbolSource::forSILDeclRef(declRef));
411411
}
412412

413413
void TBDGenVisitor::addSymbol(LinkEntity entity) {
@@ -419,7 +419,7 @@ void TBDGenVisitor::addSymbol(LinkEntity entity) {
419419
linkage.getVisibility() != llvm::GlobalValue::HiddenVisibility;
420420

421421
if (externallyVisible)
422-
addSymbol(linkage.getName());
422+
addSymbol(linkage.getName(), SymbolSource::forIRLinkEntity(entity));
423423
}
424424

425425
void TBDGenVisitor::addDispatchThunk(SILDeclRef declRef) {
@@ -490,8 +490,10 @@ void TBDGenVisitor::addConformances(const IterableDeclContext *IDC) {
490490
(isa<SelfProtocolConformance>(rootConformance) ||
491491
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessRef))) {
492492
Mangle::ASTMangler Mangler;
493-
addSymbol(
494-
Mangler.mangleWitnessThunk(rootConformance, requirementDecl));
493+
494+
// FIXME: We should have a SILDeclRef SymbolSource for this.
495+
addSymbol(Mangler.mangleWitnessThunk(rootConformance, requirementDecl),
496+
SymbolSource::forUnknown());
495497
}
496498
};
497499

@@ -542,7 +544,7 @@ void TBDGenVisitor::addAutoDiffLinearMapFunction(AbstractFunctionDecl *original,
542544
original->getGenericSignature(), config.derivativeGenericSignature)};
543545
std::string linearMapName =
544546
mangler.mangleAutoDiffLinearMapHelper(declRef.mangle(), kind, silConfig);
545-
addSymbol(linearMapName);
547+
addSymbol(linearMapName, SymbolSource::forSILDeclRef(declRef));
546548
}
547549

548550
void TBDGenVisitor::addAutoDiffDerivativeFunction(
@@ -587,7 +589,7 @@ void TBDGenVisitor::addDifferentiabilityWitness(
587589

588590
Mangle::ASTMangler mangler;
589591
auto mangledName = mangler.mangleSILDifferentiabilityWitnessKey(key);
590-
addSymbol(mangledName);
592+
addSymbol(mangledName, SymbolSource::forSILDeclRef(declRef));
591593
}
592594

593595
void TBDGenVisitor::addDerivativeConfiguration(AbstractFunctionDecl *original,
@@ -771,8 +773,9 @@ void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
771773
isGlobalOrStaticVar(VD)) {
772774
if (getDeclLinkage(VD) == FormalLinkage::PublicUnique) {
773775
// The actual variable has a symbol.
776+
// FIXME: We ought to have a symbol source for this.
774777
Mangle::ASTMangler mangler;
775-
addSymbol(mangler.mangleEntity(VD));
778+
addSymbol(mangler.mangleEntity(VD), SymbolSource::forUnknown());
776779
}
777780

778781
if (VD->isLazilyInitializedGlobal())
@@ -835,8 +838,10 @@ void TBDGenVisitor::visitClassDecl(ClassDecl *CD) {
835838
addSymbol(LinkEntity::forSwiftMetaclassStub(CD));
836839

837840
if (addObjCClass) {
841+
// FIXME: We ought to have a symbol source for this.
838842
SmallString<128> buffer;
839-
addSymbol(CD->getObjCRuntimeName(buffer), SymbolKind::ObjectiveCClass);
843+
addSymbol(CD->getObjCRuntimeName(buffer), SymbolSource::forUnknown(),
844+
SymbolKind::ObjectiveCClass);
840845
}
841846
}
842847

@@ -1048,8 +1053,10 @@ void TBDGenVisitor::visitEnumElementDecl(EnumElementDecl *EED) {
10481053

10491054
void TBDGenVisitor::addFirstFileSymbols() {
10501055
if (!Opts.ModuleLinkName.empty()) {
1056+
// FIXME: We ought to have a symbol source for this.
10511057
SmallString<32> buf;
1052-
addSymbol(irgen::encodeForceLoadSymbolName(buf, Opts.ModuleLinkName));
1058+
addSymbol(irgen::encodeForceLoadSymbolName(buf, Opts.ModuleLinkName),
1059+
SymbolSource::forUnknown());
10531060
}
10541061
}
10551062

@@ -1196,7 +1203,7 @@ TBDFile GenerateTBDRequest::evaluate(Evaluator &evaluator,
11961203
}
11971204

11981205
llvm::MachO::TargetList targets{target};
1199-
auto addSymbol = [&](StringRef symbol, SymbolKind kind) {
1206+
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
12001207
file.addSymbol(kind, symbol, targets);
12011208
};
12021209

@@ -1209,7 +1216,7 @@ std::vector<std::string>
12091216
PublicSymbolsRequest::evaluate(Evaluator &evaluator,
12101217
TBDGenDescriptor desc) const {
12111218
std::vector<std::string> symbols;
1212-
auto addSymbol = [&](StringRef symbol, SymbolKind kind) {
1219+
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
12131220
if (kind == SymbolKind::GlobalSymbol)
12141221
symbols.push_back(symbol.str());
12151222
};
@@ -1231,3 +1238,24 @@ void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
12311238
llvm::cantFail(llvm::MachO::TextAPIWriter::writeToStream(os, file),
12321239
"YAML writing should be error-free");
12331240
}
1241+
1242+
SymbolSourceMap SymbolSourceMapRequest::evaluate(Evaluator &evaluator,
1243+
TBDGenDescriptor desc) const {
1244+
using Map = SymbolSourceMap::Storage;
1245+
Map symbolSources;
1246+
1247+
auto addSymbol = [&](StringRef symbol, SymbolKind kind, SymbolSource source) {
1248+
symbolSources.insert({symbol, source});
1249+
};
1250+
1251+
TBDGenVisitor visitor(desc, addSymbol);
1252+
visitor.visit(desc);
1253+
1254+
// FIXME: Once the evaluator supports returning a reference to a cached value
1255+
// in storage, this won't be necessary.
1256+
auto &ctx = desc.getParentModule()->getASTContext();
1257+
auto *memory = ctx.Allocate<Map>();
1258+
*memory = std::move(symbolSources);
1259+
ctx.addCleanup([memory](){ memory->~Map(); });
1260+
return SymbolSourceMap(memory);
1261+
}

lib/TBDGen/TBDGenVisitor.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace swift {
4242

4343
class TBDGenDescriptor;
4444
struct TBDGenOptions;
45+
class SymbolSource;
4546

4647
namespace tbdgen {
4748

@@ -72,7 +73,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
7273
const TBDGenOptions &Opts;
7374

7475
using SymbolKind = llvm::MachO::SymbolKind;
75-
using SymbolCallbackFn = llvm::function_ref<void(StringRef, SymbolKind)>;
76+
using SymbolCallbackFn =
77+
llvm::function_ref<void(StringRef, SymbolKind, SymbolSource)>;
7678

7779
SymbolCallbackFn SymbolCallback;
7880

@@ -90,11 +92,11 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
9092
std::unique_ptr<std::map<std::string, InstallNameStore>>
9193
parsePreviousModuleInstallNameMap();
9294
void addSymbolInternal(StringRef name, llvm::MachO::SymbolKind kind,
93-
bool isLinkerDirective = false);
95+
SymbolSource source);
9496
void addLinkerDirectiveSymbolsLdHide(StringRef name, llvm::MachO::SymbolKind kind);
9597
void addLinkerDirectiveSymbolsLdPrevious(StringRef name, llvm::MachO::SymbolKind kind);
96-
void addSymbol(StringRef name, llvm::MachO::SymbolKind kind =
97-
llvm::MachO::SymbolKind::GlobalSymbol);
98+
void addSymbol(StringRef name, SymbolSource source,
99+
SymbolKind kind = SymbolKind::GlobalSymbol);
98100

99101
void addSymbol(SILDeclRef declRef);
100102

@@ -160,8 +162,9 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
160162
//
161163
// Make sure to only add the main symbol for the module that we're emitting
162164
// TBD for, and not for any statically linked libraries.
165+
// FIXME: We should have a SymbolSource for main.
163166
if (file->hasEntryPoint() && file->getParentModule() == SwiftModule)
164-
addSymbol("main");
167+
addSymbol("main", SymbolSource::forUnknown());
165168
}
166169

167170
/// Adds the global symbols associated with the first file.

0 commit comments

Comments
 (0)