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
@@ -508,6 +509,15 @@ createOptRecordFile(StringRef Filename, DiagnosticEngine &DE) {
508
509
return File;
509
510
}
510
511
512
+ static bool performCompileStepsPostSILGen (CompilerInstance &Instance,
513
+ CompilerInvocation &Invocation,
514
+ std::unique_ptr<SILModule> SM,
515
+ bool astGuaranteedToCorrespondToSIL,
516
+ bool moduleIsPublic,
517
+ int &ReturnValue,
518
+ FrontendObserver *observer,
519
+ UnifiedStatsReporter *Stats);
520
+
511
521
// / Performs the compile requested by the user.
512
522
// / \param Instance Will be reset after performIRGeneration when the verifier
513
523
// / mode is NoVerify and there were no errors.
@@ -773,7 +783,7 @@ static bool performCompile(CompilerInstance &Instance,
773
783
return Context.hadError ();
774
784
}
775
785
776
- const auto &SILOpts = Invocation.getSILOptions ();
786
+ auto &SILOpts = Invocation.getSILOptions ();
777
787
if (!opts.InputsAndOutputs .preBatchModeTBDPath ().empty ()) {
778
788
auto installName = opts.TBDInstallName .empty ()
779
789
? " lib" + Invocation.getModuleName ().str () + " .dylib"
@@ -787,43 +797,85 @@ static bool performCompile(CompilerInstance &Instance,
787
797
assert (Action >= FrontendOptions::ActionType::EmitSILGen &&
788
798
" All actions not requiring SILGen must have been handled!" );
789
799
790
- std::unique_ptr<SILModule> SM = Instance.takeSILModule ();
791
- // Records whether the SIL is directly computed from the AST we have, meaning
792
- // that it will exactly match the source. It might not if, for instance, some
793
- // of the inputs are SIB with extra explicit SIL.
794
- auto astGuaranteedToCorrespondToSIL = false ;
795
- if (!SM) {
800
+ // The second boolean in each std::pair<> in this std::deque<> indicates
801
+ // whether the SIL is guaranteed to correspond to the the AST. This might be
802
+ // false if we loaded SIL from an SIB.
803
+ std::deque<std::pair<std::unique_ptr<SILModule>, bool >> SMs;
804
+ if (auto SM = Instance.takeSILModule ()) {
805
+ SMs.push_back (std::make_pair (std::move (SM), false ));
806
+ }
807
+
808
+ if (SMs.empty ()) {
809
+ auto mod = Instance.getMainModule ();
796
810
auto fileIsSIB = [](const FileUnit *File) -> bool {
797
811
auto SASTF = dyn_cast<SerializedASTFile>(File);
798
812
return SASTF && SASTF->isSIB ();
799
813
};
800
- if (opts.Inputs .hasPrimaries ()) {
801
- FileUnit *PrimaryFile = Instance.getPrimarySourceFile ();
802
- if (!PrimaryFile) {
803
- for (FileUnit *fileUnit : Instance.getMainModule ()->getFiles ()) {
814
+ if (opts.InputsAndOutputs .hasPrimaries ()) {
815
+ if (Instance.getPrimarySourceFiles ().empty ()) {
816
+ // If we have primary inputs but no primary _source files_, we might
817
+ // have a primary serialized input.
818
+ for (FileUnit *fileUnit : mod->getFiles ()) {
804
819
if (auto SASTF = dyn_cast<SerializedASTFile>(fileUnit)) {
805
820
if (Invocation.getFrontendOptions ().InputsAndOutputs .isFilePrimary (
806
- InputFile::
807
- convertBufferNameFromLLVM_getFileOrSTDIN_toSwiftConventions (
808
- SASTF->getFilename ()))) {
809
- assert (!PrimaryFile && " Can only handle one primary so far" );
810
- PrimaryFile = fileUnit;
821
+ InputFile::
822
+ convertBufferNameFromLLVM_getFileOrSTDIN_toSwiftConventions (
823
+ SASTF->getFilename ()))) {
824
+ assert (SMs.empty () && " Can only handle one primary AST input" );
825
+ auto SM = performSILGeneration (*SASTF, SILOpts, None);
826
+ SMs.push_back (std::make_pair (std::move (SM), !fileIsSIB (SASTF)));
811
827
}
812
828
}
813
829
}
830
+ } else {
831
+ // If we have multiple primary inputs, build a separate SILModule for
832
+ // each source file, and run the remaining SILOpt-Serialize-IRGen-LLVM
833
+ // once for each such input.
834
+ for (auto *PrimaryFile : Instance.getPrimarySourceFiles ()) {
835
+ auto SM = performSILGeneration (*PrimaryFile, SILOpts, None);
836
+ SMs.push_back (std::make_pair (std::move (SM), !fileIsSIB (PrimaryFile)));
837
+ }
814
838
}
815
- astGuaranteedToCorrespondToSIL = !fileIsSIB (PrimaryFile);
816
- SM = performSILGeneration (*PrimaryFile, Invocation.getSILOptions (),
817
- None);
818
839
} else {
819
- auto mod = Instance.getMainModule ();
820
- astGuaranteedToCorrespondToSIL =
821
- llvm::none_of (mod->getFiles (), fileIsSIB);
822
- SM = performSILGeneration (mod, Invocation.getSILOptions (),
823
- true );
840
+ // If we have no primary inputs we are in WMO mode and need to build a
841
+ // SILModule for the entire module.
842
+ auto SM = performSILGeneration (mod, SILOpts, true );
843
+ SMs.push_back (std::make_pair (std::move (SM),
844
+ llvm::none_of (mod->getFiles (),
845
+ fileIsSIB)));
824
846
}
825
847
}
826
848
849
+ while (!SMs.empty ()) {
850
+ auto pair = std::move (SMs.front ());
851
+ SMs.pop_front ();
852
+ if (performCompileStepsPostSILGen (Instance, Invocation,
853
+ std::move (pair.first ),
854
+ pair.second ,
855
+ moduleIsPublic,
856
+ ReturnValue, observer, Stats))
857
+ return true ;
858
+ }
859
+ return false ;
860
+ }
861
+
862
+
863
+ static bool performCompileStepsPostSILGen (CompilerInstance &Instance,
864
+ CompilerInvocation &Invocation,
865
+ std::unique_ptr<SILModule> SM,
866
+ bool astGuaranteedToCorrespondToSIL,
867
+ bool moduleIsPublic,
868
+ int &ReturnValue,
869
+ FrontendObserver *observer,
870
+ UnifiedStatsReporter *Stats) {
871
+
872
+ FrontendOptions opts = Invocation.getFrontendOptions ();
873
+ FrontendOptions::ActionType Action = opts.RequestedAction ;
874
+ ASTContext &Context = Instance.getASTContext ();
875
+ SILOptions &SILOpts = Invocation.getSILOptions ();
876
+ IRGenOptions &IRGenOpts = Invocation.getIRGenOptions ();
877
+ bool shouldIndex = !opts.IndexStorePath .empty ();
878
+
827
879
if (observer) {
828
880
observer->performedSILGeneration (*SM);
829
881
}
0 commit comments