Skip to content

Commit db7fea4

Browse files
committed
Sink linker directive computation into IRGen
With an inverted pipeline, IRGen needs to be able to compute the linker directives itself, so sink it down such that it can be computed by the `IRGenDescriptor`.
1 parent 24dc744 commit db7fea4

File tree

10 files changed

+78
-77
lines changed

10 files changed

+78
-77
lines changed

include/swift/AST/IRGenRequests.h

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace swift {
2727
class SourceFile;
2828
class IRGenOptions;
2929
class SILModule;
30+
struct TBDGenOptions;
3031

3132
namespace irgen {
3233
class IRGenModule;
@@ -113,15 +114,17 @@ class GeneratedModule final {
113114
};
114115

115116
struct IRGenDescriptor {
116-
const IRGenOptions &Opts;
117117
llvm::PointerUnion<ModuleDecl *, SourceFile *> Ctx;
118+
119+
const IRGenOptions &Opts;
120+
const TBDGenOptions &TBDOpts;
121+
118122
SILModule *SILMod;
119123
StringRef ModuleName;
120124
const PrimarySpecificPaths &PSPs;
121125
StringRef PrivateDiscriminator;
122126
ArrayRef<std::string> parallelOutputFilenames;
123127
llvm::GlobalVariable **outModuleHash;
124-
llvm::StringSet<> *LinkerDirectives;
125128

126129
friend llvm::hash_code hash_value(const IRGenDescriptor &owner) {
127130
return llvm::hash_combine(owner.Ctx);
@@ -139,38 +142,38 @@ struct IRGenDescriptor {
139142

140143
public:
141144
static IRGenDescriptor
142-
forFile(const IRGenOptions &Opts, SourceFile &SF,
143-
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
144-
const PrimarySpecificPaths &PSPs, StringRef PrivateDiscriminator,
145-
llvm::GlobalVariable **outModuleHash,
146-
llvm::StringSet<> *LinkerDirectives) {
147-
return IRGenDescriptor{Opts,
148-
&SF,
145+
forFile(SourceFile &SF, const IRGenOptions &Opts,
146+
const TBDGenOptions &TBDOpts, std::unique_ptr<SILModule> &&SILMod,
147+
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
148+
StringRef PrivateDiscriminator,
149+
llvm::GlobalVariable **outModuleHash) {
150+
return IRGenDescriptor{&SF,
151+
Opts,
152+
TBDOpts,
149153
SILMod.release(),
150154
ModuleName,
151155
PSPs,
152156
PrivateDiscriminator,
153157
{},
154-
outModuleHash,
155-
LinkerDirectives};
158+
outModuleHash};
156159
}
157160

158161
static IRGenDescriptor
159-
forWholeModule(const IRGenOptions &Opts, swift::ModuleDecl *M,
162+
forWholeModule(ModuleDecl *M, const IRGenOptions &Opts,
163+
const TBDGenOptions &TBDOpts,
160164
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
161165
const PrimarySpecificPaths &PSPs,
162166
ArrayRef<std::string> parallelOutputFilenames,
163-
llvm::GlobalVariable **outModuleHash,
164-
llvm::StringSet<> *LinkerDirectives) {
165-
return IRGenDescriptor{Opts,
166-
M,
167+
llvm::GlobalVariable **outModuleHash) {
168+
return IRGenDescriptor{M,
169+
Opts,
170+
TBDOpts,
167171
SILMod.release(),
168172
ModuleName,
169173
PSPs,
170174
"",
171175
parallelOutputFilenames,
172-
outModuleHash,
173-
LinkerDirectives};
176+
outModuleHash};
174177
}
175178

176179
/// Retrieves the files to perform IR generation for.
@@ -179,6 +182,9 @@ struct IRGenDescriptor {
179182
/// For a single file, returns its parent module, otherwise returns the module
180183
/// itself.
181184
ModuleDecl *getParentModule() const;
185+
186+
/// Compute the linker directives to emit.
187+
llvm::StringSet<> getLinkerDirectives() const;
182188
};
183189

184190
/// Report that a request of the given kind is being evaluated, so it

include/swift/Subsystems.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace swift {
6262
class SourceManager;
6363
class SyntaxParseActions;
6464
class SyntaxParsingCache;
65+
struct TBDGenOptions;
6566
class Token;
6667
class TopLevelContext;
6768
class TypeCheckerOptions;
@@ -207,23 +208,23 @@ namespace swift {
207208
/// and return the generated LLVM IR module.
208209
/// If you set an outModuleHash, then you need to call performLLVM.
209210
GeneratedModule
210-
performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
211+
performIRGeneration(ModuleDecl *M, const IRGenOptions &Opts,
212+
const TBDGenOptions &TBDOpts,
211213
std::unique_ptr<SILModule> SILMod,
212214
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
213215
ArrayRef<std::string> parallelOutputFilenames,
214-
llvm::GlobalVariable **outModuleHash = nullptr,
215-
llvm::StringSet<> *LinkerDirectives = nullptr);
216+
llvm::GlobalVariable **outModuleHash = nullptr);
216217

217218
/// Turn the given Swift module into either LLVM IR or native code
218219
/// and return the generated LLVM IR module.
219220
/// If you set an outModuleHash, then you need to call performLLVM.
220221
GeneratedModule
221-
performIRGeneration(const IRGenOptions &Opts, SourceFile &SF,
222+
performIRGeneration(SourceFile &SF, const IRGenOptions &Opts,
223+
const TBDGenOptions &TBDOpts,
222224
std::unique_ptr<SILModule> SILMod,
223225
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
224226
StringRef PrivateDiscriminator,
225-
llvm::GlobalVariable **outModuleHash = nullptr,
226-
llvm::StringSet<> *LinkerDirectives = nullptr);
227+
llvm::GlobalVariable **outModuleHash = nullptr);
227228

228229
/// Given an already created LLVM module, construct a pass pipeline and run
229230
/// the Swift LLVM Pipeline upon it. This does not cause the module to be

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,24 +1501,21 @@ static bool serializeSIB(SILModule *SM, const PrimarySpecificPaths &PSPs,
15011501
}
15021502

15031503
static GeneratedModule
1504-
generateIR(const IRGenOptions &IRGenOpts,
1504+
generateIR(const IRGenOptions &IRGenOpts, const TBDGenOptions &TBDOpts,
15051505
std::unique_ptr<SILModule> SM,
15061506
const PrimarySpecificPaths &PSPs,
15071507
StringRef OutputFilename, ModuleOrSourceFile MSF,
15081508
llvm::GlobalVariable *&HashGlobal,
1509-
ArrayRef<std::string> parallelOutputFilenames,
1510-
llvm::StringSet<> &LinkerDirectives) {
1509+
ArrayRef<std::string> parallelOutputFilenames) {
15111510
if (auto *SF = MSF.dyn_cast<SourceFile *>()) {
1512-
return performIRGeneration(IRGenOpts, *SF,
1511+
return performIRGeneration(*SF, IRGenOpts, TBDOpts,
15131512
std::move(SM), OutputFilename, PSPs,
15141513
SF->getPrivateDiscriminator().str(),
1515-
&HashGlobal,
1516-
&LinkerDirectives);
1514+
&HashGlobal);
15171515
} else {
1518-
return performIRGeneration(IRGenOpts, MSF.get<ModuleDecl *>(),
1516+
return performIRGeneration(MSF.get<ModuleDecl *>(), IRGenOpts, TBDOpts,
15191517
std::move(SM), OutputFilename, PSPs,
1520-
parallelOutputFilenames,
1521-
&HashGlobal, &LinkerDirectives);
1518+
parallelOutputFilenames, &HashGlobal);
15221519
}
15231520
}
15241521

@@ -1663,19 +1660,6 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
16631660
OutputFilename, Instance.getStatsReporter());
16641661
}
16651662

1666-
static llvm::StringSet<>
1667-
collectLinkerDirectives(const CompilerInvocation &Invocation,
1668-
ModuleOrSourceFile MSF) {
1669-
auto tbdOpts = Invocation.getTBDGenOptions();
1670-
tbdOpts.LinkerDirectivesOnly = true;
1671-
if (auto *SF = MSF.dyn_cast<SourceFile *>()) {
1672-
return getPublicSymbols(TBDGenDescriptor::forFile(SF, tbdOpts));
1673-
} else {
1674-
return getPublicSymbols(
1675-
TBDGenDescriptor::forModule(MSF.get<ModuleDecl *>(), tbdOpts));
1676-
}
1677-
}
1678-
16791663
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
16801664
std::unique_ptr<SILModule> SM,
16811665
ModuleOrSourceFile MSF,
@@ -1783,18 +1767,13 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
17831767
return processCommandLineAndRunImmediately(
17841768
Instance, std::move(SM), MSF, observer, ReturnValue);
17851769

1786-
llvm::StringSet<> LinkerDirectives;
1787-
collectLinkerDirectives(Invocation, MSF, LinkerDirectives);
1788-
// Don't proceed to IRGen if collecting linker directives failed.
1789-
if (Context.hadError())
1790-
return true;
17911770
StringRef OutputFilename = PSPs.OutputFilename;
17921771
std::vector<std::string> ParallelOutputFilenames =
17931772
opts.InputsAndOutputs.copyOutputFilenames();
17941773
llvm::GlobalVariable *HashGlobal;
17951774
auto IRModule = generateIR(
1796-
IRGenOpts, std::move(SM), PSPs, OutputFilename, MSF, HashGlobal,
1797-
ParallelOutputFilenames, LinkerDirectives);
1775+
IRGenOpts, Invocation.getTBDGenOptions(), std::move(SM), PSPs,
1776+
OutputFilename, MSF, HashGlobal, ParallelOutputFilenames);
17981777

17991778
// Just because we had an AST error it doesn't mean we can't performLLVM.
18001779
bool HadError = Instance.getASTContext().hadError();

lib/IRGen/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,5 @@ target_link_libraries(swiftIRGen PRIVATE
6969
swiftLLVMPasses
7070
swiftSIL
7171
swiftSILGen
72-
swiftSILOptimizer)
72+
swiftSILOptimizer
73+
swiftTBDGen)

lib/IRGen/GenDecl.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,8 @@ static bool hasCodeCoverageInstrumentation(SILFunction &f, SILModule &m) {
10301030
return f.getProfiler() && m.getOptions().EmitProfileCoverageMapping;
10311031
}
10321032

1033-
void IRGenerator::emitGlobalTopLevel(llvm::StringSet<> *linkerDirectives) {
1033+
void IRGenerator::emitGlobalTopLevel(
1034+
const llvm::StringSet<> &linkerDirectives) {
10341035
// Generate order numbers for the functions in the SIL module that
10351036
// correspond to definitions in the LLVM module.
10361037
unsigned nextOrderNumber = 0;
@@ -1050,10 +1051,8 @@ void IRGenerator::emitGlobalTopLevel(llvm::StringSet<> *linkerDirectives) {
10501051
CurrentIGMPtr IGM = getGenModule(wt.getProtocol()->getDeclContext());
10511052
ensureRelativeSymbolCollocation(wt);
10521053
}
1053-
if (linkerDirectives) {
1054-
for (auto &entry: *linkerDirectives) {
1055-
createLinkerDirectiveVariable(*PrimaryIGM, entry.getKey());
1056-
}
1054+
for (auto &entry: linkerDirectives) {
1055+
createLinkerDirectiveVariable(*PrimaryIGM, entry.getKey());
10571056
}
10581057
for (SILGlobalVariable &v : PrimaryIGM->getSILModule().getSILGlobals()) {
10591058
Decl *decl = v.getDecl();

lib/IRGen/IRGen.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
931931
FrontendStatsTracer tracer(Ctx.Stats, "IRGen");
932932

933933
// Emit the module contents.
934-
irgen.emitGlobalTopLevel(desc.LinkerDirectives);
934+
irgen.emitGlobalTopLevel(desc.getLinkerDirectives());
935935

936936
for (auto *file : filesToEmit) {
937937
if (auto *nextSF = dyn_cast<SourceFile>(file)) {
@@ -1178,7 +1178,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
11781178
}
11791179

11801180
// Emit the module contents.
1181-
irgen.emitGlobalTopLevel(desc.LinkerDirectives);
1181+
irgen.emitGlobalTopLevel(desc.getLinkerDirectives());
11821182

11831183
for (auto *File : M->getFiles()) {
11841184
if (auto *SF = dyn_cast<SourceFile>(File)) {
@@ -1306,14 +1306,14 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
13061306
}
13071307

13081308
GeneratedModule swift::performIRGeneration(
1309-
const IRGenOptions &Opts, swift::ModuleDecl *M,
1310-
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
1311-
const PrimarySpecificPaths &PSPs,
1309+
swift::ModuleDecl *M, const IRGenOptions &Opts,
1310+
const TBDGenOptions &TBDOpts, std::unique_ptr<SILModule> SILMod,
1311+
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
13121312
ArrayRef<std::string> parallelOutputFilenames,
1313-
llvm::GlobalVariable **outModuleHash, llvm::StringSet<> *LinkerDirectives) {
1313+
llvm::GlobalVariable **outModuleHash) {
13141314
auto desc = IRGenDescriptor::forWholeModule(
1315-
Opts, M, std::move(SILMod), ModuleName, PSPs, parallelOutputFilenames,
1316-
outModuleHash, LinkerDirectives);
1315+
M, Opts, TBDOpts, std::move(SILMod), ModuleName, PSPs,
1316+
parallelOutputFilenames, outModuleHash);
13171317

13181318
if (Opts.shouldPerformIRGenerationInParallel() &&
13191319
!parallelOutputFilenames.empty()) {
@@ -1326,15 +1326,15 @@ GeneratedModule swift::performIRGeneration(
13261326
}
13271327

13281328
GeneratedModule swift::
1329-
performIRGeneration(const IRGenOptions &Opts, SourceFile &SF,
1329+
performIRGeneration(SourceFile &SF, const IRGenOptions &Opts,
1330+
const TBDGenOptions &TBDOpts,
13301331
std::unique_ptr<SILModule> SILMod,
13311332
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
13321333
StringRef PrivateDiscriminator,
1333-
llvm::GlobalVariable **outModuleHash,
1334-
llvm::StringSet<> *LinkerDirectives) {
1335-
auto desc = IRGenDescriptor::forFile(Opts, SF, std::move(SILMod), ModuleName,
1336-
PSPs, PrivateDiscriminator,
1337-
outModuleHash, LinkerDirectives);
1334+
llvm::GlobalVariable **outModuleHash) {
1335+
auto desc = IRGenDescriptor::forFile(SF, Opts, TBDOpts, std::move(SILMod),
1336+
ModuleName, PSPs, PrivateDiscriminator,
1337+
outModuleHash);
13381338
return llvm::cantFail(SF.getASTContext().evaluator(IRGenRequest{desc}));
13391339
}
13401340

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ class IRGenerator {
375375

376376
/// Emit functions, variables and tables which are needed anyway, e.g. because
377377
/// they are externally visible.
378-
void emitGlobalTopLevel(llvm::StringSet<> *LinkerDirectives);
378+
void emitGlobalTopLevel(const llvm::StringSet<> &LinkerDirectives);
379379

380380
/// Emit references to each of the protocol descriptors defined in this
381381
/// IR module.

lib/IRGen/IRGenRequests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/SourceFile.h"
1818
#include "swift/SIL/SILModule.h"
1919
#include "swift/Subsystems.h"
20+
#include "swift/TBDGen/TBDGen.h"
2021
#include "llvm/IR/Module.h"
2122
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
2223

@@ -75,6 +76,17 @@ ModuleDecl *IRGenDescriptor::getParentModule() const {
7576
return Ctx.get<ModuleDecl *>();
7677
}
7778

79+
llvm::StringSet<> IRGenDescriptor::getLinkerDirectives() const {
80+
auto opts = TBDOpts;
81+
opts.LinkerDirectivesOnly = true;
82+
if (auto *SF = Ctx.dyn_cast<SourceFile *>()) {
83+
return getPublicSymbols(TBDGenDescriptor::forFile(SF, opts));
84+
} else {
85+
auto *M = Ctx.get<ModuleDecl *>();
86+
return getPublicSymbols(TBDGenDescriptor::forModule(M, opts));
87+
}
88+
}
89+
7890
evaluator::DependencySource IRGenRequest::readDependencySource(
7991
const evaluator::DependencyRecorder &e) const {
8092
auto &desc = std::get<0>(getStorage());

lib/Immediate/Immediate.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ int swift::RunImmediately(CompilerInstance &CI,
201201
// IRGen the main module.
202202
auto *swiftModule = CI.getMainModule();
203203
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
204+
const auto &TBDOpts = CI.getInvocation().getTBDGenOptions();
204205
auto GenModule = performIRGeneration(
205-
IRGenOpts, swiftModule, std::move(SM), swiftModule->getName().str(),
206-
PSPs, ArrayRef<std::string>());
206+
swiftModule, IRGenOpts, TBDOpts, std::move(SM),
207+
swiftModule->getName().str(), PSPs, ArrayRef<std::string>());
207208

208209
if (Context.hadError())
209210
return -1;

tools/sil-llvm-gen/SILLLVMGen.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ int main(int argc, char **argv) {
196196
}
197197

198198
const PrimarySpecificPaths PSPs(OutputFilename, InputFilename);
199-
auto Mod = performIRGeneration(Opts, CI.getMainModule(), std::move(SILMod),
199+
auto Mod = performIRGeneration(CI.getMainModule(), Opts,
200+
CI.getInvocation().getTBDGenOptions(),
201+
std::move(SILMod),
200202
CI.getMainModule()->getName().str(), PSPs,
201203
ArrayRef<std::string>());
202204
return CI.getASTContext().hadError();

0 commit comments

Comments
 (0)