Skip to content

Commit e6761b1

Browse files
committed
[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 introduces '-Rdependency-scan', which acts as a super-set flag to the existing '-Rdependency-scan-cache' and adds emission of the above metrics as remarks when this flag is enabled. Followup changes will add further remarks about dependency scanner progress.
1 parent a859ebe commit e6761b1

File tree

15 files changed

+258
-110
lines changed

15 files changed

+258
-110
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,22 @@ WARNING(dependency_scan_module_incompatible, none,
24322432
"module file '%0' is incompatible with this Swift compiler: %1",
24332433
(StringRef, StringRef))
24342434

2435+
REMARK(dependency_scan_number_swift_queries, none,
2436+
"Number of Swift module queries: '%0'",
2437+
(uint32_t))
2438+
REMARK(dependency_scan_number_named_clang_queries, none,
2439+
"Number of named Clang module queries: '%0'",
2440+
(uint32_t))
2441+
REMARK(dependency_scan_number_swift_dependencies, none,
2442+
"Number of recorded Swift module dependencies: '%0'",
2443+
(uint32_t))
2444+
REMARK(dependency_scan_number_named_clang_dependencies, none,
2445+
"Number of recorded Clang module dependencies queried by-name from a Swift client: '%0'",
2446+
(uint32_t))
2447+
REMARK(dependency_scan_number_clang_dependencies, none,
2448+
"Number of recorded Clang module dependencies: '%0'",
2449+
(uint32_t))
2450+
24352451
ERROR(clang_dependency_scan_error, none, "clang dependency scanning failure: %0", (StringRef))
24362452

24372453
ERROR(clang_header_dependency_scan_error, none, "bridging header dependency scanning failure: %0", (StringRef))

include/swift/AST/ModuleDependencies.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,11 @@ class ModuleDependenciesCache {
11111111
bool hasDependency(StringRef moduleName) const;
11121112
/// Whether we have cached dependency information for the given Swift module.
11131113
bool hasSwiftDependency(StringRef moduleName) const;
1114+
/// Report the number of recorded Clang dependencies
1115+
int numberOfClangDependencies() const;
1116+
/// Report the number of recorded Swift dependencies
1117+
/// (Textual + Binary)
1118+
int numberOfSwiftDependencies() const;
11141119

11151120
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &
11161121
getAlreadySeenClangModules() const {

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,68 @@ using ImportStatementInfoMap =
3737
std::unordered_map<ModuleDependencyID,
3838
std::vector<ScannerImportStatementInfo>>;
3939

40+
struct ScannerMetrics {
41+
/// Number of performed queries for a Swift dependency with a given name
42+
std::atomic<uint32_t> SwiftModuleQueries;
43+
/// Number of performed queries for a Clang dependency with a given name
44+
std::atomic<uint32_t> NamedClangModuleQueries;
45+
/// Number of discovered Clang module dependencies which are directly
46+
/// imported from a Swift module by-name
47+
std::atomic<uint32_t> RecordedNamedClangModuleDependencies;
48+
};
49+
50+
class DependencyScannerDiagnosticReporter {
51+
private:
52+
DependencyScannerDiagnosticReporter(DiagnosticEngine &Diagnostics,
53+
bool EmitScanRemarks);
54+
55+
/// Diagnose scanner failure and attempt to reconstruct the dependency
56+
/// path from the main module to the missing dependency
57+
void diagnoseModuleNotFoundFailure(
58+
const ScannerImportStatementInfo &moduleImport,
59+
const ModuleDependenciesCache &cache,
60+
std::optional<ModuleDependencyID> dependencyOf,
61+
std::optional<std::pair<ModuleDependencyID, std::string>>
62+
resolvingSerializedSearchPath,
63+
std::optional<
64+
std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>>
65+
foundIncompatibleCandidates = std::nullopt);
66+
67+
/// Upon query failure, if incompatible binary module
68+
/// candidates were found, emit a failure diagnostic
69+
void diagnoseFailureOnOnlyIncompatibleCandidates(
70+
const ScannerImportStatementInfo &moduleImport,
71+
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
72+
&candidates,
73+
const ModuleDependenciesCache &cache,
74+
std::optional<ModuleDependencyID> dependencyOf);
75+
76+
/// Emit warnings for each discovered binary Swift module
77+
/// which was incompatible with the current compilation
78+
/// when querying \c moduleName
79+
void warnOnIncompatibleCandidates(
80+
StringRef moduleName,
81+
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
82+
&candidates);
83+
84+
/// If remark emission is enabled, increment the
85+
/// corresponding metric.
86+
void registerSwiftModuleQuery();
87+
void registerNamedClangModuleQuery();
88+
void registerNamedClangDependency();
89+
90+
/// Emit various metrics about the current scannig action
91+
void emitScanMetrics(const ModuleDependenciesCache &cache) const;
92+
93+
DiagnosticEngine &Diagnostics;
94+
bool EmitScanRemarks;
95+
std::unique_ptr<ScannerMetrics> ScanMetrics;
96+
std::unordered_set<std::string> ReportedMissing;
97+
// Restrict access to the parent scanner classes.
98+
friend class ModuleDependencyScanner;
99+
friend class ModuleDependencyScanningWorker;
100+
};
101+
40102
/// A dependency scanning worker which performs filesystem lookup
41103
/// of a named module dependency.
42104
class ModuleDependencyScanningWorker {
@@ -48,7 +110,8 @@ class ModuleDependencyScanningWorker {
48110
DependencyTracker &DependencyTracker,
49111
std::shared_ptr<llvm::cas::ObjectStore> CAS,
50112
std::shared_ptr<llvm::cas::ActionCache> ActionCache,
51-
llvm::PrefixMapper *mapper, DiagnosticEngine &diags);
113+
DependencyScannerDiagnosticReporter &DiagnosticReporter,
114+
llvm::PrefixMapper *mapper);
52115

53116
private:
54117
/// Query dependency information for a named Clang module
@@ -128,6 +191,9 @@ class ModuleDependencyScanningWorker {
128191
std::shared_ptr<llvm::cas::ObjectStore> CAS;
129192
std::shared_ptr<llvm::cas::ActionCache> ActionCache;
130193

194+
// The parent scanner's diagnostic reporter
195+
DependencyScannerDiagnosticReporter &diagnosticReporter;
196+
131197
// Base command line invocation for clang scanner queries (both module and header)
132198
std::vector<std::string> clangScanningBaseCommandLineArgs;
133199
// Command line invocation for clang by-name module lookups
@@ -173,46 +239,6 @@ class SwiftDependencyTracker {
173239
std::map<std::string, FileEntry> TrackedFiles;
174240
};
175241

176-
class ModuleDependencyIssueReporter {
177-
private:
178-
ModuleDependencyIssueReporter(DiagnosticEngine &Diagnostics)
179-
: Diagnostics(Diagnostics) {}
180-
181-
/// Diagnose scanner failure and attempt to reconstruct the dependency
182-
/// path from the main module to the missing dependency
183-
void diagnoseModuleNotFoundFailure(
184-
const ScannerImportStatementInfo &moduleImport,
185-
const ModuleDependenciesCache &cache,
186-
std::optional<ModuleDependencyID> dependencyOf,
187-
std::optional<std::pair<ModuleDependencyID, std::string>>
188-
resolvingSerializedSearchPath,
189-
std::optional<
190-
std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>>
191-
foundIncompatibleCandidates = std::nullopt);
192-
193-
/// Upon query failure, if incompatible binary module
194-
/// candidates were found, emit a failure diagnostic
195-
void diagnoseFailureOnOnlyIncompatibleCandidates(
196-
const ScannerImportStatementInfo &moduleImport,
197-
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
198-
&candidates,
199-
const ModuleDependenciesCache &cache,
200-
std::optional<ModuleDependencyID> dependencyOf);
201-
202-
/// Emit warnings for each discovered binary Swift module
203-
/// which was incompatible with the current compilation
204-
/// when querying \c moduleName
205-
void warnOnIncompatibleCandidates(
206-
StringRef moduleName,
207-
const std::vector<SwiftModuleScannerQueryResult::IncompatibleCandidate>
208-
&candidates);
209-
210-
DiagnosticEngine &Diagnostics;
211-
std::unordered_set<std::string> ReportedMissing;
212-
// Restrict access to the parent scanner class.
213-
friend class ModuleDependencyScanner;
214-
};
215-
216242
class ModuleDependencyScanner {
217243
public:
218244
ModuleDependencyScanner(SwiftDependencyScanningService &ScanningService,
@@ -223,7 +249,8 @@ class ModuleDependencyScanner {
223249
DependencyTracker &DependencyTracker,
224250
std::shared_ptr<llvm::cas::ObjectStore> CAS,
225251
std::shared_ptr<llvm::cas::ActionCache> ActionCache,
226-
DiagnosticEngine &Diagnostics, bool ParallelScan);
252+
DiagnosticEngine &Diagnostics, bool ParallelScan,
253+
bool EmitScanRemarks);
227254

228255
/// Identify the scanner invocation's main module's dependencies
229256
llvm::ErrorOr<ModuleDependencyInfo>
@@ -347,7 +374,7 @@ class ModuleDependencyScanner {
347374
/// For the provided collection of unresolved imports
348375
/// belonging to identified Swift dependnecies, execute a parallel
349376
/// query to the Clang dependency scanner for each import's module identifier.
350-
void performParallelClangModuleLookup(
377+
void performClangModuleLookup(
351378
const ImportStatementInfoMap &unresolvedImportsMap,
352379
const ImportStatementInfoMap &unresolvedOptionalImportsMap,
353380
BatchClangModuleLookupResult &result);
@@ -396,7 +423,7 @@ class ModuleDependencyScanner {
396423
private:
397424
const CompilerInvocation &ScanCompilerInvocation;
398425
ASTContext &ScanASTContext;
399-
ModuleDependencyIssueReporter IssueReporter;
426+
DependencyScannerDiagnosticReporter ScanDiagnosticReporter;
400427

401428
/// The location of where the explicitly-built modules will be output to
402429
std::string ModuleOutputPath;

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ class FrontendOptions {
399399
/// The path at which to either serialize or deserialize the dependency scanner cache.
400400
std::string SerializedDependencyScannerCachePath;
401401

402+
/// Emit dependency scanning related remarks.
403+
bool EmitDependencyScannerRemarks = false;
404+
402405
/// Emit remarks indicating use of the serialized module dependency scanning cache.
403406
bool EmitDependencyScannerCacheRemarks = false;
404407

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ def dependency_scan_cache_path : Separate<["-"], "dependency-scan-cache-path">,
295295
def dependency_scan_cache_remarks : Flag<["-"], "Rdependency-scan-cache">,
296296
HelpText<"Emit remarks indicating use of the serialized module dependency scanning cache.">;
297297

298+
def dependency_scan_remarks : Flag<["-"], "Rdependency-scan">,
299+
HelpText<"Emit remarks for various steps taken by the dependency scanner.">;
300+
298301
def parallel_scan : Flag<["-"], "parallel-scan">,
299302
HelpText<"Perform dependency scanning in-parallel.">;
300303
def no_parallel_scan : Flag<["-"], "no-parallel-scan">,

lib/AST/ModuleDependencies.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,14 @@ bool ModuleDependenciesCache::hasSwiftDependency(StringRef moduleName) const {
772772
return findSwiftDependency(moduleName).has_value();
773773
}
774774

775+
int ModuleDependenciesCache::numberOfClangDependencies() const {
776+
return ModuleDependenciesMap.at(ModuleDependencyKind::Clang).size();
777+
}
778+
int ModuleDependenciesCache::numberOfSwiftDependencies() const {
779+
return ModuleDependenciesMap.at(ModuleDependencyKind::SwiftInterface).size() +
780+
ModuleDependenciesMap.at(ModuleDependencyKind::SwiftBinary).size();
781+
}
782+
775783
void ModuleDependenciesCache::recordDependency(
776784
StringRef moduleName, ModuleDependencyInfo dependency) {
777785
auto dependenciesKind = dependency.getKind();
@@ -908,7 +916,6 @@ void ModuleDependenciesCache::setSwiftOverlayDependencies(
908916
ModuleDependencyID moduleID,
909917
const ArrayRef<ModuleDependencyID> dependencyIDs) {
910918
auto dependencyInfo = findKnownDependency(moduleID);
911-
assert(dependencyInfo.getSwiftOverlayDependencies().empty());
912919
#ifndef NDEBUG
913920
for (const auto &depID : dependencyIDs)
914921
assert(depID.Kind != ModuleDependencyKind::Clang);
@@ -923,7 +930,6 @@ void ModuleDependenciesCache::setCrossImportOverlayDependencies(
923930
ModuleDependencyID moduleID,
924931
const ModuleDependencyIDCollectionView dependencyIDs) {
925932
auto dependencyInfo = findKnownDependency(moduleID);
926-
assert(dependencyInfo.getCrossImportOverlayDependencies().empty());
927933
// Copy the existing info to a mutable one we can then replace it with,
928934
// after setting its overlay dependencies.
929935
auto updatedDependencyInfo = dependencyInfo;

0 commit comments

Comments
 (0)