Skip to content

Commit 63d6636

Browse files
author
David Ungar
authored
Merge pull request #750 from davidungar/fix-multi-swiftmodule-read
[Incremental] Fix clean build quadratic performance bug
2 parents 09845a1 + e2ecf22 commit 63d6636

File tree

10 files changed

+322
-163
lines changed

10 files changed

+322
-163
lines changed

Sources/SwiftDriver/IncrementalCompilation/DependencyKey.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,15 @@ extension DependencyKey.Designator: Comparable {}
348348
// MARK: - InvalidationReason
349349
extension ExternalDependency {
350350
/// When explaining incremental decisions, it helps to know why a particular external dependency
351-
/// was investigated.
351+
/// caused invalidation.
352352
public enum InvalidationReason: String, CustomStringConvertible {
353353
/// An `import` of this file was added to the source code.
354354
case added
355355

356356
/// The imported file has changed.
357357
case changed
358358

359-
/// Used when testing invalidation
359+
/// Used when testing
360360
case testing
361361

362362
public var description: String { rawValue }

Sources/SwiftDriver/IncrementalCompilation/FirstWaveComputer.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,13 @@ extension IncrementalCompilationState.FirstWaveComputer {
131131
}
132132
}
133133

134-
let inputsHavingMalformedDependencySources =
135-
sourceFiles.currentInOrder.filter { sourceFile in
136-
!moduleDependencyGraph.containsNodes(forSourceFile: sourceFile)
137-
}
134+
let inputsMissingFromGraph = sourceFiles.currentInOrder.filter { sourceFile in
135+
!moduleDependencyGraph.containsNodes(forSourceFile: sourceFile)
136+
}
138137

139-
if let reporter = reporter {
140-
for input in inputsHavingMalformedDependencySources {
138+
if let reporter = reporter,
139+
moduleDependencyGraph.phase == .buildingFromSwiftDeps {
140+
for input in inputsMissingFromGraph {
141141
reporter.report("Has malformed dependency source; will queue", input)
142142
}
143143
}
@@ -156,7 +156,7 @@ extension IncrementalCompilationState.FirstWaveComputer {
156156
let definitelyRequiredInputs =
157157
Set(changedInputs.map({ $0.filePath }) +
158158
inputsInvalidatedByExternals +
159-
inputsHavingMalformedDependencySources +
159+
inputsMissingFromGraph +
160160
inputsMissingOutputs)
161161
if let reporter = reporter {
162162
for scheduledInput in sortByCommandLineOrder(definitelyRequiredInputs) {

Sources/SwiftDriver/IncrementalCompilation/IncrementalDependencyAndInputSetup.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
206206
return readPriorGraphAndCollectInputsInvalidatedByChangedOrAddedExternals()
207207
}
208208
// Every external is added, but don't want to compile an unchanged input that has an import
209-
// so just changed, not changedOrAdded
209+
// so just changed, not changedOrAdded.
210210
return buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals()
211211
}
212212

@@ -230,7 +230,13 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
230230
}
231231
guard let graph = graphIfPresent
232232
else {
233-
return buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals()
233+
// Do not fall back to `buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals`
234+
// because it would be unsound to read a `swiftmodule` file with only a partial set of integrated `swiftdeps`.
235+
// A fingerprint change in such a `swiftmodule` would not be able to propagate and invalidate a use
236+
// in a as-yet-unread swiftdeps file.
237+
//
238+
// Instead, just compile everything. It's OK to be unsound then because every file will be compiled anyway.
239+
return bulidEmptyGraphAndCompileEverything()
234240
}
235241
graph.dotFileWriter?.write(graph)
236242

@@ -257,10 +263,7 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
257263
private func buildInitialGraphFromSwiftDepsAndCollectInputsInvalidatedByChangedExternals()
258264
-> (ModuleDependencyGraph, TransitivelyInvalidatedInputSet)?
259265
{
260-
guard let graph = ModuleDependencyGraph(self, .buildingWithoutAPrior)
261-
else {
262-
return nil
263-
}
266+
let graph = ModuleDependencyGraph(self, .buildingFromSwiftDeps)
264267
var inputsInvalidatedByChangedExternals = TransitivelyInvalidatedInputSet()
265268
for input in sourceFiles.currentInOrder {
266269
guard let invalidatedInputs =
@@ -273,4 +276,10 @@ extension IncrementalCompilationState.IncrementalDependencyAndInputSetup {
273276
reporter?.report("Created dependency graph from swiftdeps files")
274277
return (graph, inputsInvalidatedByChangedExternals)
275278
}
279+
280+
private func bulidEmptyGraphAndCompileEverything()
281+
-> (ModuleDependencyGraph, TransitivelyInvalidatedInputSet) {
282+
let graph = ModuleDependencyGraph(self, .buildingAfterEachCompilation)
283+
return (graph, TransitivelyInvalidatedInputSet())
284+
}
276285
}

0 commit comments

Comments
 (0)