Skip to content

Commit 695174a

Browse files
authored
Merge pull request #9260 from akyrtzi/dont-destroy-compiler-instance2
[frontend] Don't destroy the compiler instance object inside performCompile()
2 parents 144dc55 + cda147f commit 695174a

File tree

3 files changed

+54
-49
lines changed

3 files changed

+54
-49
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ class CompilerInstance {
426426
/// Parses the input file but does no type-checking or module imports.
427427
/// Note that this only supports parsing an invocation with a single file.
428428
void performParseOnly();
429+
430+
/// Frees up the ASTContext and SILModule objects that this instance is
431+
/// holding on.
432+
void freeContextAndSIL();
429433
};
430434

431435
} // namespace swift

lib/Frontend/Frontend.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,3 +634,8 @@ void CompilerInstance::performParseOnly() {
634634
assert(Context->LoadedModules.size() == 1 &&
635635
"Loaded a module during parse-only");
636636
}
637+
638+
void CompilerInstance::freeContextAndSIL() {
639+
Context.reset();
640+
TheSILModule.reset();
641+
}

lib/FrontendTool/FrontendTool.cpp

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static void countStatsPostSILOpt(UnifiedStatsReporter &Stats,
426426
/// \param Instance Will be reset after performIRGeneration when the verifier
427427
/// mode is NoVerify and there were no errors.
428428
/// \returns true on error
429-
static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
429+
static bool performCompile(CompilerInstance &Instance,
430430
CompilerInvocation &Invocation,
431431
ArrayRef<const char *> Args,
432432
int &ReturnValue,
@@ -439,7 +439,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
439439
// avoid touching any other inputs and just parse, emit and exit.
440440
if (Action == FrontendOptions::EmitPCH) {
441441
auto clangImporter = static_cast<ClangImporter *>(
442-
Instance->getASTContext().getClangModuleLoader());
442+
Instance.getASTContext().getClangModuleLoader());
443443
return clangImporter->emitBridgingPCH(
444444
Invocation.getInputFilenames()[0],
445445
opts.getSingleOutputFilename());
@@ -457,7 +457,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
457457
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
458458
llvm::MemoryBuffer::getFileOrSTDIN(Invocation.getInputFilenames()[0]);
459459
if (!FileBufOrErr) {
460-
Instance->getASTContext().Diags.diagnose(SourceLoc(),
460+
Instance.getASTContext().Diags.diagnose(SourceLoc(),
461461
diag::error_open_input_file,
462462
Invocation.getInputFilenames()[0],
463463
FileBufOrErr.getError().message());
@@ -472,7 +472,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
472472
if (!Module) {
473473
// TODO: Translate from the diagnostic info to the SourceManager location
474474
// if available.
475-
Instance->getASTContext().Diags.diagnose(SourceLoc(),
475+
Instance.getASTContext().Diags.diagnose(SourceLoc(),
476476
diag::error_parse_input_file,
477477
Invocation.getInputFilenames()[0],
478478
Err.getMessage());
@@ -482,31 +482,31 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
482482
// TODO: remove once the frontend understands what action it should perform
483483
IRGenOpts.OutputKind = getOutputKind(Action);
484484

485-
return performLLVM(IRGenOpts, Instance->getASTContext(), Module.get());
485+
return performLLVM(IRGenOpts, Instance.getASTContext(), Module.get());
486486
}
487487

488488
ReferencedNameTracker nameTracker;
489489
bool shouldTrackReferences = !opts.ReferenceDependenciesFilePath.empty();
490490
if (shouldTrackReferences)
491-
Instance->setReferencedNameTracker(&nameTracker);
491+
Instance.setReferencedNameTracker(&nameTracker);
492492

493493
if (Action == FrontendOptions::Parse ||
494494
Action == FrontendOptions::DumpParse ||
495495
Action == FrontendOptions::DumpInterfaceHash ||
496496
Action == FrontendOptions::EmitImportedModules)
497-
Instance->performParseOnly();
497+
Instance.performParseOnly();
498498
else
499-
Instance->performSema();
499+
Instance.performSema();
500500

501501
if (Action == FrontendOptions::Parse)
502-
return Instance->getASTContext().hadError();
502+
return Instance.getASTContext().hadError();
503503

504504
if (observer) {
505-
observer->performedSemanticAnalysis(*Instance);
505+
observer->performedSemanticAnalysis(Instance);
506506
}
507507

508508
if (Stats) {
509-
countStatsPostSema(*Stats, *Instance);
509+
countStatsPostSema(*Stats, Instance);
510510
}
511511

512512
FrontendOptions::DebugCrashMode CrashMode = opts.CrashMode;
@@ -515,19 +515,19 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
515515
else if (CrashMode == FrontendOptions::DebugCrashMode::CrashAfterParse)
516516
debugFailWithCrash();
517517

518-
ASTContext &Context = Instance->getASTContext();
518+
ASTContext &Context = Instance.getASTContext();
519519

520520
if (Invocation.getMigratorOptions().shouldRunMigrator()) {
521-
migrator::updateCodeAndEmitRemap(Instance.get(), Invocation);
521+
migrator::updateCodeAndEmitRemap(&Instance, Invocation);
522522
}
523523

524524
if (Action == FrontendOptions::REPL) {
525-
runREPL(*Instance, ProcessCmdLine(Args.begin(), Args.end()),
525+
runREPL(Instance, ProcessCmdLine(Args.begin(), Args.end()),
526526
Invocation.getParseStdlib());
527527
return Context.hadError();
528528
}
529529

530-
SourceFile *PrimarySourceFile = Instance->getPrimarySourceFile();
530+
SourceFile *PrimarySourceFile = Instance.getPrimarySourceFile();
531531

532532
// We've been told to dump the AST (either after parsing or type-checking,
533533
// which is already differentiated in CompilerInstance::performSema()),
@@ -541,7 +541,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
541541
SourceFile *SF = PrimarySourceFile;
542542
if (!SF) {
543543
SourceFileKind Kind = Invocation.getSourceFileKind();
544-
SF = &Instance->getMainModule()->getMainSourceFile(Kind);
544+
SF = &Instance.getMainModule()->getMainSourceFile(Kind);
545545
}
546546
if (Action == FrontendOptions::PrintAST)
547547
SF->print(llvm::outs(), PrintOptions::printEverything());
@@ -551,7 +551,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
551551
if (opts.DumpScopeMapLocations.empty()) {
552552
scope.expandAll();
553553
} else if (auto bufferID = SF->getBufferID()) {
554-
SourceManager &sourceMgr = Instance->getSourceMgr();
554+
SourceManager &sourceMgr = Instance.getSourceMgr();
555555
// Probe each of the locations, and dump what we find.
556556
for (auto lineColumn : opts.DumpScopeMapLocations) {
557557
SourceLoc loc = sourceMgr.getLocForLineCol(*bufferID,
@@ -597,7 +597,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
597597
SF->dump();
598598
return Context.hadError();
599599
} else if (Action == FrontendOptions::EmitImportedModules) {
600-
emitImportedModules(Context, Instance->getMainModule(), opts);
600+
emitImportedModules(Context, Instance.getMainModule(), opts);
601601
return Context.hadError();
602602
}
603603

@@ -606,15 +606,15 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
606606
Context.getClangModuleLoader()->printStatistics();
607607

608608
if (!opts.DependenciesFilePath.empty())
609-
(void)emitMakeDependencies(Context.Diags, *Instance->getDependencyTracker(),
609+
(void)emitMakeDependencies(Context.Diags, *Instance.getDependencyTracker(),
610610
opts);
611611

612612
if (shouldTrackReferences)
613-
emitReferenceDependencies(Context.Diags, Instance->getPrimarySourceFile(),
614-
*Instance->getDependencyTracker(), opts);
613+
emitReferenceDependencies(Context.Diags, Instance.getPrimarySourceFile(),
614+
*Instance.getDependencyTracker(), opts);
615615

616616
if (!opts.LoadedModuleTracePath.empty())
617-
(void)emitLoadedModuleTrace(Context, *Instance->getDependencyTracker(),
617+
(void)emitLoadedModuleTrace(Context, *Instance.getDependencyTracker(),
618618
opts);
619619

620620
if (Context.hadError())
@@ -623,39 +623,39 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
623623
// FIXME: This is still a lousy approximation of whether the module file will
624624
// be externally consumed.
625625
bool moduleIsPublic =
626-
!Instance->getMainModule()->hasEntryPoint() &&
626+
!Instance.getMainModule()->hasEntryPoint() &&
627627
opts.ImplicitObjCHeaderPath.empty() &&
628628
!Context.LangOpts.EnableAppExtensionRestrictions;
629629

630630
// We've just been told to perform a typecheck, so we can return now.
631631
if (Action == FrontendOptions::Typecheck) {
632632
if (!opts.ObjCHeaderOutputPath.empty())
633-
return printAsObjC(opts.ObjCHeaderOutputPath, Instance->getMainModule(),
633+
return printAsObjC(opts.ObjCHeaderOutputPath, Instance.getMainModule(),
634634
opts.ImplicitObjCHeaderPath, moduleIsPublic);
635635
return Context.hadError();
636636
}
637637

638638
if (Action == FrontendOptions::EmitTBD) {
639639
auto hasMultipleIRGenThreads = Invocation.getSILOptions().NumThreads > 1;
640-
return writeTBD(Instance->getMainModule(), hasMultipleIRGenThreads,
640+
return writeTBD(Instance.getMainModule(), hasMultipleIRGenThreads,
641641
opts.getSingleOutputFilename());
642642
}
643643

644644
assert(Action >= FrontendOptions::EmitSILGen &&
645645
"All actions not requiring SILGen must have been handled!");
646646

647-
std::unique_ptr<SILModule> SM = Instance->takeSILModule();
647+
std::unique_ptr<SILModule> SM = Instance.takeSILModule();
648648
if (!SM) {
649649
if (opts.PrimaryInput.hasValue() && opts.PrimaryInput.getValue().isFilename()) {
650650
FileUnit *PrimaryFile = PrimarySourceFile;
651651
if (!PrimaryFile) {
652652
auto Index = opts.PrimaryInput.getValue().Index;
653-
PrimaryFile = Instance->getMainModule()->getFiles()[Index];
653+
PrimaryFile = Instance.getMainModule()->getFiles()[Index];
654654
}
655655
SM = performSILGeneration(*PrimaryFile, Invocation.getSILOptions(),
656656
None, opts.SILSerializeAll);
657657
} else {
658-
SM = performSILGeneration(Instance->getMainModule(), Invocation.getSILOptions(),
658+
SM = performSILGeneration(Instance.getMainModule(), Invocation.getSILOptions(),
659659
opts.SILSerializeAll,
660660
true);
661661
}
@@ -673,7 +673,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
673673
// If we are asked to link all, link all.
674674
if (Invocation.getSILOptions().LinkMode == SILOptions::LinkAll)
675675
performSILLinking(SM.get(), true);
676-
return writeSIL(*SM, Instance->getMainModule(), opts.EmitVerboseSIL,
676+
return writeSIL(*SM, Instance.getMainModule(), opts.EmitVerboseSIL,
677677
opts.getSingleOutputFilename(), opts.EmitSortedSIL);
678678
}
679679

@@ -683,7 +683,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
683683
performSILLinking(SM.get(), true);
684684

685685
auto DC = PrimarySourceFile ? ModuleOrSourceFile(PrimarySourceFile) :
686-
Instance->getMainModule();
686+
Instance.getMainModule();
687687
if (!opts.ModuleOutputPath.empty()) {
688688
SerializationOptions serializationOpts;
689689
serializationOpts.OutputPath = opts.ModuleOutputPath.c_str();
@@ -769,13 +769,13 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
769769
}
770770

771771
if (!opts.ObjCHeaderOutputPath.empty()) {
772-
(void)printAsObjC(opts.ObjCHeaderOutputPath, Instance->getMainModule(),
772+
(void)printAsObjC(opts.ObjCHeaderOutputPath, Instance.getMainModule(),
773773
opts.ImplicitObjCHeaderPath, moduleIsPublic);
774774
}
775775

776776
if (Action == FrontendOptions::EmitSIB) {
777777
auto DC = PrimarySourceFile ? ModuleOrSourceFile(PrimarySourceFile) :
778-
Instance->getMainModule();
778+
Instance.getMainModule();
779779
if (!opts.ModuleOutputPath.empty()) {
780780
SerializationOptions serializationOpts;
781781
serializationOpts.OutputPath = opts.ModuleOutputPath.c_str();
@@ -789,7 +789,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
789789

790790
if (!opts.ModuleOutputPath.empty() || !opts.ModuleDocOutputPath.empty()) {
791791
auto DC = PrimarySourceFile ? ModuleOrSourceFile(PrimarySourceFile) :
792-
Instance->getMainModule();
792+
Instance.getMainModule();
793793
if (!opts.ModuleOutputPath.empty()) {
794794
SerializationOptions serializationOpts;
795795
serializationOpts.OutputPath = opts.ModuleOutputPath.c_str();
@@ -824,7 +824,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
824824

825825
// We've been told to write canonical SIL, so write it now.
826826
if (Action == FrontendOptions::EmitSIL) {
827-
return writeSIL(*SM, Instance->getMainModule(), opts.EmitVerboseSIL,
827+
return writeSIL(*SM, Instance.getMainModule(), opts.EmitVerboseSIL,
828828
opts.getSingleOutputFilename(), opts.EmitSortedSIL);
829829
}
830830

@@ -848,14 +848,14 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
848848
IRGenOpts.DebugInfoKind = IRGenDebugInfoKind::Normal;
849849
const ProcessCmdLine &CmdLine = ProcessCmdLine(opts.ImmediateArgv.begin(),
850850
opts.ImmediateArgv.end());
851-
Instance->setSILModule(std::move(SM));
851+
Instance.setSILModule(std::move(SM));
852852

853853
if (observer) {
854-
observer->aboutToRunImmediately(*Instance);
854+
observer->aboutToRunImmediately(Instance);
855855
}
856856

857857
ReturnValue =
858-
RunImmediately(*Instance, CmdLine, IRGenOpts, Invocation.getSILOptions());
858+
RunImmediately(Instance, CmdLine, IRGenOpts, Invocation.getSILOptions());
859859
return Context.hadError();
860860
}
861861

@@ -869,14 +869,14 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
869869
opts.getSingleOutputFilename(), LLVMContext,
870870
0, &HashGlobal);
871871
} else {
872-
IRModule = performIRGeneration(IRGenOpts, Instance->getMainModule(),
872+
IRModule = performIRGeneration(IRGenOpts, Instance.getMainModule(),
873873
std::move(SM),
874874
opts.getSingleOutputFilename(), LLVMContext,
875875
&HashGlobal);
876876
}
877877

878878
// Just because we had an AST error it doesn't mean we can't performLLVM.
879-
bool HadError = Instance->getASTContext().hadError();
879+
bool HadError = Instance.getASTContext().hadError();
880880

881881
// If the AST Context has no errors but no IRModule is available,
882882
// parallelIRGen happened correctly, since parallel IRGen produces multiple
@@ -896,7 +896,7 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
896896
error =
897897
validateTBD(PrimarySourceFile, *IRModule, hasMultipleIRGenThreads);
898898
else
899-
error = validateTBD(Instance->getMainModule(), *IRModule,
899+
error = validateTBD(Instance.getMainModule(), *IRModule,
900900
hasMultipleIRGenThreads);
901901
if (error)
902902
return true;
@@ -906,15 +906,11 @@ static bool performCompile(std::unique_ptr<CompilerInstance> &Instance,
906906
createTargetMachine(IRGenOpts, Context);
907907
version::Version EffectiveLanguageVersion =
908908
Context.LangOpts.EffectiveLanguageVersion;
909+
910+
// Free up some compiler resources now that we have an IRModule.
911+
Instance.freeContextAndSIL();
912+
909913
DiagnosticEngine &Diags = Context.Diags;
910-
const DiagnosticOptions &DiagOpts = Invocation.getDiagnosticOptions();
911-
912-
// Delete the compiler instance now that we have an IRModule.
913-
if (DiagOpts.VerifyMode == DiagnosticOptions::NoVerify) {
914-
SM.reset();
915-
Instance.reset();
916-
}
917-
918914
// Now that we have a single IR Module, hand it over to performLLVM.
919915
return performLLVM(IRGenOpts, &Diags, nullptr, HashGlobal, IRModule.get(),
920916
TargetMachine.get(), EffectiveLanguageVersion,
@@ -1189,7 +1185,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
11891185

11901186
int ReturnValue = 0;
11911187
bool HadError =
1192-
performCompile(Instance, Invocation, Args, ReturnValue, observer,
1188+
performCompile(*Instance, Invocation, Args, ReturnValue, observer,
11931189
StatsReporter.get());
11941190

11951191
if (!HadError) {

0 commit comments

Comments
 (0)