Skip to content

Commit f5a9401

Browse files
author
David Ungar
authored
Merge pull request #494 from davidungar/def-use-serialization
[Incremental] Add `inputDependencySourceMap` to `ModuleDependencyGraph` serialization
2 parents a7ff2ab + e41b83a commit f5a9401

File tree

4 files changed

+82
-10
lines changed

4 files changed

+82
-10
lines changed

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ extension ModuleDependencyGraph {
387387
case useIDNode = 4
388388
case externalDepNode = 5
389389
case identifierNode = 6
390+
case mapNode = 7
390391

391392
/// The human-readable name of this record.
392393
///
@@ -407,6 +408,8 @@ extension ModuleDependencyGraph {
407408
return "EXTERNAL_DEP_NODE"
408409
case .identifierNode:
409410
return "IDENTIFIER_NODE"
411+
case .mapNode:
412+
return "MAP_NODE"
410413
}
411414
}
412415
}
@@ -420,6 +423,7 @@ extension ModuleDependencyGraph {
420423
case malformedIdentifierRecord
421424
case malformedModuleDepGraphNodeRecord
422425
case malformedDependsOnRecord
426+
case malformedMapRecord
423427
case malformedExternalDepNodeRecord
424428
case unknownRecord
425429
case unexpectedSubblock
@@ -436,14 +440,17 @@ extension ModuleDependencyGraph {
436440
/// - diagnosticEngine: The diagnostics engine.
437441
/// - reporter: An optional reporter used to log information about
438442
/// - Throws: An error describing any failures to read the graph from the given file.
439-
/// - Returns: A fully deserialized ModuleDependencyGraph.
443+
/// - Returns: A fully deserialized ModuleDependencyGraph, or nil if nothing is there
440444
static func read(
441445
from path: VirtualPath,
442446
on fileSystem: FileSystem,
443447
diagnosticEngine: DiagnosticsEngine,
444448
reporter: IncrementalCompilationState.Reporter?,
445449
options: IncrementalCompilationState.Options
446-
) throws -> ModuleDependencyGraph {
450+
) throws -> ModuleDependencyGraph? {
451+
guard try fileSystem.exists(path) else {
452+
return nil
453+
}
447454
let data = try fileSystem.readFileContents(path)
448455

449456
struct Visitor: BitstreamVisitor {
@@ -456,6 +463,7 @@ extension ModuleDependencyGraph {
456463
private var identifiers: [String] = [""]
457464
private var currentDefKey: DependencyKey? = nil
458465
private var nodeUses: [DependencyKey: [Int]] = [:]
466+
private var inputDependencySourceMap: [(TypedVirtualPath, DependencySource)] = []
459467
private var allNodes: [Node] = []
460468

461469
init(
@@ -467,7 +475,7 @@ extension ModuleDependencyGraph {
467475
self.graph = ModuleDependencyGraph(
468476
diagnosticEngine: diagnosticEngine,
469477
reporter: reporter,
470-
fileSystem: fileSystem,
478+
fileSystem: fileSystem,
471479
options: options)
472480
}
473481

@@ -479,6 +487,10 @@ extension ModuleDependencyGraph {
479487
assert(isNewUse, "Duplicate use def-use arc in graph?")
480488
}
481489
}
490+
for (input, source) in inputDependencySourceMap {
491+
graph.inputDependencySourceMap[input] = source
492+
}
493+
482494
return self.graph
483495
}
484496

@@ -568,6 +580,25 @@ extension ModuleDependencyGraph {
568580
throw ReadError.malformedDependsOnRecord
569581
}
570582
self.nodeUses[key, default: []].append(Int(record.fields[0]))
583+
case .mapNode:
584+
guard record.fields.count == 2,
585+
record.fields[0] < identifiers.count,
586+
record.fields[1] < identifiers.count
587+
else {
588+
throw ReadError.malformedModuleDepGraphNodeRecord
589+
}
590+
let inputPathString = identifiers[Int(record.fields[0])]
591+
let dependencySourcePathString = identifiers[Int(record.fields[1])]
592+
let inputPath = try VirtualPath(path: inputPathString)
593+
let dependencySourcePath = try VirtualPath(path: dependencySourcePathString)
594+
guard inputPath.extension == FileType.swift.rawValue,
595+
dependencySourcePath.extension == FileType.swiftDeps.rawValue,
596+
let dependencySource = DependencySource(dependencySourcePath)
597+
else {
598+
throw ReadError.malformedMapRecord
599+
}
600+
let input = TypedVirtualPath(file: inputPath, type: .swift)
601+
inputDependencySourceMap.append((input, dependencySource))
571602
case .externalDepNode:
572603
guard record.fields.count == 2,
573604
record.fields[0] < identifiers.count,
@@ -605,7 +636,9 @@ extension ModuleDependencyGraph {
605636
else {
606637
throw ReadError.malformedMetadataRecord
607638
}
608-
return visitor.finalizeGraph()
639+
let graph = visitor.finalizeGraph()
640+
graph.reporter?.report("Read dependency graph", path)
641+
return graph
609642
}
610643
}
611644

@@ -690,6 +723,7 @@ extension ModuleDependencyGraph {
690723
self.emitRecordID(.useIDNode)
691724
self.emitRecordID(.externalDepNode)
692725
self.emitRecordID(.identifierNode)
726+
self.emitRecordID(.mapNode)
693727
}
694728
}
695729

@@ -751,6 +785,11 @@ extension ModuleDependencyGraph {
751785
}
752786
}
753787

788+
for (input, dependencySource) in graph.inputDependencySourceMap {
789+
self.addIdentifier(input.file.name)
790+
self.addIdentifier(dependencySource.file.name)
791+
}
792+
754793
for edF in graph.fingerprintedExternalDependencies {
755794
self.addIdentifier(edF.externalDependency.file.name)
756795
}
@@ -822,7 +861,14 @@ extension ModuleDependencyGraph {
822861
// identifier data
823862
.blob
824863
])
825-
}
864+
self.abbreviate(.mapNode, [
865+
.literal(RecordID.mapNode.rawValue),
866+
// input name
867+
.vbr(chunkBitWidth: 13),
868+
// dependencySource name
869+
.vbr(chunkBitWidth: 13),
870+
])
871+
}
826872

