@@ -670,6 +670,7 @@ static bool diagnoseCycle(CompilerInstance &instance,
670
670
}
671
671
672
672
static bool scanModuleDependencies (CompilerInstance &instance,
673
+ ModuleDependenciesCache &cache,
673
674
StringRef moduleName,
674
675
bool isClang,
675
676
StringRef outputPath) {
@@ -681,10 +682,6 @@ static bool scanModuleDependencies(CompilerInstance &instance,
681
682
682
683
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
683
684
std::set<ModuleDependencyID>> allModules;
684
- // Retrieve the instance's module dependency cache.
685
- ModuleDependenciesCache *cache = instance.getModuleDependencyCache ();
686
- assert (cache &&
687
- " Dependency Scanner expected a ModuleDependenciesCache on a compiler instance." );
688
685
InterfaceSubContextDelegateImpl ASTDelegate (ctx.SourceMgr , ctx.Diags ,
689
686
ctx.SearchPathOpts , ctx.LangOpts ,
690
687
ctx.ClangImporterOpts ,
@@ -700,11 +697,11 @@ static bool scanModuleDependencies(CompilerInstance &instance,
700
697
if (isClang) {
701
698
// Loading the clang module using Clang importer.
702
699
// This action will populate the cache with the main module's dependencies.
703
- rootDeps = ctx.getModuleDependencies (moduleName, /* IsClang*/ true , * cache,
700
+ rootDeps = ctx.getModuleDependencies (moduleName, /* IsClang*/ true , cache,
704
701
ASTDelegate);
705
702
} else {
706
703
// Loading the swift module's dependencies.
707
- rootDeps = ctx.getSwiftModuleDependencies (moduleName, * cache, ASTDelegate);
704
+ rootDeps = ctx.getSwiftModuleDependencies (moduleName, cache, ASTDelegate);
708
705
}
709
706
if (!rootDeps.hasValue ()) {
710
707
// We cannot find the clang module, abort.
@@ -726,16 +723,17 @@ static bool scanModuleDependencies(CompilerInstance &instance,
726
723
++currentModuleIdx) {
727
724
auto module = allModules[currentModuleIdx];
728
725
auto discoveredModules =
729
- resolveDirectDependencies (instance, module , * cache, ASTDelegate);
726
+ resolveDirectDependencies (instance, module , cache, ASTDelegate);
730
727
allModules.insert (discoveredModules.begin (), discoveredModules.end ());
731
728
}
732
729
// Write out the JSON description.
733
- writeJSON (out, instance, * cache, ASTDelegate, allModules.getArrayRef ());
730
+ writeJSON (out, instance, cache, ASTDelegate, allModules.getArrayRef ());
734
731
return false ;
735
732
}
736
733
737
734
bool swift::scanClangDependencies (CompilerInstance &instance) {
738
- return scanModuleDependencies (instance,
735
+ ModuleDependenciesCache cache;
736
+ return scanModuleDependencies (instance, cache,
739
737
instance.getMainModule ()->getNameStr (),
740
738
/* isClang*/ true ,
741
739
instance.getInvocation ().getFrontendOptions ()
@@ -745,6 +743,9 @@ bool swift::scanClangDependencies(CompilerInstance &instance) {
745
743
bool swift::batchScanModuleDependencies (CompilerInstance &instance,
746
744
llvm::StringRef batchInputFile) {
747
745
const CompilerInvocation &invok = instance.getInvocation ();
746
+ // The primary cache used for scans carried out with the compiler instance
747
+ // we have created
748
+ ModuleDependenciesCache cache;
748
749
749
750
(void )instance.getMainModule ();
750
751
llvm::BumpPtrAllocator alloc;
@@ -755,20 +756,31 @@ bool swift::batchScanModuleDependencies(CompilerInstance &instance,
755
756
return true ;
756
757
auto &diags = instance.getDiags ();
757
758
ForwardingDiagnosticConsumer FDC (diags);
758
- // Keep track of all compiler instances we have created.
759
- llvm::StringMap<std::unique_ptr<CompilerInstance>> subInstanceMap;
759
+
760
+ // Keep track of all compiler instances and dependency caches we have created.
761
+ // TODO: Re-use a single cache across all invocations, once `alreadySeen`
762
+ // state is no longer shared.
763
+ llvm::StringMap<std::pair<std::unique_ptr<CompilerInstance>,
764
+ std::unique_ptr<ModuleDependenciesCache>>> subInstanceMap;
760
765
for (auto &entry: *results) {
761
766
CompilerInstance *pInstance = nullptr ;
767
+ ModuleDependenciesCache *pCache = nullptr ;
762
768
if (entry.arguments .empty ()) {
763
769
// Use the compiler's instance if no arguments are specified.
764
770
pInstance = &instance;
771
+ pCache = &cache;
765
772
} else if (subInstanceMap.count (entry.arguments )) {
766
773
// Use the previously created instance if we've seen the arguments before.
767
- pInstance = subInstanceMap[entry.arguments ].get ();
774
+ pInstance = subInstanceMap[entry.arguments ].first .get ();
775
+ pCache = subInstanceMap[entry.arguments ].second .get ();
768
776
} else {
769
777
// Create a new instance by the arguments and save it in the map.
770
- pInstance = subInstanceMap.insert ({entry.arguments ,
771
- std::make_unique<CompilerInstance>()}).first ->getValue ().get ();
778
+ subInstanceMap.insert ({entry.arguments ,
779
+ std::make_pair (std::make_unique<CompilerInstance>(),
780
+ std::make_unique<ModuleDependenciesCache>())});
781
+
782
+ pInstance = subInstanceMap[entry.arguments ].first .get ();
783
+ pCache = subInstanceMap[entry.arguments ].second .get ();
772
784
SmallVector<const char *, 4 > args;
773
785
llvm::cl::TokenizeGNUCommandLine (entry.arguments , saver, args);
774
786
CompilerInvocation subInvok = invok;
@@ -786,8 +798,8 @@ bool swift::batchScanModuleDependencies(CompilerInstance &instance,
786
798
}
787
799
assert (pInstance);
788
800
// Scan using the chosen compiler instance.
789
- if (scanModuleDependencies (*pInstance, entry. moduleName , ! entry.isSwift ,
790
- entry.outputPath )) {
801
+ if (scanModuleDependencies (*pInstance, *pCache, entry.moduleName ,
802
+ !entry. isSwift , entry.outputPath )) {
791
803
return true ;
792
804
}
793
805
}
@@ -801,6 +813,8 @@ bool swift::scanAndOutputDependencies(CompilerInstance &instance) {
801
813
std::error_code EC;
802
814
llvm::raw_fd_ostream out (path, EC, llvm::sys::fs::F_None);
803
815
816
+ ModuleDependenciesCache SingleUseCache;
817
+
804
818
if (out.has_error () || EC) {
805
819
Context.Diags .diagnose (SourceLoc (), diag::error_opening_output, path,
806
820
EC.message ());
@@ -809,10 +823,11 @@ bool swift::scanAndOutputDependencies(CompilerInstance &instance) {
809
823
}
810
824
811
825
// Execute scan, writing JSON output to the output stream
812
- return scanDependencies (instance, out);
826
+ return scanDependencies (instance, SingleUseCache, out);
813
827
}
814
828
815
829
bool swift::scanDependencies (CompilerInstance &instance,
830
+ ModuleDependenciesCache &cache,
816
831
llvm::raw_ostream &out) {
817
832
ASTContext &Context = instance.getASTContext ();
818
833
ModuleDecl *mainModule = instance.getMainModule ();
@@ -900,11 +915,7 @@ bool swift::scanDependencies(CompilerInstance &instance,
900
915
901
916
allModules.insert ({mainModuleName.str (), mainDependencies.getKind ()});
902
917
903
- // Retrieve the instance's module dependency cache.
904
- ModuleDependenciesCache *cache = instance.getModuleDependencyCache ();
905
- assert (cache &&
906
- " Dependency Scanner expected a ModuleDependenciesCache on a compiler instance." );
907
- cache->recordDependencies (mainModuleName, std::move (mainDependencies));
918
+ cache.recordDependencies (mainModuleName, std::move (mainDependencies));
908
919
909
920
auto &ctx = instance.getASTContext ();
910
921
auto ModuleCachePath = getModuleCachePathFromClang (ctx
@@ -927,28 +938,28 @@ bool swift::scanDependencies(CompilerInstance &instance,
927
938
++currentModuleIdx) {
928
939
auto module = allModules[currentModuleIdx];
929
940
auto discoveredModules =
930
- resolveDirectDependencies (instance, module , * cache, ASTDelegate);
941
+ resolveDirectDependencies (instance, module , cache, ASTDelegate);
931
942
allModules.insert (discoveredModules.begin (), discoveredModules.end ());
932
943
}
933
944
934
945
// We have all explicit imports now, resolve cross import overlays.
935
946
discoverCrosssImportOverlayDependencies (instance, mainModuleName,
936
- /* All transitive dependencies*/ allModules.getArrayRef ().slice (1 ), * cache,
947
+ /* All transitive dependencies*/ allModules.getArrayRef ().slice (1 ), cache,
937
948
ASTDelegate, [&](ModuleDependencyID id) {
938
949
allModules.insert (id);
939
950
});
940
951
941
952
// Dignose cycle in dependency graph.
942
- if (diagnoseCycle (instance, * cache, /* MainModule*/ allModules.front (), ASTDelegate))
953
+ if (diagnoseCycle (instance, cache, /* MainModule*/ allModules.front (), ASTDelegate))
943
954
return true ;
944
955
945
956
// Write out the JSON description.
946
- writeJSON (out, instance, * cache, ASTDelegate, allModules.getArrayRef ());
957
+ writeJSON (out, instance, cache, ASTDelegate, allModules.getArrayRef ());
947
958
948
959
// Update the dependency tracker.
949
960
if (auto depTracker = instance.getDependencyTracker ()) {
950
961
for (auto module : allModules) {
951
- auto deps = cache-> findDependencies (module .first , module .second );
962
+ auto deps = cache. findDependencies (module .first , module .second );
952
963
if (!deps)
953
964
continue ;
954
965
0 commit comments