Skip to content

Commit 17bd7cf

Browse files
author
David Ungar
authored
Merge pull request #472 from davidungar/now-what
[Incremental] Support reading priors and incremental external dependencies.
2 parents 5f1d731 + 934f60f commit 17bd7cf

17 files changed

+1079
-945
lines changed

Sources/SwiftDriver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ add_library(SwiftDriver
4545
"IncrementalCompilation/DictionaryOfDictionaries.swift"
4646
"IncrementalCompilation/ExternalDependencyAndFingerprintEnforcer.swift"
4747
"IncrementalCompilation/IncrementalCompilationState.swift"
48+
"IncrementalCompilation/InitialStateComputer.swift"
4849
"IncrementalCompilation/InputInfo.swift"
4950
"IncrementalCompilation/KeyAndFingerprintHolder.swift"
5051
"IncrementalCompilation/ModuleDependencyGraph.swift"

Sources/SwiftDriver/IncrementalCompilation/BidirectionalMap.swift

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,50 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
/// Like a two-way dictionary, only works for accessing present members
13+
/// Like a two-way dictionary
1414
public struct BidirectionalMap<T1: Hashable, T2: Hashable>: Equatable, Sequence {
1515
private var map1: [T1: T2] = [:]
1616
private var map2: [T2: T1] = [:]
1717

1818
public init() {}
1919

20-
public subscript(_ key: T1) -> T2 {
20+
public subscript(_ key: T1) -> T2? {
2121
get {
2222
guard let value = map1[key]
2323
else {
24-
fatalError("\(key) was not present")
24+
return nil
2525
}
2626
return value
2727
}
2828
set {
29-
map1[key] = newValue
30-
map2[newValue] = key
29+
if let newValue = newValue {
30+
map1[key] = newValue
31+
map2[newValue] = key
32+
return
33+
}
34+
if let oldValue = map1.removeValue(forKey: key) {
35+
map2.removeValue(forKey: oldValue)
36+
}
3137
}
3238
}
33-
public subscript(_ key: T2) -> T1 {
39+
public subscript(_ key: T2) -> T1? {
3440
get {
3541
guard let value = map2[key]
3642
else {
37-
fatalError("\(key) was not present")
43+
return nil
3844
}
3945
return value
4046
}
41-
set { self[newValue] = key }
47+
set {
48+
if let newValue = newValue {
49+
map2[key] = newValue
50+
map1[newValue] = key
51+
return
52+
}
53+
if let oldValue = map2.removeValue(forKey: key) {
54+
map1.removeValue(forKey: oldValue)
55+
}
56+
}
4257
}
4358
public func contains(key: T1) -> Bool {
4459
map1.keys.contains(key)

Sources/SwiftDriver/IncrementalCompilation/BuildRecordInfo.swift

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,26 @@ import SwiftOptions
4747
// FIXME: Use an actor when possible.
4848
private let confinementQueue = DispatchQueue(label: "com.apple.swift-driver.jobresults")
4949

50-
init?(
50+
@_spi(Testing) public init(
51+
buildRecordPath: VirtualPath,
52+
fileSystem: FileSystem,
53+
currentArgsHash: String,
54+
actualSwiftVersion: String,
55+
timeBeforeFirstJob: Date,
56+
diagnosticEngine: DiagnosticsEngine,
57+
compilationInputModificationDates: [TypedVirtualPath: Date])
58+
{
59+
self.buildRecordPath = buildRecordPath
60+
self.fileSystem = fileSystem
61+
self.currentArgsHash = currentArgsHash
62+
self.actualSwiftVersion = actualSwiftVersion
63+
self.timeBeforeFirstJob = timeBeforeFirstJob
64+
self.diagnosticEngine = diagnosticEngine
65+
self.compilationInputModificationDates = compilationInputModificationDates
66+
}
67+
68+
69+
convenience init?(
5170
actualSwiftVersion: String,
5271
compilerOutputType: FileType?,
5372
workingDirectory: AbsolutePath?,
@@ -67,16 +86,20 @@ import SwiftOptions
6786
else {
6887
return nil
6988
}
70-
self.actualSwiftVersion = actualSwiftVersion
71-
self.currentArgsHash = Self.computeArgsHash(parsedOptions)
72-
self.buildRecordPath = buildRecordPath
73-
self.compilationInputModificationDates =
89+
let currentArgsHash = Self.computeArgsHash(parsedOptions)
90+
let compilationInputModificationDates =
7491
recordedInputModificationDates.filter { input, _ in
7592
input.type.isPartOfSwiftCompilation
7693
}
77-
self.diagnosticEngine = diagnosticEngine
78-
self.fileSystem = fileSystem
79-
self.timeBeforeFirstJob = Date()
94+
95+
self.init(
96+
buildRecordPath: buildRecordPath,
97+
fileSystem: fileSystem,
98+
currentArgsHash: currentArgsHash,
99+
actualSwiftVersion: actualSwiftVersion,
100+
timeBeforeFirstJob: Date(),
101+
diagnosticEngine: diagnosticEngine,
102+
compilationInputModificationDates: compilationInputModificationDates)
80103
}
81104

82105
private static func computeArgsHash(_ parsedOptionsArg: ParsedOptions
@@ -205,7 +228,7 @@ import SwiftOptions
205228
guard outOfDateBuildRecord.argsHash.map({ $0 == currentArgsHash }) ?? true else {
206229
let why = "different arguments were passed to the compiler"
207230
// mimic legacy
208-
reporter?.reportIncrementalCompilationHasBeenDisabled(" because " + why)
231+
reporter?.reportIncrementalCompilationHasBeenDisabled("because " + why)
209232
reporter?.reportDisablingIncrementalBuild(why)
210233
return nil
211234
}
@@ -217,6 +240,18 @@ import SwiftOptions
217240
finishedJobResults.append(JobResult(job, result))
218241
}
219242
}
243+
244+
/// A build-record-relative path to the location of a serialized copy of the
245+
/// driver's dependency graph.
246+
///
247+
/// FIXME: This is a little ridiculous. We could probably just replace the
248+
/// build record outright with a serialized format.
249+
var dependencyGraphPath: VirtualPath {
250+
let filename = buildRecordPath.basenameWithoutExt
251+
return buildRecordPath
252+
.parentDirectory
253+
.appending(component: filename + ".priors")
254+
}
220255
}
221256

222257
fileprivate extension AbsolutePath {

0 commit comments

Comments
 (0)