79
79
#include " llvm/Support/YAMLTraits.h"
80
80
#include " llvm/Target/TargetMachine.h"
81
81
82
+ #include < deque>
82
83
#include < memory>
83
84
#include < unordered_set>
84
85
@@ -503,6 +504,15 @@ createOptRecordFile(StringRef Filename, DiagnosticEngine &DE) {
503
504
return File;
504
505
}
505
506
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
+
506
516
// / Performs the compile requested by the user.
507
517
// / \param Instance Will be reset after performIRGeneration when the verifier
508
518
// / mode is NoVerify and there were no errors.
@@ -759,7 +769,7 @@ static bool performCompile(CompilerInstance &Instance,
759
769
return Context.hadError ();
760
770
}
761
771
762
- const auto &SILOpts = Invocation.getSILOptions ();
772
+ auto &SILOpts = Invocation.getSILOptions ();
763
773
if (!opts.TBDPath .empty ()) {
764
774
auto installName = opts.TBDInstallName .empty ()
765
775
? " lib" + Invocation.getModuleName ().str () + " .dylib"
@@ -773,43 +783,85 @@ static bool performCompile(CompilerInstance &Instance,
773
783
assert (Action >= FrontendOptions::ActionType::EmitSILGen &&
774
784
" All actions not requiring SILGen must have been handled!" );
775
785
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 ();
782
796
auto fileIsSIB = [](const FileUnit *File) -> bool {
783
797
auto SASTF = dyn_cast<SerializedASTFile>(File);
784
798
return SASTF && SASTF->isSIB ();
785
799
};
786
800
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 ()) {
790
805
if (auto SASTF = dyn_cast<SerializedASTFile>(fileUnit)) {
791
806
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)));
797
813
}
798
814
}
799
815
}
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
+ }
800
824
}
801
- astGuaranteedToCorrespondToSIL = !fileIsSIB (PrimaryFile);
802
- SM = performSILGeneration (*PrimaryFile, Invocation.getSILOptions (),
803
- None);
804
825
} 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)));
810
832
}
811
833
}
812
834
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
+
813
865
if (observer) {
814
866
observer->performedSILGeneration (*SM);
815
867
}
0 commit comments