Skip to content

Commit b567bec

Browse files
author
David Ungar
committed
Redo interface to inputDependencySourceMap.
1 parent 36247f2 commit b567bec

File tree

4 files changed

+96
-68
lines changed

4 files changed

+96
-68
lines changed

Sources/SwiftDriver/IncrementalCompilation/IncrementalDependencyAndInputSetup.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
239239
else {
240240
return buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals()
241241
}
242-
guard graph.populateInputDependencySourceMap() else {
242+
guard graph.populateInputDependencySourceMap(for: .inputsAddedSincePriors) else {
243243
return nil
244244
}
245245
graph.dotFileWriter?.write(graph)
@@ -269,7 +269,8 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
269269
{
270270
let graph = ModuleDependencyGraph(self, .buildingWithoutAPrior)
271271
assert(outputFileMap.onlySourceFilesHaveSwiftDeps())
272-
guard graph.populateInputDependencySourceMap() else {
272+
273+
guard graph.populateInputDependencySourceMap(for: .buildingFromSwiftDeps) else {
273274
return nil
274275
}
275276

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,21 @@ 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? {
67+
68+
@_spi(Testing) public func getNeededInput(for source: DependencySource) -> TypedVirtualPath? {
7269
guard let input =
7370
info.simulateGetInputFailure ? nil
74-
: inputDependencySourceMap[source]
71+
: inputDependencySourceMap.getInputIfKnown(for: source)
7572
else {
7673
info.diagnosticEngine.emit(warning: "Failed to find source file for '\(source.file.basename)', recovering with a full rebuild. Next build will be incremental.")
7774
info.reporter?.report(
@@ -148,7 +145,7 @@ extension ModuleDependencyGraph {
148145
return TransitivelyInvalidatedInputSet()
149146
}
150147
return collectInputsRequiringCompilationAfterProcessing(
151-
dependencySource: getSource(for: input))
148+
dependencySource: getRequiredSource(for: input))
152149
}
153150
}
154151

@@ -170,17 +167,17 @@ extension ModuleDependencyGraph {
170167
/// speculatively scheduled in the first wave.
171168
func collectInputsInvalidatedBy(input: TypedVirtualPath
172169
) -> TransitivelyInvalidatedInputArray {
173-
let changedSource = getSource(for: input)
170+
let changedSource = getRequiredSource(for: input)
174171
let allDependencySourcesToRecompile =
175172
collectSwiftDepsUsing(dependencySource: changedSource)
176173

177174
return allDependencySourcesToRecompile.compactMap {
178175
depedencySource in
179176
guard depedencySource != changedSource else {return nil}
180-
let dependentSource = inputDependencySourceMap[depedencySource]
177+
let dependentInput = inputDependencySourceMap.getInputIfKnown(for: depedencySource)
181178
info.reporter?.report(
182-
"Found dependent of \(input.file.basename):", dependentSource)
183-
return dependentSource
179+
"Found dependent of \(input.file.basename):", dependentInput)
180+
return dependentInput
184181
}
185182
}
186183

@@ -197,7 +194,7 @@ extension ModuleDependencyGraph {
197194
/// Does the graph contain any dependency nodes for a given source-code file?
198195
func containsNodes(forSourceFile file: TypedVirtualPath) -> Bool {
199196
precondition(file.type == .swift)
200-
guard let source = inputDependencySourceMap[file] else {
197+
guard let source = inputDependencySourceMap.getSourceIfKnown(for: file) else {
201198
return false
202199
}
203200
return containsNodes(forDependencySource: source)
@@ -207,17 +204,47 @@ extension ModuleDependencyGraph {
207204
return nodeFinder.findNodes(for: source).map {!$0.isEmpty}
208205
?? false
209206
}
210-
211-
/// Return true on success
212-
func populateInputDependencySourceMap() -> Bool {
207+
208+
/// Returns: false on error
209+
func populateInputDependencySourceMap(
210+
`for` purpose: InputDependencySourceMap.AdditionPurpose
211+
) -> Bool {
213212
let ofm = info.outputFileMap
214-
let de = info.diagnosticEngine
215-
return info.inputFiles.reduce(true) { okSoFar, input in
216-
ofm.getDependencySource(for: input, diagnosticEngine: de)
217-
.map {source in addMapEntry(input, source); return okSoFar } ?? false
213+
let diags = info.diagnosticEngine
214+
var allFound = true
215+
for input in info.inputFiles {
216+
if let source = ofm.getDependencySource(for: input, diagnosticEngine: diags) {
217+
inputDependencySourceMap.addEntry(input, source, for: purpose)
218+
}
219+
else {
220+
// Don't break in order to report all failures.
221+
allFound = false
222+
}
218223
}
224+
return allFound
219225
}
220226
}
227+
extension OutputFileMap {
228+
fileprivate func getDependencySource(
229+
for sourceFile: TypedVirtualPath,
230+
diagnosticEngine: DiagnosticsEngine
231+
) -> DependencySource? {
232+
assert(sourceFile.type == FileType.swift)
233+
guard let swiftDepsPath = existingOutput(inputFile: sourceFile.fileHandle,
234+
outputType: .swiftDeps)
235+
else {
236+
// The legacy driver fails silently here.
237+
diagnosticEngine.emit(
238+
.remarkDisabled("\(sourceFile.file.basename) has no swiftDeps file")
239+
)
240+
return nil
241+
}
242+
assert(VirtualPath.lookup(swiftDepsPath).extension == FileType.swiftDeps.rawValue)
243+
let typedSwiftDepsFile = TypedVirtualPath(file: swiftDepsPath, type: .swiftDeps)
244+
return DependencySource(typedSwiftDepsFile)
245+
}
246+
}
247+
221248
// MARK: - Scheduling the 2nd wave
222249
extension ModuleDependencyGraph {
223250
/// After `source` has been compiled, figure out what other source files need compiling.
@@ -227,7 +254,7 @@ extension ModuleDependencyGraph {
227254
func collectInputsRequiringCompilation(byCompiling input: TypedVirtualPath
228255
) -> TransitivelyInvalidatedInputSet? {
229256
precondition(input.type == .swift)
230-
let dependencySource = getSource(for: input)
257+
let dependencySource = getRequiredSource(for: input)
231258
return collectInputsRequiringCompilationAfterProcessing(
232259
dependencySource: dependencySource)
233260
}
@@ -314,7 +341,7 @@ extension ModuleDependencyGraph {
314341
) -> TransitivelyInvalidatedInputSet? {
315342
var invalidatedInputs = TransitivelyInvalidatedInputSet()
316343
for invalidatedSwiftDeps in collectSwiftDepsUsingInvalidated(nodes: directlyInvalidatedNodes) {
317-
guard let invalidatedInput = getInput(for: invalidatedSwiftDeps)
344+
guard let invalidatedInput = getNeededInput(for: invalidatedSwiftDeps)
318345
else {
319346
return nil
320347
}
@@ -392,27 +419,6 @@ extension ModuleDependencyGraph {
392419
}
393420
}
394421

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

@@ -537,10 +543,11 @@ extension ModuleDependencyGraph {
537543
.record(def: dependencyKey, use: self.allNodes[useID])
538544
assert(isNewUse, "Duplicate use def-use arc in graph?")
539545
}
540-
for (input, source) in inputDependencySourceMap {
541-
graph.addMapEntry(input, source)
546+
for (input, dependencySource) in inputDependencySourceMap {
547+
graph.inputDependencySourceMap.addEntry(input,
548+
dependencySource,
549+
for: .readingPriors)
542550
}
543-
544551
return self.graph
545552
}
546553

@@ -836,7 +843,7 @@ extension ModuleDependencyGraph {
836843
}
837844
}
838845

839-
for (input, dependencySource) in graph.inputDependencySourceMap {
846+
graph.inputDependencySourceMap.enumerateToSerializePriors { input, dependencySource in
840847
self.addIdentifier(input.file.name)
841848
self.addIdentifier(dependencySource.file.name)
842849
}
@@ -981,7 +988,8 @@ extension ModuleDependencyGraph {
981988
}
982989
}
983990
}
984-
for (input, dependencySource) in graph.inputDependencySourceMap {
991+
graph.inputDependencySourceMap.enumerateToSerializePriors {
992+
input, dependencySource in
985993
serializer.stream.writeRecord(serializer.abbreviations[.mapNode]!) {
986994
$0.append(RecordID.mapNode)
987995
$0.append(serializer.lookupIdentifierCode(for: input.file.name))
@@ -1117,6 +1125,6 @@ extension ModuleDependencyGraph {
11171125
_ mockInput: TypedVirtualPath,
11181126
_ mockDependencySource: DependencySource
11191127
) {
1120-
addMapEntry(mockInput, mockDependencySource)
1128+
inputDependencySourceMap.addEntry(mockInput, mockDependencySource, for: .mocking)
11211129
}
11221130
}

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)