Skip to content

Commit 7ae7038

Browse files
author
David Ungar
authored
Merge pull request swiftlang#20823 from davidungar/master-with-comments
[Driver] NFC: Added some comments around incremental compilation.
2 parents b9a1ad2 + 6e31cf1 commit 7ae7038

File tree

4 files changed

+43
-8
lines changed

4 files changed

+43
-8
lines changed

include/swift/Driver/DependencyGraph.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class DependencyGraphImpl {
121121
llvm::StringMap<std::pair<std::vector<DependencyEntryTy>, DependencyMaskTy>> Dependencies;
122122

123123
/// The set of marked nodes.
124+
124125
llvm::SmallPtrSet<const void *, 16> Marked;
125126

126127
/// A list of all external dependencies that cannot be resolved from just this
@@ -153,6 +154,8 @@ class DependencyGraphImpl {
153154
(void)newlyInserted;
154155
}
155156

157+
/// See DependencyGraph::markTransitive.
158+
156159
void markTransitive(SmallVectorImpl<const void *> &visited,
157160
const void *node, MarkTracerImpl *tracer = nullptr);
158161
bool markIntransitive(const void *node) {
@@ -254,7 +257,7 @@ class DependencyGraph : public DependencyGraphImpl {
254257
/// Marks \p node and all nodes that depend on \p node, and places any nodes
255258
/// that get transitively marked into \p visited.
256259
///
257-
/// Nodes that have been previously marked are not included in \p newlyMarked,
260+
/// Nodes that have been previously marked are not included in \p visited,
258261
/// nor are their successors traversed, <em>even if their "provides" set has
259262
/// been updated since it was marked.</em> (However, nodes that depend on the
260263
/// given \p node are always traversed.)
@@ -264,6 +267,14 @@ class DependencyGraph : public DependencyGraphImpl {
264267
///
265268
/// If you want to see how each node gets added to \p visited, pass a local
266269
/// MarkTracer instance to \p tracer.
270+
///
271+
/// Conservatively assumes that there exists a "cascading" edge into the
272+
/// starting node. Therefore, mark the start. For each visited node, add it to
273+
/// \p visited, and mark it if some incoming edge cascades. The start node is
274+
/// NOT added to \p visited.
275+
///
276+
/// The traversal routines use
277+
/// \p visited to avoid endless recursion.
267278
template <unsigned N>
268279
void markTransitive(SmallVector<T, N> &visited, T node,
269280
MarkTracer *tracer = nullptr) {

include/swift/Driver/Job.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,17 @@ class CommandOutput {
230230
class Job {
231231
public:
232232
enum class Condition {
233+
// There was no information about the previous build (i.e., an input map),
234+
// or the map marked this Job as dirty or needing a cascading build.
235+
// Be maximally conservative with dependencies.
233236
Always,
237+
// The input changed, or this job was scheduled as non-cascading in the last
238+
// build but didn't get to run.
234239
RunWithoutCascading,
240+
// The best case: input didn't change, output exists.
241+
// Only run if it depends on some other thing that changed.
235242
CheckDependencies,
243+
// Run no matter what (but may or may not cascade).
236244
NewlyAdded
237245
};
238246

lib/Driver/Compilation.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,10 @@ namespace driver {
206206
/// Jobs that incremental-mode has decided it can skip.
207207
CommandSet DeferredCommands;
208208

209-
/// Jobs in the initial set with Condition::Always, or lacking existing
209+
/// Jobs in the initial set with Condition::Always, and having an existing
210210
/// .swiftdeps files.
211-
SmallVector<const Job *, 16> InitialOutOfDateCommands;
211+
/// Set by scheduleInitialJobs and used only by scheduleAdditionalJobs.
212+
SmallVector<const Job *, 16> InitialCascadingCommands;
212213

213214
/// Dependency graph for deciding which jobs are dirty (need running)
214215
/// or clean (can be skipped).
@@ -382,7 +383,7 @@ namespace driver {
382383
DeferredCommands.clear();
383384
}
384385

385-
/// Helper that attmepts to reload a job's .swiftdeps file after the job
386+
/// Helper that attempts to reload a job's .swiftdeps file after the job
386387
/// exits, and re-run transitive marking to ensure everything is properly
387388
/// invalidated by any new dependency edges introduced by it. If reloading
388389
/// fails, this can cause deferred jobs to be immediately scheduled.
@@ -406,6 +407,13 @@ namespace driver {
406407
// If we have a dependency file /and/ the frontend task exited normally,
407408
// we can be discerning about what downstream files to rebuild.
408409
if (ReturnCode == EXIT_SUCCESS || ReturnCode == EXIT_FAILURE) {
410+
// "Marked" means that everything provided by this node (i.e. Job) is
411+
// dirty. Thus any file using any of these provides must be
412+
// recompiled. (Only non-private entities are output as provides.) In
413+
// other words, this Job "cascades"; the need to recompile it causes
414+
// other recompilations. It is possible that the current code marks
415+
// things that do not need to be marked. Unecessary compilation would
416+
// result if that were the case.
409417
bool wasCascading = DepGraph.isMarked(FinishedCmd);
410418

411419
switch (DepGraph.loadFromPath(FinishedCmd, DependenciesFile)) {
@@ -715,7 +723,15 @@ namespace driver {
715723
switch (Condition) {
716724
case Job::Condition::Always:
717725
if (Comp.getIncrementalBuildEnabled() && !DependenciesFile.empty()) {
718-
InitialOutOfDateCommands.push_back(Cmd);
726+
// Ensure dependents will get recompiled.
727+
InitialCascadingCommands.push_back(Cmd);
728+
// Mark this job as cascading.
729+
//
730+
// It would probably be safe and simpler to markTransitive on the
731+
// start nodes in the "Always" condition from the start instead of
732+
// using markIntransitive and having later functions call
733+
// markTransitive. That way markIntransitive would be an
734+
// implementation detail of DependencyGraph.
719735
DepGraph.markIntransitive(Cmd);
720736
}
721737
LLVM_FALLTHROUGH;
@@ -740,7 +756,7 @@ namespace driver {
740756
// We scheduled all of the files that have actually changed. Now add the
741757
// files that haven't changed, so that they'll get built in parallel if
742758
// possible and after the first set of files if it's not.
743-
for (auto *Cmd : InitialOutOfDateCommands) {
759+
for (auto *Cmd : InitialCascadingCommands) {
744760
DepGraph.markTransitive(AdditionalOutOfDateCommands, Cmd,
745761
IncrementalTracer);
746762
}

lib/Driver/CompilationRecord.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ namespace swift {
1919
namespace driver {
2020
namespace compilation_record {
2121

22-
/// Compilation record files (.swiftdeps files) are YAML files composed of these
23-
/// top-level keys.
22+
/// Compilation record files (-master.swiftdeps files) are YAML files composed
23+
/// of these top-level keys.
2424
enum class TopLevelKey {
2525
/// The key for the Swift compiler version used to produce the compilation
2626
/// record.

0 commit comments

Comments
 (0)