827873
private func abbreviate(
828874
_ record: RecordID,
@@ -884,6 +930,13 @@ extension ModuleDependencyGraph {
884930
}
885931
}
886932
}
933+
for (input, dependencySource) in graph.inputDependencySourceMap {
934+
serializer.stream.writeRecord(serializer.abbreviations[.mapNode]!) {
935+
$0.append(RecordID.mapNode)
936+
$0.append(serializer.lookupIdentifierCode(for: input.file.name))
937+
$0.append(serializer.lookupIdentifierCode(for: dependencySource.file.name))
938+
}
939+
}
887940

888941
for fingerprintedExternalDependency in graph.fingerprintedExternalDependencies {
889942
serializer.stream.writeRecord(serializer.abbreviations[.externalDepNode]!, {
@@ -1053,3 +1106,11 @@ extension Set where Element == FingerprintedExternalDependency {
10531106
self == other
10541107
}
10551108
}
1109+
1110+
// MARK: - Testing
1111+
extension ModuleDependencyGraph {
1112+
/// Must be here so that the setter can be private
1113+
func recordMapping(mockInput input: TypedVirtualPath, mockDependencySource dependencySource: DependencySource) {
1114+
inputDependencySourceMap[input] = dependencySource
1115+
}
1116+
}

Tests/SwiftDriverTests/DependencyGraphSerializationTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ class DependencyGraphSerializationTests: XCTestCase {
2121
let fs = InMemoryFileSystem()
2222
graph.write(to: mockPath, on: fs, compilerVersion: "Swift 99")
2323

24-
let deserializedGraph = try ModuleDependencyGraph.read(from: mockPath,
25-
on: fs,
26-
diagnosticEngine: de,
27-
reporter: nil,
28-
options: [])
24+
let deserializedGraph = try XCTUnwrap(
25+
try ModuleDependencyGraph.read(from: mockPath,
26+
on: fs,
27+
diagnosticEngine: de,
28+
reporter: nil,
29+
options: []))
2930
var originalNodes = Set<ModuleDependencyGraph.Node>()
3031
graph.nodeFinder.forEachNode {
3132
originalNodes.insert($0)

Tests/SwiftDriverTests/Helpers/MockingIncrementalCompilation.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ extension ModuleDependencyGraph {
3030
}
3131

3232
// MARK: - mocking
33+
34+
extension TypedVirtualPath {
35+
init(mockInput i: Int) {
36+
self.init(file: try! VirtualPath(path: "\(i).swift"), type: .swift)
37+
}
38+
}
39+
3340
extension DependencySource {
3441
init(mock i: Int) {
3542
self.init(try! VirtualPath(path: String(i) + "." + FileType.swiftDeps.rawValue))!

Tests/SwiftDriverTests/ModuleDependencyGraphTests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,9 @@ extension ModuleDependencyGraph {
927927
hadCompilationError: Bool = false
928928
) -> Set<ModuleDependencyGraph.Node> {
929929
let dependencySource = DependencySource(mock: swiftDepsIndex)
930+
// Only needed for serialization testing:
931+
recordMapping(mockInput: TypedVirtualPath.init(mockInput: swiftDepsIndex),
932+
mockDependencySource: dependencySource)
930933
let interfaceHash =
931934
interfaceHashIfPresent ?? dependencySource.interfaceHashForMockDependencySource
932935

0 commit comments

Comments
 (0)