Skip to content

Commit 890df57

Browse files
authored
Merge pull request #32654 from hamishknight/all-for-ir-and-ir-for-all
2 parents c03ea7a + bf2f4af commit 890df57

File tree

8 files changed

+102
-119
lines changed

8 files changed

+102
-119
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ class IRGenOptions {
284284
/// Whether to disable using mangled names for accessing concrete type metadata.
285285
unsigned DisableConcreteTypeMetadataMangledNameAccessors : 1;
286286

287+
/// The number of threads for multi-threaded code generation.
288+
unsigned NumThreads = 0;
289+
287290
/// Path to the profdata file to be used for PGO, or the empty string.
288291
std::string UseProfile = "";
289292

@@ -383,6 +386,10 @@ class IRGenOptions {
383386
llvm::hash_code getPCHHashComponents() const {
384387
return llvm::hash_value(0);
385388
}
389+
390+
bool hasMultipleIRGenThreads() const { return NumThreads > 1; }
391+
bool shouldPerformIRGenerationInParallel() const { return NumThreads != 0; }
392+
bool hasMultipleIGMs() const { return hasMultipleIRGenThreads(); }
386393
};
387394

388395
} // end namespace swift

include/swift/AST/IRGenRequests.h

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ struct IRGenDescriptor {
172172
outModuleHash,
173173
LinkerDirectives};
174174
}
175+
176+
/// Retrieves the files to perform IR generation for.
177+
TinyPtrVector<FileUnit *> getFiles() const;
178+
179+
/// For a single file, returns its parent module, otherwise returns the module
180+
/// itself.
181+
ModuleDecl *getParentModule() const;
175182
};
176183

177184
/// Report that a request of the given kind is being evaluated, so it
@@ -180,10 +187,10 @@ template<typename Request>
180187
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
181188
const Request &request);
182189

183-
class IRGenSourceFileRequest
184-
: public SimpleRequest<IRGenSourceFileRequest,
185-
GeneratedModule(IRGenDescriptor),
186-
RequestFlags::Uncached|RequestFlags::DependencySource> {
190+
class IRGenRequest
191+
: public SimpleRequest<IRGenRequest, GeneratedModule(IRGenDescriptor),
192+
RequestFlags::Uncached |
193+
RequestFlags::DependencySource> {
187194
public:
188195
using SimpleRequest::SimpleRequest;
189196

@@ -194,33 +201,12 @@ class IRGenSourceFileRequest
194201
GeneratedModule
195202
evaluate(Evaluator &evaluator, IRGenDescriptor desc) const;
196203

197-
public:
198-
bool isCached() const { return true; }
199-
200204
public:
201205
// Incremental dependencies.
202206
evaluator::DependencySource
203207
readDependencySource(const evaluator::DependencyRecorder &) const;
204208
};
205209

206-
class IRGenWholeModuleRequest
207-
: public SimpleRequest<IRGenWholeModuleRequest,
208-
GeneratedModule(IRGenDescriptor),
209-
RequestFlags::Uncached> {
210-
public:
211-
using SimpleRequest::SimpleRequest;
212-
213-
private:
214-
friend SimpleRequest;
215-
216-
// Evaluation.
217-
GeneratedModule
218-
evaluate(Evaluator &evaluator, IRGenDescriptor desc) const;
219-
220-
public:
221-
bool isCached() const { return true; }
222-
};
223-
224210
void simple_display(llvm::raw_ostream &out, const IRGenDescriptor &d);
225211

226212
SourceLoc extractNearestSourceLoc(const IRGenDescriptor &desc);

include/swift/AST/IRGenTypeIDZone.def

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
SWIFT_REQUEST(IRGen, IRGenSourceFileRequest,
17+
SWIFT_REQUEST(IRGen, IRGenRequest,
1818
GeneratedModule(IRGenDescriptor),
1919
Uncached, NoLocationInfo)
20-
SWIFT_REQUEST(IRGen, IRGenWholeModuleRequest,
21-
GeneratedModule(IRGenDescriptor),
22-
Uncached, NoLocationInfo)
23-

include/swift/AST/SILOptions.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ class SILOptions {
4040
/// Controls the aggressiveness of the loop unroller.
4141
int UnrollThreshold = 250;
4242

43-
/// The number of threads for multi-threaded code generation.
44-
unsigned NumThreads = 0;
45-
4643
/// Controls whether to pull in SIL from partial modules during the
4744
/// merge modules step. Could perhaps be merged with the link mode
4845
/// above but the interactions between all the flags are tricky.
@@ -183,10 +180,6 @@ class SILOptions {
183180
bool shouldOptimize() const {
184181
return OptMode > OptimizationMode::NoOptimization;
185182
}
186-
187-
bool hasMultipleIRGenThreads() const { return NumThreads > 1; }
188-
bool shouldPerformIRGenerationInParallel() const { return NumThreads != 0; }
189-
bool hasMultipleIGMs() const { return hasMultipleIRGenThreads(); }
190183
};
191184

192185
} // end namespace swift

lib/Frontend/CompilerInvocation.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,18 +1043,6 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
10431043
return true;
10441044
}
10451045
}
1046-
if (const Arg *A = Args.getLastArg(OPT_num_threads)) {
1047-
if (StringRef(A->getValue()).getAsInteger(10, Opts.NumThreads)) {
1048-
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
1049-
A->getAsString(Args), A->getValue());
1050-
return true;
1051-
}
1052-
if (environmentVariableRequestedMaximumDeterminism()) {
1053-
Opts.NumThreads = 1;
1054-
Diags.diagnose(SourceLoc(), diag::remark_max_determinism_overriding,
1055-
"-num-threads");
1056-
}
1057-
}
10581046

