Skip to content

Commit 03c0791

Browse files
graydonDavid Ungar
authored andcommitted
[BatchMode] Split performCompile at SILGen, repeat remainder per-primary-input.
1 parent 2494b14 commit 03c0791

File tree

1 file changed

+75
-23
lines changed

1 file changed

+75
-23
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include "llvm/Support/YAMLTraits.h"
8080
#include "llvm/Target/TargetMachine.h"
8181

82+
#include <deque>
8283
#include <memory>
8384
#include <unordered_set>
8485

@@ -503,6 +504,15 @@ createOptRecordFile(StringRef Filename, DiagnosticEngine &DE) {
503504
return File;
504505
}
505506

507+
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
508+
CompilerInvocation &Invocation,
509+
std::unique_ptr<SILModule> SM,
510+
bool astGuaranteedToCorrespondToSIL,
511+
bool moduleIsPublic,
512+
int &ReturnValue,
513+
FrontendObserver *observer,
514+
UnifiedStatsReporter *Stats);
515+
506516
/// Performs the compile requested by the user.
507517
/// \param Instance Will be reset after performIRGeneration when the verifier
508518
/// mode is NoVerify and there were no errors.
@@ -759,7 +769,7 @@ static bool performCompile(CompilerInstance &Instance,
759769
return Context.hadError();
760770
}
761771

762-
const auto &SILOpts = Invocation.getSILOptions();
772+
auto &SILOpts = Invocation.getSILOptions();
763773
if (!opts.TBDPath.empty()) {
764774
auto installName = opts.TBDInstallName.empty()
765775
? "lib" + Invocation.getModuleName().str() + ".dylib"
@@ -773,43 +783,85 @@ static bool performCompile(CompilerInstance &Instance,
773783
assert(Action >= FrontendOptions::ActionType::EmitSILGen &&
774784
"All actions not requiring SILGen must have been handled!");
775785

776-
std::unique_ptr<SILModule> SM = Instance.takeSILModule();
777-
// Records whether the SIL is directly computed from the AST we have, meaning
778-
// that it will exactly match the source. It might not if, for instance, some
779-
// of the inputs are SIB with extra explicit SIL.
780-
auto astGuaranteedToCorrespondToSIL = false;
781-
if (!SM) {
786+
// The second boolean in each std::pair<> in this std::deque<> indicates
787+
// whether the SIL is guaranteed to correspond to the the AST. This might be
788+
// false if we loaded SIL from an SIB.
789+
std::deque<std::pair<std::unique_ptr<SILModule>, bool>> SMs;
790+
if (auto SM = Instance.takeSILModule()) {
791+
SMs.push_back(std::make_pair(std::move(SM), false));
792+
}
793+
794+
if (SMs.empty()) {
795+
auto mod = Instance.getMainModule();
782796
auto fileIsSIB = [](const FileUnit *File) -> bool {
783797
auto SASTF = dyn_cast<SerializedASTFile>(File);
784798
return SASTF && SASTF->isSIB();
785799
};
786800
if (opts.Inputs.hasPrimaryInputs()) {
787-
FileUnit *PrimaryFile = Instance.getPrimarySourceFile();
788-
if (!PrimaryFile) {
789-
for (FileUnit *fileUnit : Instance.getMainModule()->getFiles()) {
801+
if (Instance.getPrimarySourceFiles().empty()) {
802+
// If we have primary inputs but no primary _source files_, we might
803+
// have a primary serialized input.
804+
for (FileUnit *fileUnit : mod->getFiles()) {
790805
if (auto SASTF = dyn_cast<SerializedASTFile>(fileUnit)) {
791806
if (Invocation.getFrontendOptions().Inputs.isFilePrimary(
792-
InputFile::
793-
convertBufferNameFromLLVM_getFileOrSTDIN_toSwiftConventions(
794-
SASTF->getFilename()))) {
795-
assert(!PrimaryFile && "Can only handle one primary so far");
796-
PrimaryFile = fileUnit;
807+
InputFile::
808+
convertBufferNameFromLLVM_getFileOrSTDIN_toSwiftConventions(
809+
SASTF->getFilename()))) {
810+
assert(SMs.empty() && "Can only handle one primary AST input");
811+
auto SM = performSILGeneration(*SASTF, SILOpts, None);
812+
SMs.push_back(std::make_pair(std::move(SM), !fileIsSIB(SASTF)));
797813
}
798814
}
799815
}
816+
} else {
817+
// If we have multiple primary inputs, build a separate SILModule for
818+
// each source file, and run the remaining SILOpt-Serialize-IRGen-LLVM
819+
// once for each such input.
820+
for (auto *PrimaryFile : Instance.getPrimarySourceFiles()) {
821+
auto SM = performSILGeneration(*PrimaryFile, SILOpts, None);
822+
SMs.push_back(std::make_pair(std::move(SM), !fileIsSIB(PrimaryFile)));
823+
}
800824
}
801-
astGuaranteedToCorrespondToSIL = !fileIsSIB(PrimaryFile);
802-
SM = performSILGeneration(*PrimaryFile, Invocation.getSILOptions(),
803-
None);
804825
} else {
805-
auto mod = Instance.getMainModule();
806-
astGuaranteedToCorrespondToSIL =
807-
llvm::none_of(mod->getFiles(), fileIsSIB);
808-
SM = performSILGeneration(mod, Invocation.getSILOptions(),
809-
true);
826+
// If we have no primary inputs we are in WMO mode and need to build a
827+
// SILModule for the entire module.
828+
auto SM = performSILGeneration(mod, SILOpts, true);
829+
SMs.push_back(std::make_pair(std::move(SM),
830+
llvm::none_of(mod->getFiles(),
831+
fileIsSIB)));
810832
}
811833
}
812834

835+
while (!SMs.empty()) {
836+
auto pair = std::move(SMs.front());
837+
SMs.pop_front();
838+
if (performCompileStepsPostSILGen(Instance, Invocation,
839+
std::move(pair.first),
840+
pair.second,
841+
moduleIsPublic,
842+
ReturnValue, observer, Stats))
843+
return true;
844+
}
845+
return false;
846+
}
847+
848+
849+
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
850+
CompilerInvocation &Invocation,
851+
std::unique_ptr<SILModule> SM,
852+
bool astGuaranteedToCorrespondToSIL,
853+
bool moduleIsPublic,
854+
int &ReturnValue,
855+
FrontendObserver *observer,
856+
UnifiedStatsReporter *Stats) {
857+
858+
FrontendOptions opts = Invocation.getFrontendOptions();
859+
FrontendOptions::ActionType Action = opts.RequestedAction;
860+
ASTContext &Context = Instance.getASTContext();
861+
SILOptions &SILOpts = Invocation.getSILOptions();
862+
IRGenOptions &IRGenOpts = Invocation.getIRGenOptions();
863+
bool shouldIndex = !opts.IndexStorePath.empty();
864+
813865
if (observer) {
814866
observer->performedSILGeneration(*SM);
815867
}

0 commit comments

Comments
 (0)