From eca8925994b62096b7e25af6be6f83e88f44833b Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Tue, 9 Dec 2025 14:47:26 -0800 Subject: [PATCH] [Dependency Scanning] Add tracking of the number of dependency queries and emit them as remarks This change adds collection of three metrics to the scanner: - number of Swift module lookups - number of named Clang module lookups - recorded number of Clang modules which were imported into a Swift module by name It re-uses the prior '-Rdependency-scan-cache', renaming it to '-Rdependency-scan' and adds emission of the above metrics as remarks when this flag is enabled. Followup changes will add further remarks about dependency scanner progress. --- include/swift/AST/DiagnosticsSema.def | 16 +++ include/swift/AST/ModuleDependencies.h | 5 + .../DependencyScan/ModuleDependencyScanner.h | 115 +++++++++++------- include/swift/Frontend/FrontendOptions.h | 4 +- include/swift/Option/FrontendOptions.td | 4 +- lib/AST/ModuleDependencies.cpp | 10 +- .../ModuleDependencyScanner.cpp | 99 ++++++++++++--- lib/DependencyScan/ScanDependencies.cpp | 15 ++- .../ArgsToFrontendOptionsConverter.cpp | 2 +- test/CAS/incremental_scan.swift | 6 +- test/CAS/module_deps_include_tree.swift | 5 - test/CAS/plugin_cas.swift | 3 - .../Incremental/module_deps_invalidate.swift | 12 +- .../system_search_path_invalidate.swift | 6 +- .../Inputs/Swift/E.swiftinterface | 1 - .../Inputs/Swift/G.swiftinterface | 1 - .../basic_query_metrics.swift | 41 +++++++ .../bridging-header-autochaining.swift | 4 +- ...ing-module-found-in-serialized-paths.swift | 4 +- .../module_deps_cache_reuse.swift | 54 ++++---- .../ScanDependencies/serialized_imports.swift | 4 +- 21 files changed, 275 insertions(+), 136 deletions(-) create mode 100644 test/ScanDependencies/basic_query_metrics.swift diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 625bb628627fc..75032f534b12a 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2432,6 +2432,22 @@ WARNING(dependency_scan_module_incompatible, none, "module file '%0' is incompatible with this Swift compiler: %1", (StringRef, StringRef)) +REMARK(dependency_scan_number_swift_queries, none, + "Number of Swift module queries: '%0'", + (uint32_t)) +REMARK(dependency_scan_number_named_clang_queries, none, + "Number of named Clang module queries: '%0'", + (uint32_t)) +REMARK(dependency_scan_number_swift_dependencies, none, + "Number of recorded Swift module dependencies: '%0'", + (uint32_t)) +REMARK(dependency_scan_number_named_clang_dependencies, none, + "Number of recorded Clang module dependencies queried by-name from a Swift client: '%0'", + (uint32_t)) +REMARK(dependency_scan_number_clang_dependencies, none, + "Number of recorded Clang module dependencies: '%0'", + (uint32_t)) + ERROR(clang_dependency_scan_error, none, "clang dependency scanning failure: %0", (StringRef)) ERROR(clang_header_dependency_scan_error, none, "bridging header dependency scanning failure: %0", (StringRef)) diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index 7663b99069fb0..f70410465355f 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -1111,6 +1111,11 @@ class ModuleDependenciesCache { bool hasDependency(StringRef moduleName) const; /// Whether we have cached dependency information for the given Swift module. bool hasSwiftDependency(StringRef moduleName) const; + /// Report the number of recorded Clang dependencies + int numberOfClangDependencies() const; + /// Report the number of recorded Swift dependencies + /// (Textual + Binary) + int numberOfSwiftDependencies() const; const llvm::DenseSet & getAlreadySeenClangModules() const { diff --git a/include/swift/DependencyScan/ModuleDependencyScanner.h b/include/swift/DependencyScan/ModuleDependencyScanner.h index 01cf52734b8ca..ce4d58f014970 100644 --- a/include/swift/DependencyScan/ModuleDependencyScanner.h +++ b/include/swift/DependencyScan/ModuleDependencyScanner.h @@ -37,6 +37,68 @@ using ImportStatementInfoMap = std::unordered_map>; +struct ScannerMetrics { + /// Number of performed queries for a Swift dependency with a given name + std::atomic SwiftModuleQueries; + /// Number of performed queries for a Clang dependency with a given name + std::atomic NamedClangModuleQueries; + /// Number of discovered Clang module dependencies which are directly + /// imported from a Swift module by-name + std::atomic RecordedNamedClangModuleDependencies; +}; + +class DependencyScannerDiagnosticReporter { +private: + DependencyScannerDiagnosticReporter(DiagnosticEngine &Diagnostics, + bool EmitScanRemarks); + + /// Diagnose scanner failure and attempt to reconstruct the dependency + /// path from the main module to the missing dependency + void diagnoseModuleNotFoundFailure( + const ScannerImportStatementInfo &moduleImport, + const ModuleDependenciesCache &cache, + std::optional dependencyOf, + std::optional> + resolvingSerializedSearchPath, + std::optional< + std::vector> + foundIncompatibleCandidates = std::nullopt); + + /// Upon query failure, if incompatible binary module + /// candidates were found, emit a failure diagnostic + void diagnoseFailureOnOnlyIncompatibleCandidates( + const ScannerImportStatementInfo &moduleImport, + const std::vector + &candidates, + const ModuleDependenciesCache &cache, + std::optional dependencyOf); + + /// Emit warnings for each discovered binary Swift module + /// which was incompatible with the current compilation + /// when querying \c moduleName + void warnOnIncompatibleCandidates( + StringRef moduleName, + const std::vector + &candidates); + + /// If remark emission is enabled, increment the + /// corresponding metric. + void registerSwiftModuleQuery(); + void registerNamedClangModuleQuery(); + void registerNamedClangDependency(); + + /// Emit various metrics about the current scannig action + void emitScanMetrics(const ModuleDependenciesCache &cache) const; + + DiagnosticEngine &Diagnostics; + bool EmitScanRemarks; + std::unique_ptr ScanMetrics; + std::unordered_set ReportedMissing; + // Restrict access to the parent scanner classes. + friend class ModuleDependencyScanner; + friend class ModuleDependencyScanningWorker; +}; + /// A dependency scanning worker which performs filesystem lookup /// of a named module dependency. class ModuleDependencyScanningWorker { @@ -48,7 +110,8 @@ class ModuleDependencyScanningWorker { DependencyTracker &DependencyTracker, std::shared_ptr CAS, std::shared_ptr ActionCache, - llvm::PrefixMapper *mapper, DiagnosticEngine &diags); + DependencyScannerDiagnosticReporter &DiagnosticReporter, + llvm::PrefixMapper *mapper); private: /// Query dependency information for a named Clang module @@ -128,6 +191,9 @@ class ModuleDependencyScanningWorker { std::shared_ptr CAS; std::shared_ptr ActionCache; + // The parent scanner's diagnostic reporter + DependencyScannerDiagnosticReporter &diagnosticReporter; + // Base command line invocation for clang scanner queries (both module and header) std::vector clangScanningBaseCommandLineArgs; // Command line invocation for clang by-name module lookups @@ -173,46 +239,6 @@ class SwiftDependencyTracker { std::map TrackedFiles; }; -class ModuleDependencyIssueReporter { -private: - ModuleDependencyIssueReporter(DiagnosticEngine &Diagnostics) - : Diagnostics(Diagnostics) {} - - /// Diagnose scanner failure and attempt to reconstruct the dependency - /// path from the main module to the missing dependency - void diagnoseModuleNotFoundFailure( - const ScannerImportStatementInfo &moduleImport, - const ModuleDependenciesCache &cache, - std::optional dependencyOf, - std::optional> - resolvingSerializedSearchPath, - std::optional< - std::vector> - foundIncompatibleCandidates = std::nullopt); - - /// Upon query failure, if incompatible binary module - /// candidates were found, emit a failure diagnostic - void diagnoseFailureOnOnlyIncompatibleCandidates( - const ScannerImportStatementInfo &moduleImport, - const std::vector - &candidates, - const ModuleDependenciesCache &cache, - std::optional dependencyOf); - - /// Emit warnings for each discovered binary Swift module - /// which was incompatible with the current compilation - /// when querying \c moduleName - void warnOnIncompatibleCandidates( - StringRef moduleName, - const std::vector - &candidates); - - DiagnosticEngine &Diagnostics; - std::unordered_set ReportedMissing; - // Restrict access to the parent scanner class. - friend class ModuleDependencyScanner; -}; - class ModuleDependencyScanner { public: ModuleDependencyScanner(SwiftDependencyScanningService &ScanningService, @@ -223,7 +249,8 @@ class ModuleDependencyScanner { DependencyTracker &DependencyTracker, std::shared_ptr CAS, std::shared_ptr ActionCache, - DiagnosticEngine &Diagnostics, bool ParallelScan); + DiagnosticEngine &Diagnostics, bool ParallelScan, + bool EmitScanRemarks); /// Identify the scanner invocation's main module's dependencies llvm::ErrorOr @@ -347,7 +374,7 @@ class ModuleDependencyScanner { /// For the provided collection of unresolved imports /// belonging to identified Swift dependnecies, execute a parallel /// query to the Clang dependency scanner for each import's module identifier. - void performParallelClangModuleLookup( + void performClangModuleLookup( const ImportStatementInfoMap &unresolvedImportsMap, const ImportStatementInfoMap &unresolvedOptionalImportsMap, BatchClangModuleLookupResult &result); @@ -396,7 +423,7 @@ class ModuleDependencyScanner { private: const CompilerInvocation &ScanCompilerInvocation; ASTContext &ScanASTContext; - ModuleDependencyIssueReporter IssueReporter; + DependencyScannerDiagnosticReporter ScanDiagnosticReporter; /// The location of where the explicitly-built modules will be output to std::string ModuleOutputPath; diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index db55d8650492f..edcd097f87b9d 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -399,8 +399,8 @@ class FrontendOptions { /// The path at which to either serialize or deserialize the dependency scanner cache. std::string SerializedDependencyScannerCachePath; - /// Emit remarks indicating use of the serialized module dependency scanning cache. - bool EmitDependencyScannerCacheRemarks = false; + /// Emit dependency scanning related remarks. + bool EmitDependencyScannerRemarks = false; /// The path at which the dependency scanner can write generated files. std::string ScannerOutputDir; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 183978f968953..be3f3af6f7ffe 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -292,8 +292,8 @@ def validate_prior_dependency_scan_cache : Flag<["-"], "validate-prior-dependenc def dependency_scan_cache_path : Separate<["-"], "dependency-scan-cache-path">, HelpText<"The path to output the dependency scanner's internal state.">; -def dependency_scan_cache_remarks : Flag<["-"], "Rdependency-scan-cache">, - HelpText<"Emit remarks indicating use of the serialized module dependency scanning cache.">; +def dependency_scan_remarks : Flag<["-"], "Rdependency-scan">, + HelpText<"Emit remarks for various steps taken by the dependency scanner.">; def parallel_scan : Flag<["-"], "parallel-scan">, HelpText<"Perform dependency scanning in-parallel.">; diff --git a/lib/AST/ModuleDependencies.cpp b/lib/AST/ModuleDependencies.cpp index da4e33804df5b..2fc5e905b36b9 100644 --- a/lib/AST/ModuleDependencies.cpp +++ b/lib/AST/ModuleDependencies.cpp @@ -772,6 +772,14 @@ bool ModuleDependenciesCache::hasSwiftDependency(StringRef moduleName) const { return findSwiftDependency(moduleName).has_value(); } +int ModuleDependenciesCache::numberOfClangDependencies() const { + return ModuleDependenciesMap.at(ModuleDependencyKind::Clang).size(); +} +int ModuleDependenciesCache::numberOfSwiftDependencies() const { + return ModuleDependenciesMap.at(ModuleDependencyKind::SwiftInterface).size() + + ModuleDependenciesMap.at(ModuleDependencyKind::SwiftBinary).size(); +} + void ModuleDependenciesCache::recordDependency( StringRef moduleName, ModuleDependencyInfo dependency) { auto dependenciesKind = dependency.getKind(); @@ -908,7 +916,6 @@ void ModuleDependenciesCache::setSwiftOverlayDependencies( ModuleDependencyID moduleID, const ArrayRef dependencyIDs) { auto dependencyInfo = findKnownDependency(moduleID); - assert(dependencyInfo.getSwiftOverlayDependencies().empty()); #ifndef NDEBUG for (const auto &depID : dependencyIDs) assert(depID.Kind != ModuleDependencyKind::Clang); @@ -923,7 +930,6 @@ void ModuleDependenciesCache::setCrossImportOverlayDependencies( ModuleDependencyID moduleID, const ModuleDependencyIDCollectionView dependencyIDs) { auto dependencyInfo = findKnownDependency(moduleID); - assert(dependencyInfo.getCrossImportOverlayDependencies().empty()); // Copy the existing info to a mutable one we can then replace it with, // after setting its overlay dependencies. auto updatedDependencyInfo = dependencyInfo; diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index 83c60ed7e0177..ea6743fbc74ee 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -213,16 +213,18 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker( swift::DependencyTracker &DependencyTracker, std::shared_ptr CAS, std::shared_ptr ActionCache, - llvm::PrefixMapper *Mapper, DiagnosticEngine &Diagnostics) + DependencyScannerDiagnosticReporter &DiagnosticReporter, + llvm::PrefixMapper *Mapper) : workerCompilerInvocation( std::make_unique(ScanCompilerInvocation)), clangScanningTool(*globalScanningService.ClangScanningService, getClangScanningFS(CAS, ScanASTContext)), - CAS(CAS), ActionCache(ActionCache) { + CAS(CAS), ActionCache(ActionCache), + diagnosticReporter(DiagnosticReporter) { // Instantiate a worker-specific diagnostic engine and copy over // the scanner's diagnostic consumers (expected to be thread-safe). workerDiagnosticEngine = std::make_unique(ScanASTContext.SourceMgr); - for (auto &scannerDiagConsumer : Diagnostics.getConsumers()) + for (auto &scannerDiagConsumer : DiagnosticReporter.Diagnostics.getConsumers()) workerDiagnosticEngine->addConsumer(*scannerDiagConsumer); workerASTContext = std::unique_ptr( @@ -299,6 +301,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker( SwiftModuleScannerQueryResult ModuleDependencyScanningWorker::scanFilesystemForSwiftModuleDependency( Identifier moduleName, bool isTestableImport) { + diagnosticReporter.registerSwiftModuleQuery(); return swiftModuleScannerLoader->lookupSwiftModule(moduleName, isTestableImport); } @@ -309,6 +312,7 @@ ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency( LookupModuleOutputCallback lookupModuleOutput, const llvm::DenseSet &alreadySeenModules) { + diagnosticReporter.registerNamedClangModuleQuery(); auto clangModuleDependencies = clangScanningTool.getModuleDependencies( moduleName.str(), clangScanningModuleCommandLineArgs, clangScanningWorkingDirectoryPath, alreadySeenModules, @@ -323,7 +327,6 @@ ModuleDependencyScanningWorker::scanFilesystemForClangModuleDependency( }); return std::nullopt; } - return clangModuleDependencies.get(); } @@ -524,9 +527,11 @@ ModuleDependencyScanner::ModuleDependencyScanner( swift::DependencyTracker &DependencyTracker, std::shared_ptr CAS, std::shared_ptr ActionCache, - DiagnosticEngine &Diagnostics, bool ParallelScan) + DiagnosticEngine &Diagnostics, bool ParallelScan, + bool EmitScanRemarks) : ScanCompilerInvocation(ScanCompilerInvocation), - ScanASTContext(ScanASTContext), IssueReporter(Diagnostics), + ScanASTContext(ScanASTContext), + ScanDiagnosticReporter(Diagnostics, EmitScanRemarks), ModuleOutputPath(ScanCompilerInvocation.getFrontendOptions() .ExplicitModulesOutputPath), SDKModuleOutputPath(ScanCompilerInvocation.getFrontendOptions() @@ -557,7 +562,8 @@ ModuleDependencyScanner::ModuleDependencyScanner( for (size_t i = 0; i < NumThreads; ++i) Workers.emplace_front(std::make_unique( ScanningService, ScanCompilerInvocation, SILOptions, ScanASTContext, - DependencyTracker, CAS, ActionCache, PrefixMapper.get(), Diagnostics)); + DependencyTracker, CAS, ActionCache, ScanDiagnosticReporter, + PrefixMapper.get())); } static std::set @@ -880,11 +886,12 @@ ModuleDependencyScanner::performDependencyScan(ModuleDependencyID rootModuleID) if (ScanCompilerInvocation.getSearchPathOptions().BridgingHeaderChaining) { auto err = performBridgingHeaderChaining(rootModuleID, allModules); if (err) - IssueReporter.Diagnostics.diagnose(SourceLoc(), + ScanDiagnosticReporter.Diagnostics.diagnose(SourceLoc(), diag::error_scanner_extra, toString(std::move(err))); } + ScanDiagnosticReporter.emitScanMetrics(DependencyCache); return allModules.takeVector(); } @@ -1074,16 +1081,17 @@ void ModuleDependencyScanner::reQueryMissedModulesFromCache( unresolvedModuleID); DependencyCache.addVisibleClangModules( unresolvedImport.first, {unresolvedImport.second.importIdentifier}); + ScanDiagnosticReporter.registerNamedClangDependency(); } else { // Failed to resolve module dependency. - IssueReporter.diagnoseModuleNotFoundFailure( + ScanDiagnosticReporter.diagnoseModuleNotFoundFailure( unresolvedImport.second, DependencyCache, unresolvedImport.first, attemptToFindResolvingSerializedSearchPath(unresolvedImport.second)); } } } -void ModuleDependencyScanner::performParallelClangModuleLookup( +void ModuleDependencyScanner::performClangModuleLookup( const ImportStatementInfoMap &unresolvedImportsMap, const ImportStatementInfoMap &unresolvedOptionalImportsMap, BatchClangModuleLookupResult &result) { @@ -1160,6 +1168,8 @@ void ModuleDependencyScanner::cacheComputedClangModuleLookupResults( // Add the resolved dependency ID if (lookupResult.discoveredDependencyInfos.contains( moduleIdentifier)) { + if (!DependencyCache.hasDependency(dependencyID)) + ScanDiagnosticReporter.registerNamedClangDependency(); auto dependencyInfo = lookupResult.discoveredDependencyInfos.at( moduleImport.importIdentifier); allDiscoveredClangModules.insert(dependencyID); @@ -1214,7 +1224,7 @@ void ModuleDependencyScanner::resolveAllClangModuleDependencies( // Execute parallel lookup of all unresolved import // identifiers as Clang modules. BatchClangModuleLookupResult lookupResult; - performParallelClangModuleLookup( + performClangModuleLookup( unresolvedImportsMap, unresolvedOptionalImportsMap, lookupResult); // Use the computed scan results to record directly-queried clang module @@ -1368,7 +1378,7 @@ void ModuleDependencyScanner::resolveSwiftImportsForModule( importedSwiftDependencies.insert( {moduleImport.importIdentifier, lookupResult.foundDependencyInfo->getKind()}); - IssueReporter.warnOnIncompatibleCandidates( + ScanDiagnosticReporter.warnOnIncompatibleCandidates( moduleImport.importIdentifier, lookupResult.incompatibleCandidates); // Module was resolved from a cache @@ -1377,9 +1387,9 @@ void ModuleDependencyScanner::resolveSwiftImportsForModule( importedSwiftDependencies.insert( {moduleImport.importIdentifier, cachedInfo.value()->getKind()}); else - IssueReporter.diagnoseFailureOnOnlyIncompatibleCandidates( - moduleImport, lookupResult.incompatibleCandidates, - DependencyCache, std::nullopt); + ScanDiagnosticReporter.diagnoseFailureOnOnlyIncompatibleCandidates( + moduleImport, lookupResult.incompatibleCandidates, + DependencyCache, std::nullopt); }; for (const auto &importInfo : moduleDependencyInfo.getModuleImports()) @@ -1569,7 +1579,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule( *(lookupResult.foundDependencyInfo)); swiftOverlayDependencies.insert( {moduleName, lookupResult.foundDependencyInfo->getKind()}); - IssueReporter.warnOnIncompatibleCandidates( + ScanDiagnosticReporter.warnOnIncompatibleCandidates( moduleName, lookupResult.incompatibleCandidates); // Module was resolved from a cache } else if (auto cachedInfo = @@ -1577,7 +1587,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule( swiftOverlayDependencies.insert( {moduleName, cachedInfo.value()->getKind()}); else - IssueReporter.diagnoseFailureOnOnlyIncompatibleCandidates( + ScanDiagnosticReporter.diagnoseFailureOnOnlyIncompatibleCandidates( ScannerImportStatementInfo(moduleName), lookupResult.incompatibleCandidates, DependencyCache, std::nullopt); @@ -2055,7 +2065,7 @@ ModuleDependencyInfo ModuleDependencyScanner::bridgeClangModuleDependency( return bridgedDependencyInfo; } -void ModuleDependencyIssueReporter::diagnoseModuleNotFoundFailure( +void DependencyScannerDiagnosticReporter::diagnoseModuleNotFoundFailure( const ScannerImportStatementInfo &moduleImport, const ModuleDependenciesCache &cache, std::optional dependencyOf, @@ -2166,7 +2176,7 @@ void ModuleDependencyIssueReporter::diagnoseModuleNotFoundFailure( ReportedMissing.insert(moduleImport.importIdentifier); } -void ModuleDependencyIssueReporter::diagnoseFailureOnOnlyIncompatibleCandidates( +void DependencyScannerDiagnosticReporter::diagnoseFailureOnOnlyIncompatibleCandidates( const ScannerImportStatementInfo &moduleImport, const std::vector &candidates, @@ -2195,7 +2205,14 @@ void ModuleDependencyIssueReporter::diagnoseFailureOnOnlyIncompatibleCandidates( candidates); } -void ModuleDependencyIssueReporter::warnOnIncompatibleCandidates( +DependencyScannerDiagnosticReporter::DependencyScannerDiagnosticReporter( + DiagnosticEngine &Diagnostics, bool EmitScanRemarks) + : Diagnostics(Diagnostics), EmitScanRemarks(EmitScanRemarks) { + if (EmitScanRemarks) + ScanMetrics = std::make_unique(); +} + +void DependencyScannerDiagnosticReporter::warnOnIncompatibleCandidates( StringRef moduleName, const std::vector &candidates) { @@ -2207,6 +2224,48 @@ void ModuleDependencyIssueReporter::warnOnIncompatibleCandidates( candidate.path, candidate.incompatibilityReason); } +void DependencyScannerDiagnosticReporter::registerSwiftModuleQuery() { + if (!EmitScanRemarks) + return; + assert(ScanMetrics); + ScanMetrics->SwiftModuleQueries++; +} + +void DependencyScannerDiagnosticReporter::registerNamedClangModuleQuery() { + if (!EmitScanRemarks) + return; + assert(ScanMetrics); + ScanMetrics->NamedClangModuleQueries++; +} + +void DependencyScannerDiagnosticReporter::registerNamedClangDependency() { + if (!EmitScanRemarks) + return; + assert(ScanMetrics); + ScanMetrics->RecordedNamedClangModuleDependencies++; +} + +void DependencyScannerDiagnosticReporter::emitScanMetrics( + const ModuleDependenciesCache &cache) const { + if (!EmitScanRemarks || !ScanMetrics) + return; + + Diagnostics.diagnose(SourceLoc(), diag::dependency_scan_number_swift_queries, + ScanMetrics->SwiftModuleQueries); + Diagnostics.diagnose(SourceLoc(), + diag::dependency_scan_number_named_clang_queries, + ScanMetrics->NamedClangModuleQueries); + Diagnostics.diagnose(SourceLoc(), + diag::dependency_scan_number_named_clang_dependencies, + ScanMetrics->RecordedNamedClangModuleDependencies); + Diagnostics.diagnose(SourceLoc(), + diag::dependency_scan_number_swift_dependencies, + cache.numberOfSwiftDependencies()); + Diagnostics.diagnose(SourceLoc(), + diag::dependency_scan_number_clang_dependencies, + cache.numberOfClangDependencies()); +} + std::optional> ModuleDependencyScanner::attemptToFindResolvingSerializedSearchPath( const ScannerImportStatementInfo &moduleImport) { diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 2af0d2555772d..592da4d71a765 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -1383,14 +1383,14 @@ performModuleScanImpl( // is specified if (opts.ReuseDependencyScannerCache) { auto cachePath = opts.SerializedDependencyScannerCachePath; - if (opts.EmitDependencyScannerCacheRemarks) + if (opts.EmitDependencyScannerRemarks) ctx.Diags.diagnose(SourceLoc(), diag::remark_reuse_cache, cachePath); llvm::sys::TimePoint<> serializedCacheTimeStamp; bool loadFailure = module_dependency_cache_serialization::readInterModuleDependenciesCache( cachePath, cache, serializedCacheTimeStamp); - if (opts.EmitDependencyScannerCacheRemarks && loadFailure) + if (opts.EmitDependencyScannerRemarks && loadFailure) ctx.Diags.diagnose(SourceLoc(), diag::warn_scanner_deserialize_failed, cachePath); @@ -1401,7 +1401,7 @@ performModuleScanImpl( incremental::validateInterModuleDependenciesCache( mainModuleID, cache, instance->getSharedCASInstance(), serializedCacheTimeStamp, *instance->getSourceMgr().getFileSystem(), - ctx.Diags, opts.EmitDependencyScannerCacheRemarks); + ctx.Diags, opts.EmitDependencyScannerRemarks); } } @@ -1410,7 +1410,8 @@ performModuleScanImpl( instance->getASTContext(), *instance->getDependencyTracker(), instance->getSharedCASInstance(), instance->getSharedCacheInstance(), instance->getDiags(), - instance->getInvocation().getFrontendOptions().ParallelDependencyScan); + instance->getInvocation().getFrontendOptions().ParallelDependencyScan, + instance->getInvocation().getFrontendOptions().EmitDependencyScannerRemarks); // Identify imports of the main module and add an entry for it // to the dependency graph. @@ -1444,7 +1445,7 @@ performModuleScanImpl( auto savePath = opts.SerializedDependencyScannerCachePath; module_dependency_cache_serialization::writeInterModuleDependenciesCache( ctx.Diags, instance->getOutputBackend(), savePath, cache); - if (opts.EmitDependencyScannerCacheRemarks) + if (opts.EmitDependencyScannerRemarks) ctx.Diags.diagnose(SourceLoc(), diag::remark_save_cache, savePath); } @@ -1462,7 +1463,9 @@ static llvm::ErrorOr performModulePrescanImpl( instance->getASTContext(), *instance->getDependencyTracker(), instance->getSharedCASInstance(), instance->getSharedCacheInstance(), instance->getDiags(), - instance->getInvocation().getFrontendOptions().ParallelDependencyScan); + instance->getInvocation().getFrontendOptions().ParallelDependencyScan, + instance->getInvocation().getFrontendOptions().EmitDependencyScannerRemarks); + // Execute import prescan, and write JSON output to the output stream auto mainDependencies = scanner.getMainModuleDependencyInfo(instance->getMainModule()); diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 9292948dfd221..ff6e511a5cfb5 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -158,7 +158,7 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.SerializeDependencyScannerCache |= Args.hasArg(OPT_serialize_dependency_scan_cache); Opts.ReuseDependencyScannerCache |= Args.hasArg(OPT_reuse_dependency_scan_cache); Opts.ValidatePriorDependencyScannerCache |= Args.hasArg(OPT_validate_prior_dependency_scan_cache); - Opts.EmitDependencyScannerCacheRemarks |= Args.hasArg(OPT_dependency_scan_cache_remarks); + Opts.EmitDependencyScannerRemarks |= Args.hasArg(OPT_dependency_scan_remarks); Opts.ParallelDependencyScan = Args.hasFlag(OPT_parallel_scan, OPT_no_parallel_scan, true); diff --git a/test/CAS/incremental_scan.swift b/test/CAS/incremental_scan.swift index 0c25378c742c6..ca9e5a12eace1 100644 --- a/test/CAS/incremental_scan.swift +++ b/test/CAS/incremental_scan.swift @@ -1,14 +1,14 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/module-cache) -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE --check-prefix=FAILED-LOAD +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE --check-prefix=FAILED-LOAD /// Test reuse -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE /// Test invalidation after removing CAS. // RUN: rm -rf %t/cas -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE --check-prefix=INVALIDATE +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/Swift -cache-compile-job -cas-path %t/cas -no-clang-include-tree -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache 2>&1 | %FileCheck %s --check-prefix=REUSE --check-prefix=INVALIDATE // REUSE: Incremental module scan: Re-using serialized module scanning dependency cache from: // FAILED-LOD: Incremental module scan: Failed to load module scanning dependency cache from diff --git a/test/CAS/module_deps_include_tree.swift b/test/CAS/module_deps_include_tree.swift index 21a3f20afec3b..ae226469b79d9 100644 --- a/test/CAS/module_deps_include_tree.swift +++ b/test/CAS/module_deps_include_tree.swift @@ -152,7 +152,6 @@ import SubE // CHECK: "directDependencies" // CHECK-NEXT: { // CHECK-DAG: "clang": "G" -// CHECK-DAG: "swift": "Swift" // CHECK-DAG: "swift": "SwiftOnoneSupport" // CHECK: ], // CHECK-NEXT: "linkLibraries": [ @@ -173,10 +172,6 @@ import SubE /// --------Swift module E // CHECK: "swift": "E" // CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule" -// CHECK: "directDependencies" -// CHECK-NEXT: { -// CHECK-NEXT: "swift": "Swift" - // CHECK: "moduleInterfacePath" // CHECK-SAME: E.swiftinterface diff --git a/test/CAS/plugin_cas.swift b/test/CAS/plugin_cas.swift index 476e97eb652c4..179f40f58795b 100644 --- a/test/CAS/plugin_cas.swift +++ b/test/CAS/plugin_cas.swift @@ -136,7 +136,6 @@ import SubE // CHECK: "directDependencies" // CHECK-NEXT: { // CHECK-DAG: "clang": "G" -// CHECK-DAG: "swift": "Swift" // CHECK-DAG: "swift": "SwiftOnoneSupport" // CHECK: ], // CHECK-NEXT: "linkLibraries": [ @@ -157,8 +156,6 @@ import SubE // CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule" // CHECK: "directDependencies" // CHECK-NEXT: { -// CHECK-NEXT: "swift": "Swift" - // CHECK: "moduleInterfacePath" // CHECK-SAME: E.swiftinterface diff --git a/test/ScanDependencies/Incremental/module_deps_invalidate.swift b/test/ScanDependencies/Incremental/module_deps_invalidate.swift index 4b0d6f2775cb1..00a4e984c3b3a 100644 --- a/test/ScanDependencies/Incremental/module_deps_invalidate.swift +++ b/test/ScanDependencies/Incremental/module_deps_invalidate.swift @@ -20,19 +20,19 @@ // RUN: %target-swift-frontend -emit-module %t/A.swift -emit-module-path %t/Modules/A.swiftmodule/%target-swiftmodule-name -module-name A -enable-library-evolution -emit-module-interface-path %t/Modules/A.swiftmodule/%target-swiftinterface-name -I %t/Modules -I %t/ExtraCModules // Initial Scan Client module -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_initial.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_initial.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client // Clean re-scan -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_clean_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/clean_incremental_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_clean_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/clean_incremental_scan_output.txt // RUN: cat %t/clean_incremental_scan_output.txt | %FileCheck %s -check-prefix=CLEAN-INCREMENTAL-SCAN-CHECK // Touch C and re-scan // RUN: touch %t/Modules/C.swiftmodule/%target-swiftinterface-name -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_stale_C_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/stale_C_incremental_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_stale_C_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/stale_C_incremental_scan_output.txt // RUN: cat %t/stale_C_incremental_scan_output.txt | %FileCheck %s -check-prefix=STALE-C-INCREMENTAL-SCAN-CHECK // Clean re-scan -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_clean_rescan_2.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/clean_incremental_scan_output_2.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_clean_rescan_2.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/clean_incremental_scan_output_2.txt // RUN: cat %t/clean_incremental_scan_output_2.txt | %FileCheck %s -check-prefix=CLEAN-INCREMENTAL-SCAN-CHECK // Replace a module dependency in A, ensure re-scan detects it @@ -40,13 +40,13 @@ // RUN: %target-swift-frontend -emit-module %t/A.swift -emit-module-path %t/Modules/A.swiftmodule/%target-swiftmodule-name -module-name A -enable-library-evolution -emit-module-interface-path %t/Modules/A.swiftmodule/%target-swiftinterface-name -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders // Re-scan to ensure A gets scanned again and the new dependency is picked up. -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_new_A_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/new_A_incremental_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_new_A_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/new_A_incremental_scan_output.txt // RUN: cat %t/new_A_incremental_scan_output.txt | %FileCheck %s -check-prefix=NEW-A-INCREMENTAL-SCAN-CHECK // RUN: %validate-json %t/deps_new_A_rescan.json | %FileCheck %s --check-prefix=NEW-A-DEPS-CHECK // Touch a header in Clang module Z and re-scan // RUN: touch %t/ExtraCModules/Z.h -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_stale_Z_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/stale_Z_incremental_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %t/Client.swift -o %t/deps_stale_Z_rescan.json -I %t/Modules -I %t/ExtraCModules -I %S/../Inputs/CHeaders -module-name Client -serialize-dependency-scan-cache -validate-prior-dependency-scan-cache &> %t/stale_Z_incremental_scan_output.txt // RUN: cat %t/stale_Z_incremental_scan_output.txt | %FileCheck %s -check-prefix=STALE-Z-INCREMENTAL-SCAN-CHECK // CLEAN-INCREMENTAL-SCAN-CHECK: remark: Incremental module scan: Re-using serialized module scanning dependency cache from: {{.*}}cache.moddepcache diff --git a/test/ScanDependencies/Incremental/system_search_path_invalidate.swift b/test/ScanDependencies/Incremental/system_search_path_invalidate.swift index 7e003ac018087..a5bd4be86ff39 100644 --- a/test/ScanDependencies/Incremental/system_search_path_invalidate.swift +++ b/test/ScanDependencies/Incremental/system_search_path_invalidate.swift @@ -2,14 +2,14 @@ // RUN: %empty-directory(%t/module-cache) // RUN: %empty-directory(%t/Frameworks) -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/first_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/first_scan_output.txt // RUN: cat %t/first_scan_output.txt | %FileCheck %s -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/second_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -F %t/Frameworks &> %t/second_scan_output.txt // RUN: cat %t/second_scan_output.txt | %FileCheck %s -check-prefix=INCREMENTAL-CHECK // Change an '-F' to a '-Fsystem' and ensure that the serialized cache does not get reused -// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -Fsystem %t/Frameworks &> %t/second_system_scan_output.txt +// RUN: %target-swift-frontend -scan-dependencies -scanner-module-validation -module-load-mode prefer-interface -Rdependency-scan -load-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %t/ExtraCModules -I %S/../Inputs/CHeaders -Fsystem %t/Frameworks &> %t/second_system_scan_output.txt // RUN: cat %t/second_system_scan_output.txt | %FileCheck %s // CHECK: remark: Incremental module scan: Failed to load module scanning dependency cache from: diff --git a/test/ScanDependencies/Inputs/Swift/E.swiftinterface b/test/ScanDependencies/Inputs/Swift/E.swiftinterface index d1fb4b2cb0a5f..edca17859e292 100644 --- a/test/ScanDependencies/Inputs/Swift/E.swiftinterface +++ b/test/ScanDependencies/Inputs/Swift/E.swiftinterface @@ -1,4 +1,3 @@ // swift-interface-format-version: 1.0 // swift-module-flags: -module-name E -autolink-force-load -module-link-name swiftyLibE -import Swift public func funcE() { } diff --git a/test/ScanDependencies/Inputs/Swift/G.swiftinterface b/test/ScanDependencies/Inputs/Swift/G.swiftinterface index e6fea1948fbe5..a5197ad71150f 100644 --- a/test/ScanDependencies/Inputs/Swift/G.swiftinterface +++ b/test/ScanDependencies/Inputs/Swift/G.swiftinterface @@ -2,7 +2,6 @@ // swift-module-flags: -module-name G -swift-version 5 #if swift(>=5.0) -import Swift @_exported import G public func overlayFuncG() { } diff --git a/test/ScanDependencies/basic_query_metrics.swift b/test/ScanDependencies/basic_query_metrics.swift new file mode 100644 index 0000000000000..4b47ff4dc7cb4 --- /dev/null +++ b/test/ScanDependencies/basic_query_metrics.swift @@ -0,0 +1,41 @@ +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/module-cache) +// RUN: %empty-directory(%t/inputs) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/module-cache -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib %t/test.swift -o %t/deps.json -I %t/inputs -Rdependency-scan &> %t/remarks.txt +// RUN: cat %t/remarks.txt | %FileCheck %s + +// Ensure that despite being a common dependency to multiple Swift modules, only 1 query is performed to find 'C' +// CHECK: remark: Number of Swift module queries: '6' +// CHECK: remark: Number of named Clang module queries: '1' +// CHEKC: remark: Number of recorded Clang module dependencies queried by-name from a Swift client: '1' +// CHECK: remark: Number of recorded Swift module dependencies: '2' +// CHECK: remark: Number of recorded Clang module dependencies: '1' + +//--- test.swift +import A +import B +public func test() {} + +//--- inputs/A.swiftinterface +// swift-interface-format-version: 1.0 +// swift-module-flags: -module-name A -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -user-module-version 1.0 +import C +public func a() { } + +//--- inputs/B.swiftinterface +// swift-interface-format-version: 1.0 +// swift-module-flags: -module-name B -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -user-module-version 1.0 +import C +public func b() { } + +//--- inputs/C.h +void c(void); + +//--- inputs/module.modulemap +module C { + header "C.h" + export * +} + diff --git a/test/ScanDependencies/bridging-header-autochaining.swift b/test/ScanDependencies/bridging-header-autochaining.swift index 66321f068589a..6b1b098f8cff5 100644 --- a/test/ScanDependencies/bridging-header-autochaining.swift +++ b/test/ScanDependencies/bridging-header-autochaining.swift @@ -118,7 +118,7 @@ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -scanner-module-validation \ // RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap \ // RUN: -I %t %t/user2.swift -import-objc-header %t/Bridging3.h -auto-bridging-header-chaining -scanner-output-dir %t -scanner-debug-write-output \ -// RUN: -o %t/deps4.json -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache +// RUN: -o %t/deps4.json -Rdependency-scan -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache // RUN: %FileCheck %s --check-prefix DEPS_JSON2 --input-file=%t/deps4.json // DEPS_JSON2: "chainedBridgingHeaderPath": @@ -134,7 +134,7 @@ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -scanner-module-validation \ // RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap \ // RUN: -I %t %t/user2.swift -import-objc-header %t/Bridging3.h -auto-bridging-header-chaining -scanner-output-dir %t -scanner-debug-write-output \ -// RUN: -o %t/deps4.json -Rdependency-scan-cache -load-dependency-scan-cache -serialize-dependency-scan-cache \ +// RUN: -o %t/deps4.json -Rdependency-scan -load-dependency-scan-cache -serialize-dependency-scan-cache \ // RUN: -dependency-scan-cache-path %t/cache.moddepcache 2>&1 | %FileCheck %s -check-prefix=CACHE-LOAD // CACHE-LOAD: remark: Incremental module scan: Re-using serialized module scanning dependency cache from: diff --git a/test/ScanDependencies/cached-missing-module-found-in-serialized-paths.swift b/test/ScanDependencies/cached-missing-module-found-in-serialized-paths.swift index c078691e1ecd2..3e97a9b94a6f4 100644 --- a/test/ScanDependencies/cached-missing-module-found-in-serialized-paths.swift +++ b/test/ScanDependencies/cached-missing-module-found-in-serialized-paths.swift @@ -9,13 +9,13 @@ // Put the dependency module into a location discoverable by the first scan which will succeed and serialize scanner state // RUN: cp %t/moreDeps/C.swiftinterface %t/deps/C.swiftinterface -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %t/client.swift -I %t/deps -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache &> %t/initial_output.txt +// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %t/client.swift -I %t/deps -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -Rdependency-scan -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache &> %t/initial_output.txt // Remove the 'C' dependency module into a location not discoverable by the second scan in order to trigger a failure and use serialized scanner state // to emit the diagnostic // RUN: rm %t/deps/C.swiftinterface -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %t/client.swift -I %t/deps -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -validate-prior-dependency-scan-cache &> %t/output.txt +// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %t/client.swift -I %t/deps -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -Rdependency-scan -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -validate-prior-dependency-scan-cache &> %t/output.txt // RUN: cat %t/output.txt | %FileCheck %s // CHECK: remark: Incremental module scan: Re-using serialized module scanning dependency cache from: '{{.*}}cache.moddepcache'. diff --git a/test/ScanDependencies/module_deps_cache_reuse.swift b/test/ScanDependencies/module_deps_cache_reuse.swift index 2d2d8eba9a45a..fd7976ffbc935 100644 --- a/test/ScanDependencies/module_deps_cache_reuse.swift +++ b/test/ScanDependencies/module_deps_cache_reuse.swift @@ -2,10 +2,12 @@ // RUN: mkdir -p %t/clang-module-cache // Run the scanner once, emitting the serialized scanner cache -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cross-import-overlays 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE +// RUN: %target-swift-frontend -scan-dependencies -module-name FooReuse -module-load-mode prefer-interface -Rdependency-scan -validate-prior-dependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cross-import-overlays &> %t/remarks_save.txt +// RUN: cat %t/remarks_save.txt | %FileCheck %s -check-prefix CHECK-REMARK-SAVE // Run the scanner again, but now re-using previously-serialized cache -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cross-import-overlays 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD +// RUN: %target-swift-frontend -scan-dependencies -module-name FooReuse -module-load-mode prefer-interface -Rdependency-scan -validate-prior-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -enable-cross-import-overlays &> %t/remarks_load.txt +// RUN: cat %t/remarks_load.txt | %FileCheck %s -check-prefix CHECK-REMARK-LOAD // Check the contents of the JSON output // RUN: %validate-json %t/deps.json &>/dev/null @@ -19,13 +21,28 @@ import E import G import SubE +// CHECK-REMARK-SAVE: remark: Number of Swift module queries: '21' +// CHECK-REMARK-SAVE: remark: Number of named Clang module queries: '6' +// CHECK-REMARK-SAVE: remark: Number of recorded Clang module dependencies queried by-name from a Swift client: '6' +// CHECK-REMARK-SAVE: remark: Number of recorded Swift module dependencies: '8' +// CHECK-REMARK-SAVE: remark: Number of recorded Clang module dependencies: '7' // CHECK-REMARK-SAVE: remark: Incremental module scan: Serializing module scanning dependency cache to: + // CHECK-REMARK-LOAD: remark: Incremental module scan: Re-using serialized module scanning dependency cache from: +// 'SwiftShims', 'C' and 'B' are Clang modules which are directly imorted from Swift code in this test, without a corresponding Swift overlay module. Because we do not serialize negative Swift dependency lookup results, resolving a dependency on these modules involves a query for whether a Swift module under this name can be found. This query fails and the subsequent query for this identifier as a Clang dependency is then able to re-use the loaded serialized cache. + +// CHECK-REMARK-LOAD: remark: Number of Swift module queries: '7' +// FIXME: Today, we do not serialize dependencies of the main source module which results in a lookup for 'C' even though +// it is fully redundant. +// CHECK-REMARK-LOAD: remark: Number of named Clang module queries: '1' +// CHECK-REMARK-LOAD: remark: Number of recorded Clang module dependencies queried by-name from a Swift client: '0' +// CHECK-REMARK-LOAD: remark: Number of recorded Swift module dependencies: '8' +// CHECK-REMARK-LOAD: remark: Number of recorded Clang module dependencies: '7' -// CHECK: "mainModuleName": "deps" +// CHECK: "mainModuleName": "FooReuse" /// --------Main module -// CHECK-LABEL: "modulePath": "deps.swiftmodule", +// CHECK-LABEL: "modulePath": "FooReuse.swiftmodule", // CHECK-NEXT: sourceFiles // CHECK-NEXT: module_deps_cache_reuse.swift // CHECK-NEXT: ], @@ -36,12 +53,7 @@ import SubE // CHECK-DAG: "clang": "F" // CHECK-DAG: "swift": "G" // CHECK-DAG: "swift": "SubE" -// CHECK-DAG: "swift": "Swift" -// CHECK-DAG: "swift": "SwiftOnoneSupport" -// CHECK-DAG: "swift": "_Concurrency" -// CHECK-DAG: "swift": "_StringProcessing" // CHECK-DAG: "swift": "_cross_import_E" -// CHECK-DAG: "clang": "_SwiftConcurrencyShims" // CHECK: ], // CHECK: "contextHash": @@ -105,9 +117,7 @@ import SubE // CHECK-NEXT: ], // CHECK-NEXT: "directDependencies": [ // CHECK-NEXT: { -// CHECK-DAG: "clang": "F" -// CHECK-DAG: "swift": "Swift" -// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK: "clang": "F" // CHECK: ], /// --------Swift module A @@ -116,15 +126,12 @@ import SubE // CHECK: directDependencies // CHECK-NEXT: { // CHECK-DAG: "clang": "A" -// CHECK-DAG: "swift": "Swift" /// --------Swift module G // CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}G-{{.*}}.swiftmodule" // CHECK: "directDependencies" // CHECK-NEXT: { -// CHECK-DAG: "clang": "G" -// CHECK-DAG: "swift": "Swift" -// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK: "clang": "G" // CHECK: ], // CHECK-NEXT: "linkLibraries": [ // CHECK-NEXT: ], @@ -143,20 +150,5 @@ import SubE /// --------Swift module E // CHECK: "swift": "E" // CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule" -// CHECK: "directDependencies" -// CHECK-NEXT: { -// CHECK: "swift": "Swift" - // CHECK: "moduleInterfacePath" // CHECK-SAME: E.swiftinterface - -/// --------Swift module Swift -// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule", - -// CHECK: directDependencies -// CHECK-NEXT: { -// CHECK: "clang": "SwiftShims" - -/// --------Clang module SwiftShims -// CHECK-LABEL: "modulePath": "{{.*}}/SwiftShims-{{.*}}.pcm", - diff --git a/test/ScanDependencies/serialized_imports.swift b/test/ScanDependencies/serialized_imports.swift index 41b3945a715f3..4116856001bc3 100644 --- a/test/ScanDependencies/serialized_imports.swift +++ b/test/ScanDependencies/serialized_imports.swift @@ -3,12 +3,12 @@ // RUN: %empty-directory(%t/module-cache) // Run the scanner once, emitting the serialized scanner cache -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE // RUN: llvm-bcanalyzer --dump %t/cache.moddepcache > %t/cache.moddepcache.initial.dump.txt // RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix CHECK-IMPORTS // Run the scanner again, but now re-using previously-serialized cache -// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps_incremental.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps_incremental.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD // RUN: llvm-bcanalyzer --dump %t/cache.moddepcache > %t/cache.moddepcache.dump.txt // RUN: %validate-json %t/deps_incremental.json | %FileCheck %s -check-prefix CHECK-IMPORTS