Skip to content

Commit b1d669b

Browse files
[Caching] Fix multi-threaded WMO with MCCAS
MCCAS wasn't setup correctly when using parallel WMO. Make sure the CAS ObjectStore and ResultCallbacks are passed to LLVM backend when using parallel WMO. rdar://164409895
1 parent f1d564d commit b1d669b

File tree

9 files changed

+158
-79
lines changed

9 files changed

+158
-79
lines changed

include/swift/AST/IRGenRequests.h

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class SILOptions;
3333
struct TBDGenOptions;
3434
class TBDGenDescriptor;
3535

36+
namespace cas {
37+
class SwiftCASOutputBackend;
38+
}
39+
3640
namespace irgen {
3741
class IRGenModule;
3842
}
@@ -149,12 +153,15 @@ struct IRGenDescriptor {
149153

150154
StringRef ModuleName;
151155
const PrimarySpecificPaths &PSPs;
156+
std::shared_ptr<llvm::cas::ObjectStore> CAS;
152157
StringRef PrivateDiscriminator;
153158
ArrayRef<std::string> parallelOutputFilenames;
154159
ArrayRef<std::string> parallelIROutputFilenames;
155160
llvm::GlobalVariable **outModuleHash;
161+
swift::cas::SwiftCASOutputBackend *casBackend = nullptr;
156162
llvm::raw_pwrite_stream *out = nullptr;
157163

164+
158165
friend llvm::hash_code hash_value(const IRGenDescriptor &owner) {
159166
return llvm::hash_combine(owner.Ctx, owner.SymbolsToEmit, owner.SILMod);
160167
}
@@ -176,8 +183,10 @@ struct IRGenDescriptor {
176183
const TBDGenOptions &TBDOpts, const SILOptions &SILOpts,
177184
Lowering::TypeConverter &Conv, std::unique_ptr<SILModule> &&SILMod,
178185
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
186+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
179187
StringRef PrivateDiscriminator, SymsToEmit symsToEmit = std::nullopt,
180-
llvm::GlobalVariable **outModuleHash = nullptr) {
188+
llvm::GlobalVariable **outModuleHash = nullptr,
189+
cas::SwiftCASOutputBackend *casBackend = nullptr) {
181190
return IRGenDescriptor{file,
182191
symsToEmit,
183192
Opts,
@@ -187,20 +196,26 @@ struct IRGenDescriptor {
187196
SILMod.release(),
188197
ModuleName,
189198
PSPs,
199+
std::move(CAS),
190200
PrivateDiscriminator,
191201
{},
192202
{},
193-
outModuleHash};
203+
outModuleHash,
204+
casBackend};
194205
}
195206

196-
static IRGenDescriptor forWholeModule(
197-
ModuleDecl *M, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts,
198-
const SILOptions &SILOpts, Lowering::TypeConverter &Conv,
199-
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
200-
const PrimarySpecificPaths &PSPs, SymsToEmit symsToEmit = std::nullopt,
201-
ArrayRef<std::string> parallelOutputFilenames = {},
202-
ArrayRef<std::string> parallelIROutputFilenames = {},
203-
llvm::GlobalVariable **outModuleHash = nullptr) {
207+
static IRGenDescriptor
208+
forWholeModule(ModuleDecl *M, const IRGenOptions &Opts,
209+
const TBDGenOptions &TBDOpts, const SILOptions &SILOpts,
210+
Lowering::TypeConverter &Conv,
211+
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
212+
const PrimarySpecificPaths &PSPs,
213+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
214+
SymsToEmit symsToEmit = std::nullopt,
215+
ArrayRef<std::string> parallelOutputFilenames = {},
216+
ArrayRef<std::string> parallelIROutputFilenames = {},
217+
llvm::GlobalVariable **outModuleHash = nullptr,
218+
cas::SwiftCASOutputBackend *casBackend = nullptr) {
204219
return IRGenDescriptor{M,
205220
symsToEmit,
206221
Opts,
@@ -210,10 +225,12 @@ struct IRGenDescriptor {
210225
SILMod.release(),
211226
ModuleName,
212227
PSPs,
228+
std::move(CAS),
213229
"",
214230
parallelOutputFilenames,
215231
parallelIROutputFilenames,
216-
outModuleHash};
232+
outModuleHash,
233+
casBackend};
217234
}
218235

219236
/// Retrieves the files to perform IR generation for. If the descriptor is

include/swift/Subsystems.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ namespace swift {
8080
class TypeConverter;
8181
}
8282

83+
namespace cas {
84+
class SwiftCASOutputBackend;
85+
}
86+
8387
namespace fine_grained_dependencies {
8488
class SourceFileDepGraph;
8589
}
@@ -243,7 +247,8 @@ namespace swift {
243247
/// Get the CPU, subtarget feature options, and triple to use when emitting code.
244248
std::tuple<llvm::TargetOptions, std::string, std::vector<std::string>,
245249
std::string>
246-
getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx);
250+
getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx,
251+
std::shared_ptr<llvm::cas::ObjectStore> CAS = nullptr);
247252

248253
/// Turn the given Swift module into LLVM IR and return the generated module.
249254
/// To compile and output the generated code, call \c performLLVM.
@@ -252,19 +257,23 @@ namespace swift {
252257
const TBDGenOptions &TBDOpts,
253258
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
254259
const PrimarySpecificPaths &PSPs,
260+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
255261
ArrayRef<std::string> parallelOutputFilenames,
256262
ArrayRef<std::string> parallelIROutputFilenames,
257-
llvm::GlobalVariable **outModuleHash = nullptr);
263+
llvm::GlobalVariable **outModuleHash = nullptr,
264+
cas::SwiftCASOutputBackend *casBackend = nullptr);
258265

