Skip to content

Commit 403bb98

Browse files
committed
AST: Optimize collectLinkLibraries()
SourceFile::collectLinkLibraries() did not depend on the source file, so let's move this logic up into ModuleDecl::collectLinkLibraries().
1 parent eca5a1c commit 403bb98

File tree

5 files changed

+76
-60
lines changed

5 files changed

+76
-60
lines changed

lib/AST/Module.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,45 +2135,57 @@ bool ModuleDecl::registerEntryPointFile(
21352135
}
21362136

21372137
void ModuleDecl::collectLinkLibraries(LinkLibraryCallback callback) const {
2138-
// FIXME: The proper way to do this depends on the decls used.
2139-
FORWARD(collectLinkLibraries, (callback));
2140-
}
2138+
bool hasSourceFile = false;
2139+
2140+
for (auto *file : getFiles()) {
2141+
if (isa<SourceFile>(file)) {
2142+
hasSourceFile = true;
2143+
} else {
2144+
file->collectLinkLibraries(callback);
2145+
}
2146+
2147+
if (auto *synth = file->getSynthesizedFile()) {
2148+
synth->collectLinkLibraries(callback);
2149+
}
2150+
}
2151+
2152+
if (!hasSourceFile)
2153+
return;
21412154

2142-
void
2143-
SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const {
21442155
llvm::SmallDenseSet<ModuleDecl *, 32> visited;
21452156
SmallVector<ImportedModule, 32> stack;
21462157

21472158
ModuleDecl::ImportFilter filter = {
21482159
ModuleDecl::ImportFilterKind::Exported,
21492160
ModuleDecl::ImportFilterKind::Default};
21502161

2151-
auto *topLevel = getParentModule();
2152-
21532162
ModuleDecl::ImportFilter topLevelFilter = filter;
21542163
topLevelFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
21552164
topLevelFilter |= ModuleDecl::ImportFilterKind::InternalOrBelow;
21562165
topLevelFilter |= ModuleDecl::ImportFilterKind::PackageOnly,
21572166
topLevelFilter |= ModuleDecl::ImportFilterKind::SPIOnly;
2158-
topLevel->getImportedModules(stack, topLevelFilter);
2167+
getImportedModules(stack, topLevelFilter);
21592168

21602169
// Make sure the top-level module is first; we want pre-order-ish traversal.
2161-
stack.emplace_back(ImportPath::Access(), topLevel);
2170+
stack.emplace_back(ImportPath::Access(), const_cast<ModuleDecl *>(this));
21622171

21632172
while (!stack.empty()) {
21642173
auto next = stack.pop_back_val().importedModule;
21652174

21662175
if (!visited.insert(next).second)
21672176
continue;
21682177

2169-
if (next->getName() != getParentModule()->getName()) {
2178+
if (next->getName() != getName()) {
21702179
next->collectLinkLibraries(callback);
21712180
}
21722181

21732182
next->getImportedModules(stack, filter);
21742183
}
21752184
}
21762185

2186+
void
2187+
SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const {}
2188+
21772189
bool ModuleDecl::walk(ASTWalker &Walker) {
21782190
llvm::SaveAndRestore<ASTWalker::ParentTy> SAR(Walker.Parent, this);
21792191
for (auto SF : getFiles())

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -476,47 +476,6 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
476476
emitGlobalDecl(localDecl);
477477
for (auto *opaqueDecl : SF.getOpaqueReturnTypeDecls())
478478
maybeEmitOpaqueTypeDecl(opaqueDecl);
479-
480-
auto registerLinkLibrary = [this](const LinkLibrary &ll) {
481-
this->addLinkLibrary(ll);
482-
};
483-
484-
SF.collectLinkLibraries([registerLinkLibrary](LinkLibrary linkLib) {
485-
registerLinkLibrary(linkLib);
486-
});
487-
488-
if (ObjCInterop)
489-
registerLinkLibrary(LinkLibrary("objc", LibraryKind::Library));
490-
491-
// If C++ interop is enabled, add -lc++ on Darwin and -lstdc++ on linux.
492-
// Also link with C++ bridging utility module (Cxx) and C++ stdlib overlay
493-
// (std) if available.
494-
if (Context.LangOpts.EnableCXXInterop) {
495-
bool hasStaticCxx = false;
496-
bool hasStaticCxxStdlib = false;
497-
if (const auto *M = Context.getModuleByName("Cxx"))
498-
hasStaticCxx = M->isStaticLibrary();
499-
if (Context.LangOpts.Target.getOS() == llvm::Triple::Win32)
500-
if (const auto *M = Context.getModuleByName("CxxStdlib"))
501-
hasStaticCxxStdlib = M->isStaticLibrary();
502-
dependencies::registerCxxInteropLibraries(Context.LangOpts.Target,
503-
getSwiftModule()->getName().str(),
504-
hasStaticCxx,
505-
hasStaticCxxStdlib,
506-
registerLinkLibrary);
507-
}
508-
509-
// FIXME: It'd be better to have the driver invocation or build system that
510-
// executes the linker introduce these compatibility libraries, since at
511-
// that point we know whether we're building an executable, which is the only
512-
// place where the compatibility libraries take effect. For the benefit of
513-
// build systems that build Swift code, but don't use Swift to drive
514-
// the linker, we can also use autolinking to pull in the compatibility
515-
// libraries. This may however cause the library to get pulled in in
516-
// situations where it isn't useful, such as for dylibs, though this is
517-
// harmless aside from code size.
518-
if (!IRGen.Opts.UseJIT && !Context.LangOpts.hasFeature(Feature::Embedded))
519-
dependencies::registerBackDeployLibraries(IRGen.Opts, registerLinkLibrary);
520479
}
521480

522481
/// Emit all the top-level code in the synthesized file unit.

lib/IRGen/IRGen.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,13 +1192,11 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
11921192
if (auto *synthSFU = file->getSynthesizedFile()) {
11931193
IGM.emitSynthesizedFileUnit(*synthSFU);
11941194
}
1195-
} else {
1196-
file->collectLinkLibraries([&IGM](LinkLibrary LinkLib) {
1197-
IGM.addLinkLibrary(LinkLib);
1198-
});
11991195
}
12001196
}
12011197

