Skip to content

Commit 72d9da7

Browse files
author
David Ungar
committed
Redo interface to inputDependencySourceMap.
1 parent 8a3fc05 commit 72d9da7

File tree

4 files changed

+98
-68
lines changed

4 files changed

+98
-68
lines changed

Sources/SwiftDriver/IncrementalCompilation/IncrementalDependencyAndInputSetup.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
226226
else {
227227
return buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals()
228228
}
229-
guard graph.populateInputDependencySourceMap() else {
229+
guard graph.populateInputDependencySourceMap(for: .inputsAddedSincePriors) else {
230230
return nil
231231
}
232232
graph.dotFileWriter?.write(graph)
@@ -256,7 +256,8 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
256256
{
257257
let graph = ModuleDependencyGraph(self, .buildingWithoutAPrior)
258258
assert(outputFileMap.onlySourceFilesHaveSwiftDeps())
259-
guard graph.populateInputDependencySourceMap() else {
259+
260+
guard graph.populateInputDependencySourceMap(for: .buildingFromSwiftDeps) else {
260261
return nil
261262
}
262263

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift

Lines changed: 64 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,20 @@ import SwiftOptions
5454
self.creationPhase = phase
5555
}
5656

57-
private func addMapEntry(_ input: TypedVirtualPath, _ dependencySource: DependencySource) {
58-
assert(input.type == .swift && dependencySource.typedFile.type == .swiftDeps)
59-
inputDependencySourceMap[input] = dependencySource
60-
}
61-
62-
@_spi(Testing) public func getSource(for input: TypedVirtualPath,
63-
function: String = #function,
64-
file: String = #file,
65-
line: Int = #line) -> DependencySource {
66-
guard let source = inputDependencySourceMap[input] else {
57+
@_spi(Testing) public func getRequiredSource(for input: TypedVirtualPath,
58+
function: String = #function,
59+
file: String = #file,
60+
line: Int = #line) -> DependencySource {
61+
guard let source = inputDependencySourceMap.getSourceIfKnown(for: input)
62+
else {
6763
fatalError("\(input.file.basename) not found in inputDependencySourceMap, \(file):\(line) in \(function)")
6864
}
6965
return source
7066
}
71-
@_spi(Testing) public func getInput(for source: DependencySource) -> TypedVirtualPath? {
72-
guard let input = inputDependencySourceMap[source] else {
67+
68+
@_spi(Testing) public func getNeededInput(for source: DependencySource) -> TypedVirtualPath? {
69+
guard let input = inputDependencySourceMap.getInputIfKnown(for: source)
70+
else {
7371
info.diagnosticEngine.emit(warning: "Failed to find source file for '\(source.file.basename)', recovering with a full rebuild. Next build will be incremental.")
7472
return nil
7573
}
@@ -143,7 +141,7 @@ extension ModuleDependencyGraph {
143141
return TransitivelyInvalidatedInputSet()
144142
}
145143
return collectInputsRequiringCompilationAfterProcessing(
146-
dependencySource: getSource(for: input))
144+
dependencySource: getRequiredSource(for: input))
147145
}
148146
}
149147

@@ -165,17 +163,17 @@ extension ModuleDependencyGraph {
165163
/// speculatively scheduled in the first wave.
166164
func collectInputsInvalidatedBy(input: TypedVirtualPath
167165
) -> TransitivelyInvalidatedInputArray {
168-
let changedSource = getSource(for: input)
166+
let changedSource = getRequiredSource(for: input)
169167
let allDependencySourcesToRecompile =
170168
collectSwiftDepsUsing(dependencySource: changedSource)
171169

172170
return allDependencySourcesToRecompile.compactMap {
173171
depedencySource in
174172
guard depedencySource != changedSource else {return nil}
175-
let dependentSource = inputDependencySourceMap[depedencySource]
173+
let dependentInput = inputDependencySourceMap.getInputIfKnown(for: depedencySource)
176174
info.reporter?.report(
177-
"Found dependent of \(input.file.basename):", dependentSource)
178-
return dependentSource
175+
"Found dependent of \(input.file.basename):", dependentInput)
176+
return dependentInput
179177
}
180178
}
181179

@@ -192,7 +190,7 @@ extension ModuleDependencyGraph {
192190
/// Does the graph contain any dependency nodes for a given source-code file?
193191
func containsNodes(forSourceFile file: TypedVirtualPath) -> Bool {
194192
precondition(file.type == .swift)
195-
guard let source = inputDependencySourceMap[file] else {
193+
guard let source = inputDependencySourceMap.getSourceIfKnown(for: file) else {
196194
return false
197195
}
198196
return containsNodes(forDependencySource: source)
@@ -202,17 +200,47 @@ extension ModuleDependencyGraph {
202200
return nodeFinder.findNodes(for: source).map {!$0.isEmpty}
203201
?? false
204202
}
205-
206-
/// Return true on success
207-
func populateInputDependencySourceMap() -> Bool {
203+
204+
/// Returns: false on error
205+
func populateInputDependencySourceMap(
206+
`for` purpose: InputDependencySourceMap.AdditionPurpose
207+
) -> Bool {
208208
let ofm = info.outputFileMap
209-
let de = info.diagnosticEngine
210-
return info.inputFiles.reduce(true) { okSoFar, input in
211-
ofm.getDependencySource(for: input, diagnosticEngine: de)
212-
.map {source in addMapEntry(input, source); return okSoFar } ?? false
209+
let diags = info.diagnosticEngine
210+
var allFound = true
211+
for input in info.inputFiles {
212+
if let source = ofm.getDependencySource(for: input, diagnosticEngine: diags) {
213+
inputDependencySourceMap.addEntry(input, source, for: purpose)
214+
}
215+
else {
216+
// Don't break in order to report all failures.
217+
allFound = false
218+
}
213219
}
220+
return allFound
214221
}
215222
}
223+
extension OutputFileMap {
224+
fileprivate func getDependencySource(
225+
for sourceFile: TypedVirtualPath,
226+
diagnosticEngine: DiagnosticsEngine
227+
) -> DependencySource? {
228+
assert(sourceFile.type == FileType.swift)
229+
guard let swiftDepsPath = existingOutput(inputFile: sourceFile.fileHandle,
230+
outputType: .swiftDeps)
231+
else {
232+
// The legacy driver fails silently here.
233+
diagnosticEngine.emit(
234+
.remarkDisabled("\(sourceFile.file.basename) has no swiftDeps file")
235+
)
236+
return nil
237+
}
238+
assert(VirtualPath.lookup(swiftDepsPath).extension == FileType.swiftDeps.rawValue)
239+
let typedSwiftDepsFile = TypedVirtualPath(file: swiftDepsPath, type: .swiftDeps)
240+
return DependencySource(typedSwiftDepsFile)
241+
}
242+
}
243+
216244
// MARK: - Scheduling the 2nd wave
217245
extension ModuleDependencyGraph {
218246
/// After `source` has been compiled, figure out what other source files need compiling.
@@ -222,7 +250,7 @@ extension ModuleDependencyGraph {
222250
func collectInputsRequiringCompilation(byCompiling input: TypedVirtualPath
223251
) -> TransitivelyInvalidatedInputSet? {
224252
precondition(input.type == .swift)
225-
let dependencySource = getSource(for: input)
253+
let dependencySource = getRequiredSource(for: input)
226254
return collectInputsRequiringCompilationAfterProcessing(
227255
dependencySource: dependencySource)
228256
}
@@ -317,7 +345,8 @@ extension ModuleDependencyGraph {
317345
) -> TransitivelyInvalidatedInputSet? {
318346
var invalidatedInputs = TransitivelyInvalidatedInputSet()
319347
for invalidatedSwiftDeps in collectSwiftDepsUsingInvalidated(nodes: directlyInvalidatedNodes) {
320-
guard let invalidatedInput = getInput(for: invalidatedSwiftDeps) else {
348+
guard let invalidatedInput = getNeededInput(for: invalidatedSwiftDeps)
349+
else {
321350
return nil
322351
}
323352
invalidatedInputs.insert(invalidatedInput)
@@ -394,27 +423,6 @@ extension ModuleDependencyGraph {
394423
}
395424
}
396425

397-
extension OutputFileMap {
398-
fileprivate func getDependencySource(
399-
for sourceFile: TypedVirtualPath,
400-
diagnosticEngine: DiagnosticsEngine
401-
) -> DependencySource? {
402-
assert(sourceFile.type == FileType.swift)
403-
guard let swiftDepsPath = existingOutput(inputFile: sourceFile.fileHandle,
404-
outputType: .swiftDeps)
405-
else {
406-
// The legacy driver fails silently here.
407-
diagnosticEngine.emit(
408-
.remarkDisabled("\(sourceFile.file.basename) has no swiftDeps file")
409-
)
410-
return nil
411-
}
412-
assert(VirtualPath.lookup(swiftDepsPath).extension == FileType.swiftDeps.rawValue)
413-
let typedSwiftDepsFile = TypedVirtualPath(file: swiftDepsPath, type: .swiftDeps)
414-
return DependencySource(typedSwiftDepsFile)
415-
}
416-
}
417-
418426
// MARK: - tracking traced nodes
419427
extension ModuleDependencyGraph {
420428

@@ -539,10 +547,11 @@ extension ModuleDependencyGraph {
539547
.record(def: dependencyKey, use: self.allNodes[useID])
540548
assert(isNewUse, "Duplicate use def-use arc in graph?")
541549
}
542-
for (input, source) in inputDependencySourceMap {
543-
graph.addMapEntry(input, source)
550+
for (input, dependencySource) in inputDependencySourceMap {
551+
graph.inputDependencySourceMap.addEntry(input,
552+
dependencySource,
553+
for: .readingPriors)
544554
}
545-
546555
return self.graph
547556
}
548557

@@ -838,7 +847,7 @@ extension ModuleDependencyGraph {
838847
}
839848
}
840849

841-
for (input, dependencySource) in graph.inputDependencySourceMap {
850+
graph.inputDependencySourceMap.enumerateToSerializePriors { input, dependencySource in
842851
self.addIdentifier(input.file.name)
843852
self.addIdentifier(dependencySource.file.name)
844853
}
@@ -983,7 +992,8 @@ extension ModuleDependencyGraph {
983992
}
984993
}
985994
}
986-
for (input, dependencySource) in graph.inputDependencySourceMap {
995+
graph.inputDependencySourceMap.enumerateToSerializePriors {
996+
input, dependencySource in
987997
serializer.stream.writeRecord(serializer.abbreviations[.mapNode]!) {
988998
$0.append(RecordID.mapNode)
989999
$0.append(serializer.lookupIdentifierCode(for: input.file.name))
@@ -1119,6 +1129,6 @@ extension ModuleDependencyGraph {
11191129
_ mockInput: TypedVirtualPath,
11201130
_ mockDependencySource: DependencySource
11211131
) {
1122-
addMapEntry(mockInput, mockDependencySource)
1132+
inputDependencySourceMap.addEntry(mockInput, mockDependencySource, for: .mocking)
11231133
}
11241134
}

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/InputDependencySourceMap.swift

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111
import Foundation
12+
import TSCBasic
1213

13-
@_spi(Testing) public struct InputDependencySourceMap: Equatable, Sequence {
14+
@_spi(Testing) public struct InputDependencySourceMap: Equatable {
1415

1516
/// Maps input files (e.g. .swift) to and from the DependencySource object.
1617
///
@@ -28,19 +29,36 @@ import Foundation
2829

2930
public typealias BiMap = BidirectionalMap<TypedVirtualPath, DependencySource>
3031
@_spi(Testing) public var biMap = BiMap()
31-
32-
@_spi(Testing) public subscript(input: TypedVirtualPath) -> DependencySource? {
33-
get { biMap[input] }
34-
set { biMap[input] = newValue }
32+
}
33+
34+
// MARK: - Accessing
35+
extension InputDependencySourceMap {
36+
@_spi(Testing) public func getSourceIfKnown(for input: TypedVirtualPath) -> DependencySource? {
37+
biMap[input]
3538
}
36-
37-
@_spi(Testing) public private(set) subscript(dependencySource: DependencySource) -> TypedVirtualPath? {
38-
get { biMap[dependencySource] }
39-
set { biMap[dependencySource] = newValue }
39+
40+
@_spi(Testing) public func getInputIfKnown(for source: DependencySource) -> TypedVirtualPath? {
41+
biMap[source]
4042
}
4143

42-
public func makeIterator() -> BiMap.Iterator {
43-
biMap.makeIterator()
44+
@_spi(Testing) public func enumerateToSerializePriors(
45+
_ eachFn: (TypedVirtualPath, DependencySource) -> Void
46+
) {
47+
biMap.forEach(eachFn)
4448
}
49+
}
4550

51+
// MARK: - Populating
52+
extension InputDependencySourceMap {
53+
public enum AdditionPurpose {
54+
case mocking,
55+
buildingFromSwiftDeps,
56+
readingPriors,
57+
inputsAddedSincePriors }
58+
@_spi(Testing) public mutating func addEntry(_ input: TypedVirtualPath,
59+
_ dependencySource: DependencySource,
60+
`for` _ : AdditionPurpose) {
61+
assert(input.type == .swift && dependencySource.typedFile.type == .swiftDeps)
62+
biMap[input] = dependencySource
63+
}
4664
}

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/Tracer.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ extension ModuleDependencyGraph.Tracer {
121121
path.compactMap { node in
122122
node.dependencySource.map {
123123
source in
124-
graph.inputDependencySourceMap[source].map { input in
124+
graph.inputDependencySourceMap.getInputIfKnown(for: source).map {
125+
input in
125126
"\(node.key) in \(input.file.basename)"
126127
}
127128
?? "\(node.key)"

0 commit comments

Comments
 (0)