259266
/// Turn the given Swift file into LLVM IR and return the generated module.
260267
/// To compile and output the generated code, call \c performLLVM.
261268
GeneratedModule
262-
performIRGeneration(FileUnit *file, const IRGenOptions &Opts,
269+
performIRGeneration(FileUnit *file, const IRGenOptions &Opts,
263270
const TBDGenOptions &TBDOpts,
264-
std::unique_ptr<SILModule> SILMod,
265-
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
271+
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
272+
const PrimarySpecificPaths &PSPs,
273+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
266274
StringRef PrivateDiscriminator,
267-
llvm::GlobalVariable **outModuleHash = nullptr);
275+
llvm::GlobalVariable **outModuleHash = nullptr,
276+
cas::SwiftCASOutputBackend *casBackend = nullptr);
268277

269278
/// Given an already created LLVM module, construct a pass pipeline and run
270279
/// the Swift LLVM Pipeline upon it. This will include the emission of LLVM IR
@@ -330,7 +339,8 @@ namespace swift {
330339

331340
/// Creates a TargetMachine from the IRGen opts and AST Context.
332341
std::unique_ptr<llvm::TargetMachine>
333-
createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx);
342+
createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx,
343+
std::shared_ptr<llvm::cas::ObjectStore> CAS);
334344

335345
/// A convenience wrapper for Parser functionality.
336346
class ParserUnit {

lib/DriverTool/sil_llvm_gen_main.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,13 @@ int sil_llvm_gen_main(ArrayRef<const char *> argv, void *MainAddr) {
456456
if (options.PerformWMO) {
457457
return IRGenDescriptor::forWholeModule(
458458
mod, Opts, TBDOpts, SILOpts, SILTypes,
459-
/*SILMod*/ nullptr, moduleName, PSPs);
459+
/*SILMod*/ nullptr, moduleName, PSPs, /*CAS=*/nullptr);
460460
}
461461

462-
return IRGenDescriptor::forFile(
463-
mod->getFiles()[0], Opts, TBDOpts, SILOpts, SILTypes,
464-
/*SILMod*/ nullptr, moduleName, PSPs, /*discriminator*/ "");
462+
return IRGenDescriptor::forFile(mod->getFiles()[0], Opts, TBDOpts, SILOpts,
463+
SILTypes,
464+
/*SILMod*/ nullptr, moduleName, PSPs,
465+
/*CAS=*/nullptr, /*discriminator*/ "");
465466
};
466467

467468
auto &eval = CI.getASTContext().evaluator;