1198+
IGM.addLinkLibraries();
1199+
12021200
// Okay, emit any definitions that we suddenly need.
12031201
irgen.emitLazyDefinitions();
12041202

@@ -1413,7 +1411,6 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
14131411
IRGenModule *IGM = new IRGenModule(
14141412
irgen, std::move(targetMachine), nextSF, desc.ModuleName, *OutputIter++,
14151413
nextSF->getFilename(), nextSF->getPrivateDiscriminator().str());
1416-
IGMcreated = true;
14171414

14181415
initLLVMModule(*IGM, *SILMod);
14191416
if (!DidRunSILCodeGenPreparePasses) {
@@ -1424,6 +1421,11 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
14241421
}
14251422

14261423
(void)layoutStringsEnabled(*IGM, /*diagnose*/ true);
1424+
1425+
// Only need to do this once.
1426+
if (!IGMcreated)
1427+
IGM->addLinkLibraries();
1428+
IGMcreated = true;
14271429
}
14281430

14291431
if (!IGMcreated) {
@@ -1446,10 +1448,6 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
14461448
CurrentIGMPtr IGM = irgen.getGenModule(&synthSFU->getFileUnit());
14471449
IGM->emitSynthesizedFileUnit(*synthSFU);
14481450
}
1449-
} else {
1450-
File->collectLinkLibraries([&](LinkLibrary LinkLib) {
1451-
irgen.getPrimaryIGM()->addLinkLibrary(LinkLib);
1452-
});
14531451
}
14541452
}
14551453

lib/IRGen/IRGenModule.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/IRGenOptions.h"
2222
#include "swift/AST/IRGenRequests.h"
2323
#include "swift/AST/Module.h"
24+
#include "swift/AST/ModuleDependencies.h"
2425
#include "swift/Basic/Assertions.h"
2526
#include "swift/Basic/LLVMExtras.h"
2627
#include "swift/ClangImporter/ClangImporter.h"
@@ -1617,6 +1618,50 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
16171618
}
16181619
}
16191620

1621+
void IRGenModule::addLinkLibraries() {
1622+
auto registerLinkLibrary = [this](const LinkLibrary &ll) {
1623+
this->addLinkLibrary(ll);
1624+
};
1625+
1626+
getSwiftModule()->collectLinkLibraries(
1627+
[registerLinkLibrary](LinkLibrary linkLib) {
1628+
registerLinkLibrary(linkLib);
1629+
});
1630+
1631+
if (ObjCInterop)
1632+
registerLinkLibrary(LinkLibrary("objc", LibraryKind::Library));
1633+
1634+
// If C++ interop is enabled, add -lc++ on Darwin and -lstdc++ on linux.
1635+
// Also link with C++ bridging utility module (Cxx) and C++ stdlib overlay
1636+
// (std) if available.
1637+
if (Context.LangOpts.EnableCXXInterop) {
1638+
bool hasStaticCxx = false;
1639+
bool hasStaticCxxStdlib = false;
1640+
if (const auto *M = Context.getModuleByName("Cxx"))
1641+
hasStaticCxx = M->isStaticLibrary();
1642+
if (Context.LangOpts.Target.getOS() == llvm::Triple::Win32)
1643+
if (const auto *M = Context.getModuleByName("CxxStdlib"))
1644+
hasStaticCxxStdlib = M->isStaticLibrary();
1645+
dependencies::registerCxxInteropLibraries(Context.LangOpts.Target,
1646+
getSwiftModule()->getName().str(),
1647+
hasStaticCxx,
1648+
hasStaticCxxStdlib,
1649+
registerLinkLibrary);
1650+
}
1651+
1652+
// FIXME: It'd be better to have the driver invocation or build system that
1653+
// executes the linker introduce these compatibility libraries, since at
1654+
// that point we know whether we're building an executable, which is the only
1655+
// place where the compatibility libraries take effect. For the benefit of
1656+
// build systems that build Swift code, but don't use Swift to drive
1657+
// the linker, we can also use autolinking to pull in the compatibility
1658+
// libraries. This may however cause the library to get pulled in in
1659+
// situations where it isn't useful, such as for dylibs, though this is
1660+
// harmless aside from code size.
1661+
if (!IRGen.Opts.UseJIT && !Context.LangOpts.hasFeature(Feature::Embedded))
1662+
dependencies::registerBackDeployLibraries(IRGen.Opts, registerLinkLibrary);
1663+
}
1664+
16201665
static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx,
16211666
llvm::Module &Module, StringRef EntryName,
16221667
llvm::Module::ModFlagBehavior Behavior,

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,8 @@ private: \
15641564

15651565
void emitSourceFile(SourceFile &SF);
15661566
void emitSynthesizedFileUnit(SynthesizedFileUnit &SFU);
1567+
1568+
void addLinkLibraries();
15671569
void addLinkLibrary(const LinkLibrary &linkLib);
15681570

15691571
/// Attempt to finalize the module.

0 commit comments

Comments
 (0)