Skip to content

Commit 5786b73

Browse files
author
David Ungar
committed
Redo interface to inputDependencySourceMap.
# Conflicts: # Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift
1 parent 07269b8 commit 5786b73

File tree

4 files changed

+97
-67
lines changed

4 files changed

+97
-67
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: 63 additions & 53 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

@@ -163,7 +161,7 @@ extension ModuleDependencyGraph {
163161
/// speculatively scheduled in the first wave.
164162
func collectInputsInvalidatedBy(input: TypedVirtualPath
165163
) -> TransitivelyInvalidatedInputArray {
166-
let changedSource = getSource(for: input)
164+
let changedSource = getRequiredSource(for: input)
167165
let allDependencySourcesToRecompile =
168166
collectSwiftDepsUsing(dependencySource: changedSource)
169167

@@ -172,8 +170,8 @@ extension ModuleDependencyGraph {
172170
guard dependencySource != changedSource else {return nil}
173171
let dependentSource = inputDependencySourceMap[dependencySource]
174172
info.reporter?.report(
175-
"Found dependent of \(input.file.basename):", dependentSource)
176-
return dependentSource
173+
"Found dependent of \(input.file.basename):", dependentInput)
174+
return dependentInput
177175
}
178176
}
179177

@@ -190,7 +188,7 @@ extension ModuleDependencyGraph {
190188
/// Does the graph contain any dependency nodes for a given source-code file?
191189
func containsNodes(forSourceFile file: TypedVirtualPath) -> Bool {
192190
precondition(file.type == .swift)
193-
guard let source = inputDependencySourceMap[file] else {
191+
guard let source = inputDependencySourceMap.getSourceIfKnown(for: file) else {
194192
return false
195193
}
196194
return containsNodes(forDependencySource: source)
@@ -200,17 +198,47 @@ extension ModuleDependencyGraph {
200198
return nodeFinder.findNodes(for: source).map {!$0.isEmpty}
201199
?? false
202200
}
203-
204-
/// Return true on success
205-
func populateInputDependencySourceMap() -> Bool {
201+
202+
/// Returns: false on error
203+
func populateInputDependencySourceMap(
204+
`for` purpose: InputDependencySourceMap.AdditionPurpose
205+
) -> Bool {
206206
let ofm = info.outputFileMap
207-
let de = info.diagnosticEngine
208-
return info.inputFiles.reduce(true) { okSoFar, input in
209-
ofm.getDependencySource(for: input, diagnosticEngine: de)
210-
.map {source in addMapEntry(input, source); return okSoFar } ?? false
207+
let diags = info.diagnosticEngine
208+
var allFound = true
209+
for input in info.inputFiles {
210+
if let source = ofm.getDependencySource(for: input, diagnosticEngine: diags) {
211+
inputDependencySourceMap.addEntry(input, source, for: purpose)
212+
}
213+
else {
214+
// Don't break in order to report all failures.
215+
allFound = false
216+
}
217+
}
218+
return allFound
219+
}
220+
}
221+
extension OutputFileMap {
222+
fileprivate func getDependencySource(
223+
for sourceFile: TypedVirtualPath,
224+
diagnosticEngine: DiagnosticsEngine
225+
) -> DependencySource? {
226+
assert(sourceFile.type == FileType.swift)
227+
guard let swiftDepsPath = existingOutput(inputFile: sourceFile.fileHandle,
228+
outputType: .swiftDeps)
229+
else {
230+
// The legacy driver fails silently here.
231+
diagnosticEngine.emit(
232+
.remarkDisabled("\(sourceFile.file.basename) has no swiftDeps file")
233+
)
234+
return nil
211235
}
236+
assert(VirtualPath.lookup(swiftDepsPath).extension == FileType.swiftDeps.rawValue)
237+
let typedSwiftDepsFile = TypedVirtualPath(file: swiftDepsPath, type: .swiftDeps)
238+
return DependencySource(typedSwiftDepsFile)
212239
}
213240
}
241+
214242
// MARK: - Scheduling the 2nd wave
215243
extension ModuleDependencyGraph {
216244
/// After `source` has been compiled, figure out what other source files need compiling.
@@ -220,7 +248,7 @@ extension ModuleDependencyGraph {
220248
func collectInputsRequiringCompilation(byCompiling input: TypedVirtualPath
221249
) -> TransitivelyInvalidatedInputSet? {
222250
precondition(input.type == .swift)
223-
let dependencySource = getSource(for: input)
251+
let dependencySource = getRequiredSource(for: input)
224252
return collectInputsRequiringCompilationAfterProcessing(
225253
dependencySource: dependencySource)
226254
}
@@ -315,7 +343,8 @@ extension ModuleDependencyGraph {
315343
) -> TransitivelyInvalidatedInputSet? {
316344
var invalidatedInputs = TransitivelyInvalidatedInputSet()
317345
for invalidatedSwiftDeps in collectSwiftDepsUsingInvalidated(nodes: directlyInvalidatedNodes) {
318-
guard let invalidatedInput = getInput(for: invalidatedSwiftDeps) else {
346+
guard let invalidatedInput = getNeededInput(for: invalidatedSwiftDeps)
347+
else {
319348
return nil
320349
}
321350
invalidatedInputs.insert(invalidatedInput)
@@ -439,27 +468,6 @@ extension ModuleDependencyGraph {
439468
}
440469
}
441470

442-
extension OutputFileMap {
443-
fileprivate func getDependencySource(
444-
for sourceFile: TypedVirtualPath,
445-
diagnosticEngine: DiagnosticsEngine
446-
) -> DependencySource? {
447-
assert(sourceFile.type == FileType.swift)
448-
guard let swiftDepsPath = existingOutput(inputFile: sourceFile.fileHandle,
449-
outputType: .swiftDeps)
450-
else {
451-
// The legacy driver fails silently here.
452-
diagnosticEngine.emit(
453-
.remarkDisabled("\(sourceFile.file.basename) has no swiftDeps file")
454-
)
455-
return nil
456-
}
457-
assert(VirtualPath.lookup(swiftDepsPath).extension == FileType.swiftDeps.rawValue)
458-
let typedSwiftDepsFile = TypedVirtualPath(file: swiftDepsPath, type: .swiftDeps)
459-
return DependencySource(typedSwiftDepsFile)
460-
}
461-
}
462-
463471
// MARK: - tracking traced nodes
464472
extension ModuleDependencyGraph {
465473

@@ -584,10 +592,11 @@ extension ModuleDependencyGraph {
584592
.record(def: dependencyKey, use: self.allNodes[useID])
585593
assert(isNewUse, "Duplicate use def-use arc in graph?")
586594
}
587-
for (input, source) in inputDependencySourceMap {
588-
graph.addMapEntry(input, source)
595+
for (input, dependencySource) in inputDependencySourceMap {
596+
graph.inputDependencySourceMap.addEntry(input,
597+
dependencySource,
598+
for: .readingPriors)
589599
}
590-
591600
return self.graph
592601
}
593602

@@ -883,7 +892,7 @@ extension ModuleDependencyGraph {
883892
}
884893
}
885894

886-
for (input, dependencySource) in graph.inputDependencySourceMap {
895+
graph.inputDependencySourceMap.enumerateToSerializePriors { input, dependencySource in
887896
self.addIdentifier(input.file.name)
888897
self.addIdentifier(dependencySource.file.name)
889898
}
@@ -1028,7 +1037,8 @@ extension ModuleDependencyGraph {
10281037
}
10291038
}
10301039
}
1031-
for (input, dependencySource) in graph.inputDependencySourceMap {
1040+
graph.inputDependencySourceMap.enumerateToSerializePriors {
1041+
input, dependencySource in
10321042
serializer.stream.writeRecord(serializer.abbreviations[.mapNode]!) {
10331043
$0.append(RecordID.mapNode)
10341044
$0.append(serializer.lookupIdentifierCode(for: input.file.name))
@@ -1164,6 +1174,6 @@ extension ModuleDependencyGraph {
11641174
_ mockInput: TypedVirtualPath,
11651175
_ mockDependencySource: DependencySource
11661176
) {
1167-
addMapEntry(mockInput, mockDependencySource)
1177+
inputDependencySourceMap.addEntry(mockInput, mockDependencySource, for: .mocking)
11681178
}
11691179
}

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)