10591047
// If we're only emitting a module, stop optimizations once we've serialized
10601048
// the SIL for the module.
@@ -1259,7 +1247,7 @@ static bool ParseTBDGenArgs(TBDGenOptions &Opts, ArgList &Args,
12591247
CompilerInvocation &Invocation) {
12601248
using namespace options;
12611249

1262-
Opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
1250+
Opts.HasMultipleIGMs = Invocation.getIRGenOptions().hasMultipleIGMs();
12631251

12641252
if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
12651253
Opts.ModuleLinkName = A->getValue();
@@ -1593,6 +1581,19 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
15931581
getRuntimeCompatVersion();
15941582
}
15951583

1584+
if (const Arg *A = Args.getLastArg(OPT_num_threads)) {
1585+
if (StringRef(A->getValue()).getAsInteger(10, Opts.NumThreads)) {
1586+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
1587+
A->getAsString(Args), A->getValue());
1588+
return true;
1589+
}
1590+
if (environmentVariableRequestedMaximumDeterminism()) {
1591+
Opts.NumThreads = 1;
1592+
Diags.diagnose(SourceLoc(), diag::remark_max_determinism_overriding,
1593+
"-num-threads");
1594+
}
1595+
}
1596+
15961597
return false;
15971598
}
15981599

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ class PrettySynthesizedFileUnitEmission : public llvm::PrettyStackTraceEntry {
443443

444444
/// Emit all the top-level code in the source file.
445445
void IRGenModule::emitSourceFile(SourceFile &SF) {
446+
assert(SF.ASTStage == SourceFile::TypeChecked);
446447
PrettySourceFileEmission StackEntry(SF);
447448

448449
// Emit types and other global decls.

lib/IRGen/IRGen.cpp

Lines changed: 36 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -889,14 +889,16 @@ static void runIRGenPreparePasses(SILModule &Module,
889889

890890
/// Generates LLVM IR, runs the LLVM passes and produces the output file.
891891
/// All this is done in a single thread.
892-
static GeneratedModule
893-
performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
894-
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
895-
const PrimarySpecificPaths &PSPs,
896-
StringRef PrivateDiscriminator,
897-
SourceFile *SF = nullptr,
898-
llvm::GlobalVariable **outModuleHash = nullptr,
899-
llvm::StringSet<> *linkerDirectives = nullptr) {
892+
GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
893+
IRGenDescriptor desc) const {
894+
const auto &Opts = desc.Opts;
895+
const auto &PSPs = desc.PSPs;
896+
897+
auto SILMod = std::unique_ptr<SILModule>(desc.SILMod);
898+
auto *M = desc.getParentModule();
899+
auto filesToEmit = desc.getFiles();
900+
auto *primaryFile = desc.Ctx.dyn_cast<SourceFile *>();
901+
900902
auto &Ctx = M->getASTContext();
901903
assert(!Ctx.hadError());
902904

@@ -906,9 +908,9 @@ performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
906908
if (!targetMachine) return GeneratedModule::null();
907909

908910
// Create the IR emitter.
909-
IRGenModule IGM(irgen, std::move(targetMachine), SF, ModuleName,
911+
IRGenModule IGM(irgen, std::move(targetMachine), primaryFile, desc.ModuleName,
910912
PSPs.OutputFilename, PSPs.MainInputFilenameForDebugInfo,
911-
PrivateDiscriminator);
913+
desc.PrivateDiscriminator);
912914

913915
initLLVMModule(IGM, *SILMod);
914916

@@ -919,25 +921,17 @@ performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
919921
FrontendStatsTracer tracer(Ctx.Stats, "IRGen");
920922

921923
// Emit the module contents.
922-
irgen.emitGlobalTopLevel(linkerDirectives);
923-
924-
if (SF) {
925-
IGM.emitSourceFile(*SF);
926-
// Emit synthesized file unit, if it exists.
927-
if (auto *synthesizedFile = SF->getSynthesizedFile())
928-
IGM.emitSynthesizedFileUnit(*synthesizedFile);
929-
} else {
930-
for (auto *File : M->getFiles()) {
931-
if (auto *nextSF = dyn_cast<SourceFile>(File)) {
932-
if (nextSF->ASTStage >= SourceFile::TypeChecked)
933-
IGM.emitSourceFile(*nextSF);
934-
} else if (auto *nextSFU = dyn_cast<SynthesizedFileUnit>(File)) {
935-
IGM.emitSynthesizedFileUnit(*nextSFU);
936-
} else {
937-
File->collectLinkLibraries([&IGM](LinkLibrary LinkLib) {
938-
IGM.addLinkLibrary(LinkLib);
939-
});
940-
}
924+
irgen.emitGlobalTopLevel(desc.LinkerDirectives);
925+
926+
for (auto *file : filesToEmit) {
927+
if (auto *nextSF = dyn_cast<SourceFile>(file)) {
928+
IGM.emitSourceFile(*nextSF);
929+
} else if (auto *nextSFU = dyn_cast<SynthesizedFileUnit>(file)) {
930+
IGM.emitSynthesizedFileUnit(*nextSFU);
931+
} else {
932+
file->collectLinkLibraries([&IGM](LinkLibrary LinkLib) {
933+
IGM.addLinkLibrary(LinkLib);
934+
});
941935
}
942936
}
943937

@@ -990,7 +984,7 @@ performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
990984

991985
embedBitcode(IGM.getModule(), Opts);
992986

993-
if (outModuleHash) {
987+
if (auto **outModuleHash = desc.outModuleHash) {
994988
*outModuleHash = IGM.ModuleHash;
995989
} else {
996990
FrontendStatsTracer tracer(Ctx.Stats, "LLVM pipeline");
@@ -1138,7 +1132,7 @@ static void performParallelIRGeneration(
11381132
bool DidRunSILCodeGenPreparePasses = false;
11391133
for (auto *File : M->getFiles()) {
11401134
auto nextSF = dyn_cast<SourceFile>(File);
1141-
if (!nextSF || nextSF->ASTStage < SourceFile::TypeChecked)
1135+
if (!nextSF)
11421136
continue;
11431137

11441138
// There must be an output filename for each source file.
@@ -1286,7 +1280,7 @@ static void performParallelIRGeneration(
12861280

12871281
// Start all the threads and do the LLVM compilation.
12881282

1289-
LLVMCodeGenThreads codeGenThreads(&irgen, &DiagMutex, SILMod->getOptions().NumThreads - 1);
1283+
LLVMCodeGenThreads codeGenThreads(&irgen, &DiagMutex, Opts.NumThreads - 1);
12901284
codeGenThreads.startThreads();
12911285

12921286
// Free the memory occupied by the SILModule.
@@ -1307,30 +1301,19 @@ GeneratedModule swift::performIRGeneration(
13071301
const PrimarySpecificPaths &PSPs,
13081302
ArrayRef<std::string> parallelOutputFilenames,
13091303
llvm::GlobalVariable **outModuleHash, llvm::StringSet<> *LinkerDirectives) {
1310-
auto desc = IRGenDescriptor::forWholeModule(
1311-
Opts, M, std::move(SILMod), ModuleName, PSPs,
1312-
parallelOutputFilenames, outModuleHash, LinkerDirectives);
1313-
return llvm::cantFail(
1314-
M->getASTContext().evaluator(IRGenWholeModuleRequest{desc}));
1315-
}
1316-
1317-
GeneratedModule
1318-
IRGenWholeModuleRequest::evaluate(Evaluator &evaluator,
1319-
IRGenDescriptor desc) const {
1320-
auto *M = desc.Ctx.get<ModuleDecl *>();
1321-
if (desc.SILMod->getOptions().shouldPerformIRGenerationInParallel() &&
1322-
!desc.parallelOutputFilenames.empty()) {
1323-
::performParallelIRGeneration(
1324-
desc.Opts, M, std::unique_ptr<SILModule>(desc.SILMod), desc.ModuleName,
1325-
desc.parallelOutputFilenames, desc.LinkerDirectives);
1304+
if (Opts.shouldPerformIRGenerationInParallel() &&
1305+
!parallelOutputFilenames.empty()) {
1306+
::performParallelIRGeneration(Opts, M, std::move(SILMod), ModuleName,
1307+
parallelOutputFilenames, LinkerDirectives);
13261308
// TODO: Parallel LLVM compilation cannot be used if a (single) module is
13271309
// needed as return value.
13281310
return GeneratedModule::null();
13291311
}
1330-
return ::performIRGeneration(
1331-
desc.Opts, M, std::unique_ptr<SILModule>(desc.SILMod), desc.ModuleName,
1332-
desc.PSPs, "", nullptr, desc.outModuleHash,
1333-
desc.LinkerDirectives);
1312+
1313+
auto desc = IRGenDescriptor::forWholeModule(
1314+
Opts, M, std::move(SILMod), ModuleName, PSPs, parallelOutputFilenames,
1315+
outModuleHash, LinkerDirectives);
1316+
return llvm::cantFail(M->getASTContext().evaluator(IRGenRequest{desc}));
13341317
}
13351318

13361319
GeneratedModule swift::
@@ -1343,18 +1326,7 @@ performIRGeneration(const IRGenOptions &Opts, SourceFile &SF,
13431326
auto desc = IRGenDescriptor::forFile(Opts, SF, std::move(SILMod), ModuleName,
13441327
PSPs, PrivateDiscriminator,
13451328
outModuleHash, LinkerDirectives);
1346-
return llvm::cantFail(
1347-
SF.getASTContext().evaluator(IRGenSourceFileRequest{desc}));
1348-
}
1349-
1350-
GeneratedModule
1351-
IRGenSourceFileRequest::evaluate(Evaluator &evaluator,
1352-
IRGenDescriptor desc) const {
1353-
auto *SF = desc.Ctx.get<SourceFile *>();
1354-
return ::performIRGeneration(
1355-
desc.Opts, SF->getParentModule(), std::unique_ptr<SILModule>(desc.SILMod),
1356-
desc.ModuleName, desc.PSPs, desc.PrivateDiscriminator,
1357-
SF, desc.outModuleHash, desc.LinkerDirectives);
1329+
return llvm::cantFail(SF.getASTContext().evaluator(IRGenRequest{desc}));
13581330
}
13591331

13601332
void

lib/IRGen/IRGenRequests.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,40 @@ SourceLoc swift::extractNearestSourceLoc(const IRGenDescriptor &desc) {
5252
return SourceLoc();
5353
}
5454

55-
evaluator::DependencySource IRGenSourceFileRequest::readDependencySource(
55+
TinyPtrVector<FileUnit *> IRGenDescriptor::getFiles() const {
56+
// For a whole module, we emit IR for all files.
57+
if (auto *mod = Ctx.dyn_cast<ModuleDecl *>())
58+
return TinyPtrVector<FileUnit *>(mod->getFiles());
59+
60+
// For a primary source file, we emit IR for both it and potentially its
61+
// SynthesizedFileUnit.
62+
auto *SF = Ctx.get<SourceFile *>();
63+
TinyPtrVector<FileUnit *> files;
64+
files.push_back(SF);
65+
66+
if (auto *synthesizedFile = SF->getSynthesizedFile())
67+
files.push_back(synthesizedFile);
68+
69+
return files;
70+
}
71+
72+
ModuleDecl *IRGenDescriptor::getParentModule() const {
73+
if (auto *SF = Ctx.dyn_cast<SourceFile *>())
74+
return SF->getParentModule();
75+
return Ctx.get<ModuleDecl *>();
76+
}
77+
78+
evaluator::DependencySource IRGenRequest::readDependencySource(
5679
const evaluator::DependencyRecorder &e) const {
5780
auto &desc = std::get<0>(getStorage());
58-
return {
59-
desc.Ctx.dyn_cast<SourceFile *>(),
60-
evaluator::DependencyScope::Cascading
61-
};
81+
82+
// We don't track dependencies in whole-module mode.
83+
if (auto *mod = desc.Ctx.dyn_cast<ModuleDecl *>()) {
84+
return {nullptr, e.getActiveSourceScope()};
85+
}
86+
87+
auto *SF = desc.Ctx.get<SourceFile *>();
88+
return {SF, evaluator::DependencyScope::Cascading};
6289
}
6390

6491
// Define request evaluation functions for each of the IRGen requests.

0 commit comments

Comments
 (0)