mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Reduce memory usage by freeing memory occupied by SILModules after IRGen.
There is no need to keep SILModules around after IRGen has generated LLVM IR from them. This reduces the compiler memory usage during LLVM code-generation and optimization phases roughly by 15%-20%.
This commit is contained in:
@@ -250,13 +250,15 @@ namespace swift {
|
||||
/// Turn the given Swift module into either LLVM IR or native code
|
||||
/// and return the generated LLVM IR module.
|
||||
std::unique_ptr<llvm::Module>
|
||||
performIRGeneration(IRGenOptions &Opts, ModuleDecl *M, SILModule *SILMod,
|
||||
performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName, llvm::LLVMContext &LLVMContext);
|
||||
|
||||
/// Turn the given Swift module into either LLVM IR or native code
|
||||
/// and return the generated LLVM IR module.
|
||||
std::unique_ptr<llvm::Module>
|
||||
performIRGeneration(IRGenOptions &Opts, SourceFile &SF, SILModule *SILMod,
|
||||
performIRGeneration(IRGenOptions &Opts, SourceFile &SF,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName, llvm::LLVMContext &LLVMContext,
|
||||
unsigned StartElem = 0);
|
||||
|
||||
|
||||
@@ -1073,10 +1073,10 @@ static bool performCompile(CompilerInstance &Instance,
|
||||
// something is persisting across calls to performIRGeneration.
|
||||
auto &LLVMContext = getGlobalLLVMContext();
|
||||
if (PrimarySourceFile) {
|
||||
performIRGeneration(IRGenOpts, *PrimarySourceFile, SM.get(),
|
||||
performIRGeneration(IRGenOpts, *PrimarySourceFile, std::move(SM),
|
||||
opts.getSingleOutputFilename(), LLVMContext);
|
||||
} else {
|
||||
performIRGeneration(IRGenOpts, Instance.getMainModule(), SM.get(),
|
||||
performIRGeneration(IRGenOpts, Instance.getMainModule(), std::move(SM),
|
||||
opts.getSingleOutputFilename(), LLVMContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -595,7 +595,7 @@ static void initLLVMModule(const IRGenModule &IGM) {
|
||||
/// All this is done in a single thread.
|
||||
static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
|
||||
swift::Module *M,
|
||||
SILModule *SILMod,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName,
|
||||
llvm::LLVMContext &LLVMContext,
|
||||
SourceFile *SF = nullptr,
|
||||
@@ -689,6 +689,9 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
|
||||
|
||||
embedBitcode(IGM.getModule(), Opts);
|
||||
|
||||
// Free the memory occupied by the SILModule.
|
||||
SILMod.reset(nullptr);
|
||||
|
||||
if (performLLVM(Opts, IGM.Context.Diags, nullptr, IGM.ModuleHash,
|
||||
IGM.getModule(), IGM.TargetMachine.get(),
|
||||
IGM.Context.LangOpts.EffectiveLanguageVersion,
|
||||
@@ -725,7 +728,7 @@ static void ThreadEntryPoint(IRGenerator *irgen,
|
||||
/// All this is done in multiple threads.
|
||||
static void performParallelIRGeneration(IRGenOptions &Opts,
|
||||
swift::Module *M,
|
||||
SILModule *SILMod,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName, int numThreads) {
|
||||
|
||||
IRGenerator irgen(Opts, *SILMod);
|
||||
@@ -897,6 +900,9 @@ static void performParallelIRGeneration(IRGenOptions &Opts,
|
||||
// Bail out if there are any errors.
|
||||
if (Ctx.hadError()) return;
|
||||
|
||||
// Free the memory occupied by the SILModule.
|
||||
SILMod.reset(nullptr);
|
||||
|
||||
std::vector<std::thread> Threads;
|
||||
llvm::sys::Mutex DiagMutex;
|
||||
|
||||
@@ -916,23 +922,27 @@ static void performParallelIRGeneration(IRGenOptions &Opts,
|
||||
|
||||
|
||||
std::unique_ptr<llvm::Module> swift::
|
||||
performIRGeneration(IRGenOptions &Opts, swift::Module *M, SILModule *SILMod,
|
||||
performIRGeneration(IRGenOptions &Opts, swift::Module *M,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName, llvm::LLVMContext &LLVMContext) {
|
||||
int numThreads = SILMod->getOptions().NumThreads;
|
||||
if (numThreads != 0) {
|
||||
::performParallelIRGeneration(Opts, M, SILMod, ModuleName, numThreads);
|
||||
::performParallelIRGeneration(Opts, M, std::move(SILMod),
|
||||
ModuleName, numThreads);
|
||||
// TODO: Parallel LLVM compilation cannot be used if a (single) module is
|
||||
// needed as return value.
|
||||
return nullptr;
|
||||
}
|
||||
return ::performIRGeneration(Opts, M, SILMod, ModuleName, LLVMContext);
|
||||
return ::performIRGeneration(Opts, M, std::move(SILMod), ModuleName, LLVMContext);
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::Module> swift::
|
||||
performIRGeneration(IRGenOptions &Opts, SourceFile &SF, SILModule *SILMod,
|
||||
performIRGeneration(IRGenOptions &Opts, SourceFile &SF,
|
||||
std::unique_ptr<SILModule> SILMod,
|
||||
StringRef ModuleName, llvm::LLVMContext &LLVMContext,
|
||||
unsigned StartElem) {
|
||||
return ::performIRGeneration(Opts, SF.getParentModule(), SILMod, ModuleName,
|
||||
return ::performIRGeneration(Opts, SF.getParentModule(),
|
||||
std::move(SILMod), ModuleName,
|
||||
LLVMContext, &SF, StartElem);
|
||||
}
|
||||
|
||||
|
||||
@@ -260,9 +260,10 @@ bool swift::immediate::IRGenImportedModules(
|
||||
|
||||
// FIXME: We shouldn't need to use the global context here, but
|
||||
// something is persisting across calls to performIRGeneration.
|
||||
auto SubModule =
|
||||
performIRGeneration(IRGenOpts, import, SILMod.get(),
|
||||
import->getName().str(), getGlobalLLVMContext());
|
||||
auto SubModule = performIRGeneration(IRGenOpts, import,
|
||||
std::move(SILMod),
|
||||
import->getName().str(),
|
||||
getGlobalLLVMContext());
|
||||
|
||||
if (CI.getASTContext().hadError()) {
|
||||
hadError = true;
|
||||
@@ -298,9 +299,10 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
|
||||
auto *swiftModule = CI.getMainModule();
|
||||
// FIXME: We shouldn't need to use the global context here, but
|
||||
// something is persisting across calls to performIRGeneration.
|
||||
auto ModuleOwner =
|
||||
performIRGeneration(IRGenOpts, swiftModule, CI.getSILModule(),
|
||||
swiftModule->getName().str(), getGlobalLLVMContext());
|
||||
auto ModuleOwner = performIRGeneration(IRGenOpts, swiftModule,
|
||||
std::move(CI.takeSILModule()),
|
||||
swiftModule->getName().str(),
|
||||
getGlobalLLVMContext());
|
||||
auto *Module = ModuleOwner.get();
|
||||
|
||||
if (Context.hadError())
|
||||
|
||||
@@ -860,9 +860,11 @@ private:
|
||||
// IRGen the current line(s).
|
||||
// FIXME: We shouldn't need to use the global context here, but
|
||||
// something is persisting across calls to performIRGeneration.
|
||||
auto LineModule =
|
||||
performIRGeneration(IRGenOpts, REPLInputFile, sil.get(), "REPLLine",
|
||||
getGlobalLLVMContext(), RC.CurIRGenElem);
|
||||
auto LineModule = performIRGeneration(IRGenOpts, REPLInputFile,
|
||||
std::move(sil),
|
||||
"REPLLine",
|
||||
getGlobalLLVMContext(),
|
||||
RC.CurIRGenElem);
|
||||
RC.CurIRGenElem = RC.CurElem;
|
||||
|
||||
if (CI.getASTContext().hadError())
|
||||
|
||||
Reference in New Issue
Block a user