Skip to content

Commit 859b37e

Browse files
committed
Frontend: Only build and generate a single SILModule at a time
Instead of SILGen'ing all primary files before we go on to optimize and IRGen them, run each file to completion before starting the next one. This reduces memory usage.
1 parent 01e65e1 commit 859b37e

File tree

1 file changed

+46
-51
lines changed

1 file changed

+46
-51
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
#include "llvm/Support/YAMLTraits.h"
8383
#include "llvm/Target/TargetMachine.h"
8484

85-
#include <deque>
8685
#include <memory>
8786
#include <unordered_set>
8887
#include <utility>
@@ -648,13 +647,6 @@ createOptRecordFile(StringRef Filename, DiagnosticEngine &DE) {
648647
return File;
649648
}
650649

651-
struct PostSILGenInputs {
652-
std::unique_ptr<SILModule> TheSILModule;
653-
bool ASTGuaranteedToCorrespondToSIL;
654-
ModuleOrSourceFile ModuleOrPrimarySourceFile;
655-
PrimarySpecificPaths PSPs;
656-
};
657-
658650
static bool precompileBridgingHeader(CompilerInvocation &Invocation,
659651
CompilerInstance &Instance) {
660652
auto clangImporter = static_cast<ClangImporter *>(
@@ -896,15 +888,27 @@ static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
896888
return writeTBD(Instance.getMainModule(), TBDPath, tbdOpts);
897889
}
898890

899-
static std::deque<PostSILGenInputs>
900-
generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
891+
static bool performCompileStepsPostSILGen(
892+
CompilerInstance &Instance, CompilerInvocation &Invocation,
893+
std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
894+
ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
895+
bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer,
896+
UnifiedStatsReporter *Stats);
897+
898+
static bool
899+
performCompileStepsPostSema(CompilerInvocation &Invocation,
900+
CompilerInstance &Instance,
901+
bool moduleIsPublic, int &ReturnValue,
902+
FrontendObserver *observer,
903+
UnifiedStatsReporter *Stats) {
901904
auto mod = Instance.getMainModule();
902905
if (auto SM = Instance.takeSILModule()) {
903-
std::deque<PostSILGenInputs> PSGIs;
904906
const PrimarySpecificPaths PSPs =
905907
Instance.getPrimarySpecificPathsForAtMostOnePrimary();
906-
PSGIs.push_back(PostSILGenInputs{std::move(SM), false, mod, PSPs});
907-
return PSGIs;
908+
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
909+
/*ASTGuaranteedToCorrespondToSIL=*/false,
910+
mod, PSPs, moduleIsPublic,
911+
ReturnValue, observer, Stats);
908912
}
909913

910914
SILOptions &SILOpts = Invocation.getSILOptions();
@@ -918,40 +922,51 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
918922
// If there are no primary inputs the compiler is in WMO mode and builds one
919923
// SILModule for the entire module.
920924
auto SM = performSILGeneration(mod, Instance.getSILTypes(), SILOpts);
921-
std::deque<PostSILGenInputs> PSGIs;
922925
const PrimarySpecificPaths PSPs =
923926
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
924-
PSGIs.push_back(PostSILGenInputs{
925-
std::move(SM), llvm::none_of(mod->getFiles(), fileIsSIB), mod, PSPs});
926-
return PSGIs;
927+
bool astGuaranteedToCorrespondToSIL =
928+
llvm::none_of(mod->getFiles(), fileIsSIB);
929+
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
930+
astGuaranteedToCorrespondToSIL,
931+
mod, PSPs, moduleIsPublic,
932+
ReturnValue, observer, Stats);
927933
}
928934
// If there are primary source files, build a separate SILModule for
929935
// each source file, and run the remaining SILOpt-Serialize-IRGen-LLVM
930936
// once for each such input.
931-
std::deque<PostSILGenInputs> PSGIs;
932-
for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) {
933-
auto SM = performSILGeneration(*PrimaryFile, Instance.getSILTypes(), SILOpts);
934-
const PrimarySpecificPaths PSPs =
935-
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
936-
PSGIs.push_back(PostSILGenInputs{std::move(SM), true, PrimaryFile, PSPs});
937+
if (!Instance.getPrimarySourceFiles().empty()) {
938+
bool result = false;
939+
for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) {
940+
auto SM = performSILGeneration(*PrimaryFile, Instance.getSILTypes(), SILOpts);
941+
const PrimarySpecificPaths PSPs =
942+
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
943+
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
944+
/*ASTGuaranteedToCorrespondToSIL*/true,
945+
PrimaryFile, PSPs, moduleIsPublic,
946+
ReturnValue, observer, Stats);
947+
}
948+
949+
return result;
937950
}
938-
if (!PSGIs.empty())
939-
return PSGIs;
951+
940952
// If there are primary inputs but no primary _source files_, there might be
941953
// a primary serialized input.
954+
bool result = false;
942955
for (FileUnit *fileUnit : mod->getFiles()) {
943956
if (auto SASTF = dyn_cast<SerializedASTFile>(fileUnit))
944957
if (Invocation.getFrontendOptions().InputsAndOutputs.isInputPrimary(
945958
SASTF->getFilename())) {
946-
assert(PSGIs.empty() && "Can only handle one primary AST input");
947959
auto SM = performSILGeneration(*SASTF, Instance.getSILTypes(), SILOpts);
948960
const PrimarySpecificPaths &PSPs =
949961
Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename());
950-
PSGIs.push_back(
951-
PostSILGenInputs{std::move(SM), !fileIsSIB(SASTF), mod, PSPs});
962+
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
963+
!fileIsSIB(SASTF),
964+
mod, PSPs, moduleIsPublic,
965+
ReturnValue, observer, Stats);
952966
}
953967
}
954-
return PSGIs;
968+
969+
return result;
955970
}
956971

957972
/// Emits index data for all primary inputs, or the main module.
@@ -1002,13 +1017,6 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
10021017
return hadAnyError;
10031018
}
10041019

1005-
static bool performCompileStepsPostSILGen(
1006-
CompilerInstance &Instance, CompilerInvocation &Invocation,
1007-
std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
1008-
ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
1009-
bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer,
1010-
UnifiedStatsReporter *Stats);
1011-
10121020
/// Performs the compile requested by the user.
10131021
/// \param Instance Will be reset after performIRGeneration when the verifier
10141022
/// mode is NoVerify and there were no errors.
@@ -1125,21 +1133,8 @@ static bool performCompile(CompilerInstance &Instance,
11251133
assert(FrontendOptions::doesActionGenerateSIL(Action) &&
11261134
"All actions not requiring SILGen must have been handled!");
11271135

1128-
std::deque<PostSILGenInputs> PSGIs = generateSILModules(Invocation, Instance);
1129-
1130-
while (!PSGIs.empty()) {
1131-
auto PSGI = std::move(PSGIs.front());
1132-
PSGIs.pop_front();
1133-
if (performCompileStepsPostSILGen(Instance, Invocation,
1134-
std::move(PSGI.TheSILModule),
1135-
PSGI.ASTGuaranteedToCorrespondToSIL,
1136-
PSGI.ModuleOrPrimarySourceFile,
1137-
PSGI.PSPs,
1138-
moduleIsPublic,
1139-
ReturnValue, observer, Stats))
1140-
return true;
1141-
}
1142-
return false;
1136+
return performCompileStepsPostSema(Invocation, Instance, moduleIsPublic,
1137+
ReturnValue, observer, Stats);
11431138
}
11441139

11451140
/// Get the main source file's private discriminator and attach it to

0 commit comments

Comments
 (0)