Skip to content

Commit 51233ed

Browse files
author
David Ungar
authored
Merge pull request #800 from davidungar/intern-experiment
[Incremental] Optimize incremental build logic by interning strings
2 parents c6fdb9c + d2c805d commit 51233ed

31 files changed

+1291
-761
lines changed

Sources/SwiftDriver/CMakeLists.txt

+9-7
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,32 @@ add_library(SwiftDriver
3232
Execution/ParsableOutput.swift
3333
Execution/ProcessProtocol.swift
3434

35-
"IncrementalCompilation/ModuleDependencyGraphParts/Integrator.swift"
36-
"IncrementalCompilation/ModuleDependencyGraphParts/Node.swift"
37-
"IncrementalCompilation/ModuleDependencyGraphParts/NodeFinder.swift"
38-
"IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift"
39-
"IncrementalCompilation/ModuleDependencyGraphParts/Tracer.swift"
4035
"IncrementalCompilation/BuildRecord.swift"
4136
"IncrementalCompilation/BuildRecordInfo.swift"
4237
"IncrementalCompilation/DependencyGraphDotFileWriter.swift"
4338
"IncrementalCompilation/DependencyKey.swift"
44-
"IncrementalCompilation/TwoLevelMap.swift"
4539
"IncrementalCompilation/DirectAndTransitiveCollections.swift"
4640
"IncrementalCompilation/ExternalDependencyAndFingerprintEnforcer.swift"
41+
"IncrementalCompilation/FirstWaveComputer.swift"
42+
"IncrementalCompilation/IncrementalCompilationSynchronizer.swift"
4743
"IncrementalCompilation/IncrementalCompilationState.swift"
4844
"IncrementalCompilation/IncrementalCompilationState+Extensions.swift"
4945
"IncrementalCompilation/IncrementalCompilationProtectedState.swift"
5046
"IncrementalCompilation/IncrementalDependencyAndInputSetup.swift"
51-
"IncrementalCompilation/FirstWaveComputer.swift"
5247
"IncrementalCompilation/InputInfo.swift"
5348
"IncrementalCompilation/KeyAndFingerprintHolder.swift"
5449
"IncrementalCompilation/ModuleDependencyGraph.swift"
50+
"IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift"
51+
"IncrementalCompilation/ModuleDependencyGraphParts/Integrator.swift"
52+
"IncrementalCompilation/ModuleDependencyGraphParts/InternedStrings.swift"
53+
"IncrementalCompilation/ModuleDependencyGraphParts/Node.swift"
54+
"IncrementalCompilation/ModuleDependencyGraphParts/NodeFinder.swift"
55+
"IncrementalCompilation/ModuleDependencyGraphParts/Tracer.swift"
5556
"IncrementalCompilation/Multidictionary.swift"
5657
"IncrementalCompilation/SwiftSourceFile.swift"
5758
"IncrementalCompilation/SourceFileDependencyGraph.swift"
5859
"IncrementalCompilation/TwoDMap.swift"
60+
"IncrementalCompilation/TwoLevelMap.swift"
5961

6062
Jobs/APIDigesterJobs.swift
6163
Jobs/AutolinkExtractJob.swift

Sources/SwiftDriver/Driver/Driver.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ extension Driver {
12491249
}
12501250
buildRecordInfo?.writeBuildRecord(
12511251
jobs,
1252-
incrementalCompilationState?.blockingConcurrentMutation{$0.skippedCompilationInputs})
1252+
incrementalCompilationState?.blockingConcurrentMutationToProtectedState{$0.skippedCompilationInputs})
12531253
}
12541254