lib/FrontendTool/FrontendTool.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,21 +1785,22 @@ static bool serializeModuleSummary(SILModule *SM,
17851785
static GeneratedModule
17861786
generateIR(const IRGenOptions &IRGenOpts, const TBDGenOptions &TBDOpts,
17871787
std::unique_ptr<SILModule> SM, const PrimarySpecificPaths &PSPs,
1788+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
1789+
cas::SwiftCASOutputBackend *casBackend,
17881790
StringRef OutputFilename, ModuleOrSourceFile MSF,
17891791
llvm::GlobalVariable *&HashGlobal,
17901792
ArrayRef<std::string> parallelOutputFilenames,
17911793
ArrayRef<std::string> parallelIROutputFilenames) {
1792-
if (auto *SF = MSF.dyn_cast<SourceFile *>()) {
1793-
return performIRGeneration(SF, IRGenOpts, TBDOpts,
1794-
std::move(SM), OutputFilename, PSPs,
1795-
SF->getPrivateDiscriminator().str(),
1796-
&HashGlobal);
1797-
} else {
1798-
return performIRGeneration(cast<ModuleDecl *>(MSF), IRGenOpts, TBDOpts,
1799-
std::move(SM), OutputFilename, PSPs,
1800-
parallelOutputFilenames,
1801-
parallelIROutputFilenames, &HashGlobal);
1802-
}
1794+
if (auto *SF = MSF.dyn_cast<SourceFile *>())
1795+
return performIRGeneration(SF, IRGenOpts, TBDOpts, std::move(SM),
1796+
OutputFilename, PSPs, std::move(CAS),
1797+
SF->getPrivateDiscriminator().str(), &HashGlobal,
1798+
casBackend);
1799+
1800+
return performIRGeneration(
1801+
cast<ModuleDecl *>(MSF), IRGenOpts, TBDOpts, std::move(SM),
1802+
OutputFilename, PSPs, std::move(CAS), parallelOutputFilenames,
1803+
parallelIROutputFilenames, &HashGlobal, casBackend);
18031804
}
18041805

18051806
static bool processCommandLineAndRunImmediately(CompilerInstance &Instance,
@@ -1950,10 +1951,8 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
19501951
llvm::Module *IRModule,
19511952
llvm::GlobalVariable *HashGlobal) {
19521953
const auto &opts = Instance.getInvocation().getIRGenOptions();
1953-
std::unique_ptr<llvm::TargetMachine> TargetMachine =
1954-
createTargetMachine(opts, Instance.getASTContext());
1955-
1956-
TargetMachine->Options.MCOptions.CAS = Instance.getSharedCASInstance();
1954+
std::unique_ptr<llvm::TargetMachine> TargetMachine = createTargetMachine(
1955+
opts, Instance.getASTContext(), Instance.getSharedCASInstance());
19571956

19581957
if (Instance.getInvocation().getCASOptions().EnableCaching &&
19591958
opts.UseCASBackend)
@@ -2162,10 +2161,14 @@ static bool performCompileStepsPostSILGen(
21622161
options::OPT_ir_output_path);
21632162

21642163
llvm::GlobalVariable *HashGlobal;
2165-
auto IRModule =
2166-
generateIR(IRGenOpts, Invocation.getTBDGenOptions(), std::move(SM), PSPs,
2167-
OutputFilename, MSF, HashGlobal, ParallelOutputFilenames,
2168-
ParallelIROutputFilenames);
2164+
cas::SwiftCASOutputBackend *casBackend =
2165+
Invocation.getCASOptions().EnableCaching && IRGenOpts.UseCASBackend
2166+
? &Instance.getCASOutputBackend()
2167+
: nullptr;
2168+
auto IRModule = generateIR(
2169+
IRGenOpts, Invocation.getTBDGenOptions(), std::move(SM), PSPs,
2170+
Instance.getSharedCASInstance(), casBackend, OutputFilename, MSF,
2171+
HashGlobal, ParallelOutputFilenames, ParallelIROutputFilenames);
21692172

21702173
// Write extra LLVM IR output if requested
21712174
if (IRModule && !PSPs.SupplementaryOutputs.LLVMIROutputPath.empty()) {

lib/IRGen/IRGen.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ static cl::opt<bool> AlignModuleToPageSize(
129129

130130
std::tuple<llvm::TargetOptions, std::string, std::vector<std::string>,
131131
std::string>
132-
swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) {
132+
swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx,
133+
std::shared_ptr<llvm::cas::ObjectStore> CAS) {
133134
// Things that maybe we should collect from the command line:
134135
// - relocation model
135136
// - code model
@@ -150,6 +151,9 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) {
150151
// Set option to select the CASBackendMode.
151152
TargetOpts.MCOptions.CASObjMode = Opts.CASObjMode;
152153

154+
// Set CAS and CASID callbacks.
155+
TargetOpts.MCOptions.CAS = std::move(CAS);
156+
153157
auto *Clang = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
154158

155159
// Set UseInitArray appropriately.
@@ -1104,7 +1108,8 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
11041108
}
11051109

11061110
std::unique_ptr<llvm::TargetMachine>
1107-
swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) {
1111+
swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx,
1112+
std::shared_ptr<llvm::cas::ObjectStore> CAS) {
11081113
CodeGenOptLevel OptLevel = Opts.shouldOptimize()
11091114
? CodeGenOptLevel::Default // -Os
11101115
: CodeGenOptLevel::None;
@@ -1114,8 +1119,8 @@ swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) {
11141119
std::string CPU;
11151120
std::string EffectiveClangTriple;
11161121
std::vector<std::string> targetFeaturesArray;
1117-
std::tie(TargetOpts, CPU, targetFeaturesArray, EffectiveClangTriple)
1118-
= getIRTargetOptions(Opts, Ctx);
1122+
std::tie(TargetOpts, CPU, targetFeaturesArray, EffectiveClangTriple) =
1123+
getIRTargetOptions(Opts, Ctx, std::move(CAS));
11191124
const llvm::Triple &EffectiveTriple = llvm::Triple(EffectiveClangTriple);
11201125
std::string targetFeatures;
11211126
if (!targetFeaturesArray.empty()) {
@@ -1168,12 +1173,12 @@ swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) {
11681173
return std::unique_ptr<llvm::TargetMachine>(TargetMachine);
11691174
}
11701175

1171-
IRGenerator::IRGenerator(const IRGenOptions &options, SILModule &module)
1172-
: Opts(options), SIL(module), QueueIndex(0) {
1173-
}
1176+
IRGenerator::IRGenerator(const IRGenOptions &options, SILModule &module,
1177+
std::shared_ptr<llvm::cas::ObjectStore> CAS)
1178+
: Opts(options), SIL(module), CAS(std::move(CAS)), QueueIndex(0) {}
11741179

11751180
std::unique_ptr<llvm::TargetMachine> IRGenerator::createTargetMachine() {
1176-
return ::createTargetMachine(Opts, SIL.getASTContext());
1181+
return ::createTargetMachine(Opts, SIL.getASTContext(), CAS);
11771182
}
11781183

11791184
// With -embed-bitcode, save a copy of the llvm IR as data in the
@@ -1479,7 +1484,7 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
14791484
auto *primaryFile =
14801485
dyn_cast_or_null<SourceFile>(desc.Ctx.dyn_cast<FileUnit *>());
14811486

1482-
IRGenerator irgen(Opts, *SILMod);
1487+
IRGenerator irgen(Opts, *SILMod, desc.CAS);
14831488

14841489
auto targetMachine = irgen.createTargetMachine();
14851490
if (!targetMachine) return GeneratedModule::null();
@@ -1687,7 +1692,7 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
16871692
auto SILMod = std::unique_ptr<SILModule>(desc.SILMod);
16881693
auto *M = desc.getParentModule();
16891694

1690-
IRGenerator irgen(Opts, *SILMod);
1695+
IRGenerator irgen(Opts, *SILMod, desc.CAS);
16911696

16921697
// Enter a cleanup to delete all the IGMs and their associated LLVMContexts
16931698
// that have been associated with the IRGenerator.
@@ -1726,6 +1731,16 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
17261731

17271732
// Create the IR emitter.
17281733
auto outputName = *OutputIter++;
1734+
if (desc.casBackend) {
1735+
targetMachine->Options.MCOptions.ResultCallBack =
1736+
[=](const llvm::cas::CASID &id) -> llvm::Error {
1737+
if (auto Err = desc.casBackend->storeMCCASObjectID(outputName, id))
1738+
return Err;
1739+
1740+
return llvm::Error::success();
1741+
};
1742+
}
1743+
17291744
IRGenModule *IGM = new IRGenModule(
17301745
irgen, std::move(targetMachine), nextSF, desc.ModuleName, outputName,
17311746
nextSF->getFilename(), nextSF->getPrivateDiscriminator().str());
@@ -1929,16 +1944,19 @@ GeneratedModule swift::performIRGeneration(
19291944
swift::ModuleDecl *M, const IRGenOptions &Opts,
19301945
const TBDGenOptions &TBDOpts, std::unique_ptr<SILModule> SILMod,
19311946
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
1947+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
19321948
ArrayRef<std::string> parallelOutputFilenames,
19331949
ArrayRef<std::string> parallelIROutputFilenames,
1934-
llvm::GlobalVariable **outModuleHash) {
1950+
llvm::GlobalVariable **outModuleHash,
1951+
cas::SwiftCASOutputBackend *casBackend) {
19351952
// Get a pointer to the SILModule to avoid a potential use-after-move.
19361953
const auto *SILModPtr = SILMod.get();
19371954
const auto &SILOpts = SILModPtr->getOptions();
19381955
auto desc = IRGenDescriptor::forWholeModule(
19391956
M, Opts, TBDOpts, SILOpts, SILModPtr->Types, std::move(SILMod),
1940-
ModuleName, PSPs, /*symsToEmit*/ std::nullopt, parallelOutputFilenames,
1941-
parallelIROutputFilenames, outModuleHash);
1957+
ModuleName, PSPs, std::move(CAS), /*symsToEmit*/ std::nullopt,
1958+
parallelOutputFilenames, parallelIROutputFilenames, outModuleHash,
1959+
casBackend);
19421960

19431961
if (Opts.shouldPerformIRGenerationInParallel() &&
19441962
!parallelOutputFilenames.empty() &&
@@ -1951,20 +1969,20 @@ GeneratedModule swift::performIRGeneration(
19511969
return evaluateOrFatal(M->getASTContext().evaluator, IRGenRequest{desc});
19521970
}
19531971

1954-
GeneratedModule swift::
1955-
performIRGeneration(FileUnit *file, const IRGenOptions &Opts,
1956-
const TBDGenOptions &TBDOpts,
1957-
std::unique_ptr<SILModule> SILMod,
1958-
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
1959-
StringRef PrivateDiscriminator,
1960-
llvm::GlobalVariable **outModuleHash) {
1972+
GeneratedModule swift::performIRGeneration(
1973+
FileUnit *file, const IRGenOptions &Opts, const TBDGenOptions &TBDOpts,
1974+
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
1975+
const PrimarySpecificPaths &PSPs,
1976+
std::shared_ptr<llvm::cas::ObjectStore> CAS, StringRef PrivateDiscriminator,
1977+
llvm::GlobalVariable **outModuleHash,
1978+
cas::SwiftCASOutputBackend *casBackend) {
19611979
// Get a pointer to the SILModule to avoid a potential use-after-move.
19621980
const auto *SILModPtr = SILMod.get();
19631981
const auto &SILOpts = SILModPtr->getOptions();
19641982
auto desc = IRGenDescriptor::forFile(
19651983
file, Opts, TBDOpts, SILOpts, SILModPtr->Types, std::move(SILMod),
1966-
ModuleName, PSPs, PrivateDiscriminator,
1967-
/*symsToEmit*/ std::nullopt, outModuleHash);
1984+
ModuleName, PSPs, std::move(CAS), PrivateDiscriminator,
1985+
/*symsToEmit*/ std::nullopt, outModuleHash, casBackend);
19681986
return evaluateOrFatal(file->getASTContext().evaluator, IRGenRequest{desc});
19691987
}
19701988

@@ -2038,7 +2056,7 @@ void swift::createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer,
20382056
bool swift::performLLVM(const IRGenOptions &Opts, ASTContext &Ctx,
20392057
llvm::Module *Module, StringRef OutputFilename) {
20402058
// Build TargetMachine.
2041-
auto TargetMachine = createTargetMachine(Opts, Ctx);
2059+
auto TargetMachine = createTargetMachine(Opts, Ctx, /*CAS=*/nullptr);
20422060
if (!TargetMachine)
20432061
return true;
20442062

0 commit comments

Comments
 (0)