12551255
private func printBindings(_ job: Job) {

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public extension Driver {
4141

4242
/// Generate a full command-line invocation to be used for the dependency scanning action
4343
/// on the target module.
44-
mutating func dependencyScannerInvocationCommand() throws -> ([TypedVirtualPath],[Job.ArgTemplate]) {
44+
@_spi(Testing) mutating func dependencyScannerInvocationCommand()
45+
throws -> ([TypedVirtualPath],[Job.ArgTemplate]) {
4546
// Aggregate the fast dependency scanner arguments
4647
var inputs: [TypedVirtualPath] = []
4748
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }

Sources/SwiftDriver/IncrementalCompilation/DependencyGraphDotFileWriter.swift

+36-25
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,36 @@ public struct DependencyGraphDotFileWriter {
2222
self.info = info
2323
}
2424

25-
mutating func write(_ sfdg: SourceFileDependencyGraph, for file: TypedVirtualPath) {
25+
mutating func write(_ sfdg: SourceFileDependencyGraph, for file: TypedVirtualPath,
26+
internedStringTable: InternedStringTable) {
2627
let basename = file.file.basename
27-
write(sfdg, basename: basename)
28+
write(sfdg, basename: basename, internedStringTable: internedStringTable)
2829
}
2930

3031
mutating func write(_ mdg: ModuleDependencyGraph) {
31-
write(mdg, basename: Self.moduleDependencyGraphBasename)
32+
write(mdg, basename: Self.moduleDependencyGraphBasename,
33+
internedStringTable: mdg.internedStringTable)
3234
}
3335

3436
@_spi(Testing) public static let moduleDependencyGraphBasename = "moduleDependencyGraph"
3537
}
3638

3739
// MARK: Asking to write dot files / implementation
3840
fileprivate extension DependencyGraphDotFileWriter {
39-
mutating func write<Graph: ExportableGraph>(_ graph: Graph, basename: String) {
41+
mutating func write<Graph: ExportableGraph>(
42+
_ graph: Graph,
43+
basename: String,
44+
internedStringTable: InternedStringTable
45+
) {
4046
let path = dotFilePath(for: basename)
4147
try! info.fileSystem.writeFileContents(path) { stream in
4248
var s = DOTDependencyGraphSerializer<Graph>(
4349
graph,
4450
graphID: basename,
4551
stream,
4652
includeExternals: info.dependencyDotFilesIncludeExternals,
47-
includeAPINotes: info.dependencyDotFilesIncludeAPINotes)
53+
includeAPINotes: info.dependencyDotFilesIncludeAPINotes,
54+
internedStringTable: internedStringTable)
4855
s.emit()
4956
}
5057
}
@@ -103,7 +110,7 @@ extension ModuleDependencyGraph: ExportableGraph {
103110
fileprivate protocol ExportableNode: Hashable {
104111
var key: DependencyKey {get}
105112
var isProvides: Bool {get}
106-
var label: String {get}
113+
func label(in: InternedStringTable) -> String
107114
}
108115

109116
extension SourceFileDependencyGraph.Node: ExportableNode {
@@ -116,19 +123,19 @@ extension ModuleDependencyGraph.Node: ExportableNode {
116123
}
117124

118125
extension ExportableNode {
119-
fileprivate func emit(id: Int, to out: inout WritableByteStream) {
120-
out <<< DotFileNode(id: id, node: self).description <<< "\n"
126+
fileprivate func emit(id: Int, to out: inout WritableByteStream, _ t: InternedStringTable) {
127+
out <<< DotFileNode(id: id, node: self, in: t).description <<< "\n"
121128
}
122129

123-
fileprivate var label: String {
124-
"\(key.description) \(isProvides ? "here" : "somewhere else")"
130+
fileprivate func label(in t: InternedStringTable) -> String {
131+
"\(key.description(in: t)) \(isProvides ? "here" : "somewhere else")"
125132
}
126133

127134
fileprivate var isExternal: Bool {
128135
key.designator.externalDependency != nil
129136
}
130137
fileprivate var isAPINotes: Bool {
131-
key.designator.externalDependency?.fileName.hasSuffix(".apinotes")
138+
key.designator.externalDependency?.fileNameString.hasSuffix(".apinotes")
132139
?? false
133140
}
134141

@@ -164,24 +171,26 @@ fileprivate extension DependencyKey.Designator {
164171
}
165172
}
166173

167-
static let oneOfEachKind: [DependencyKey.Designator] = [
168-
.topLevel(name: ""),
169-
.dynamicLookup(name: ""),
170-
.externalDepend(ExternalDependency(fileName: ".")),
171-
.sourceFileProvide(name: ""),
172-
.nominal(context: ""),
173-
.potentialMember(context: ""),
174-
.member(context: "", name: "")
175-
]
174+
static var oneOfEachKind: [DependencyKey.Designator] {
175+
[
176+
.topLevel(name: .empty),
177+
.dynamicLookup(name: .empty),
178+
.externalDepend(.dummy),
179+
.sourceFileProvide(name: .empty),
180+
.nominal(context: .empty),
181+
.potentialMember(context: .empty),
182+
.member(context: .empty, name: .empty)
183+
]}
176184
}
177185

178186
// MARK: - writing one dot file
179187

180-
fileprivate struct DOTDependencyGraphSerializer<Graph: ExportableGraph> {
188+
fileprivate struct DOTDependencyGraphSerializer<Graph: ExportableGraph>: InternedStringTableHolder {
181189
private let includeExternals: Bool
182190
private let includeAPINotes: Bool
183191
private let graphID: String
184192
private let graph: Graph
193+
fileprivate let internedStringTable: InternedStringTable
185194
private var nodeIDs = [Graph.Node: Int]()
186195
private var out: WritableByteStream
187196

@@ -190,9 +199,11 @@ fileprivate struct DOTDependencyGraphSerializer<Graph: ExportableGraph> {
190199
graphID: String,
191200
_ stream: WritableByteStream,
192201
includeExternals: Bool,
193-
includeAPINotes: Bool
202+
includeAPINotes: Bool,
203+
internedStringTable: InternedStringTable
194204
) {
195205
self.graph = graph
206+
self.internedStringTable = internedStringTable
196207
self.graphID = graphID
197208
self.out = stream
198209
self.includeExternals = includeExternals
@@ -218,7 +229,7 @@ fileprivate struct DOTDependencyGraphSerializer<Graph: ExportableGraph> {
218229
private mutating func emitNodes() {
219230
graph.forEachExportableNode { (n: Graph.Node) in
220231
if include(n) {
221-
n.emit(id: register(n), to: &out)
232+
n.emit(id: register(n), to: &out, internedStringTable)
222233
}
223234
}
224235
}
@@ -265,9 +276,9 @@ fileprivate struct DotFileNode: CustomStringConvertible {
265276
let fillColor: Color
266277
let style: Style?
267278

268-
init<Node: ExportableNode>(id: Int, node: Node) {
279+
init<Node: ExportableNode>(id: Int, node: Node, in t: InternedStringTable) {
269280
self.id = String(id)
270-
self.label = node.label
281+
self.label = node.label(in: t)
271282
self.shape = node.shape
272283
self.fillColor = node.fillColor
273284
self.style = node.style

0 commit comments

Comments
 (0)