-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Driver] NFC: Added some comments around incremental compilation. #20823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
include/swift/Driver/Job.h
Outdated
@@ -230,9 +230,17 @@ class CommandOutput { | |||
class Job { | |||
public: | |||
enum class Condition { | |||
// There was no input map, or the map makred this Job as dirty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: marked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this!
/// | ||
/// "Marked" does NOT mean that any successors in the graph have been | ||
/// processed. The traversal routines use "Visited" to avoid endless | ||
/// "recursion". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This last bit doesn't seem like it belongs here, since "Visited" isn't persistent state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworded and moved to markTransitive
.
/// Assume that the starting node is "cascading"; that all dependencies must | ||
/// be dirty if the start is dirty. Therefore, mark the start. For each | ||
/// visited node, add it to visited, and mark it if it cascades. The start | ||
/// node is NOT added to visited. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no comment here because there is a comment on the templated version. Can you keep them all together?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Moved this comment and added an attempt at a cross-reference.
include/swift/Driver/Job.h
Outdated
CheckDependencies, | ||
// Pessimal: run no matter what. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually not the worst case; a newly-added file doesn't necessarily cascade.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified, thanks.
include/swift/Driver/Job.h
Outdated
Always, | ||
// The input changed, or this job was private or [it was not dirty but | ||
// primary output was missing]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick to "non-cascading" as the terminology, but even then it's something more like "this job was scheduled as non-cascading in the last build but didn't get to run".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the term "private". I didn't want to remove the lower-level predicate, so I added your sentence to the comment.
include/swift/Driver/Job.h
Outdated
@@ -230,9 +230,17 @@ class CommandOutput { | |||
class Job { | |||
public: | |||
enum class Condition { | |||
// There was no input map, or the map makred this Job as dirty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's obvious what "input map" means here. Maybe something like "we have no information about any previous build"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Fixed it to say both.
@@ -206,8 +206,9 @@ namespace driver { | |||
/// Jobs that incremental-mode has decided it can skip. | |||
CommandSet DeferredCommands; | |||
|
|||
/// Jobs in the initial set with Condition::Always, or lacking existing | |||
/// Jobs in the initial set with Condition::Always, and having an existing | |||
/// .swiftdeps files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change seems incorrect. NewlyAdded files would also show up here (at least they should).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, maybe not. Maybe the variable name just needs to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the code from Compilation.cpp
:
case Job::Condition::Always:
if (Comp.getIncrementalBuildEnabled() && !DependenciesFile.empty()) {
// Ensure dependents will get recompiled.
InitialOutOfDateCommands.push_back(Cmd);
// Mark this job as cascading.
DepGraph.markIntransitive(Cmd);
}
LLVM_FALLTHROUGH;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look at the code above and see if the code is wrong, or I'm reading it wrong, or what? Am I missing another place where jobs get added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, didn't see your second thought, messages crossed in progress. Happy to change the name if you like. Let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, given that this is the only place this gets set, I suggest "InitialCascadingCommands" or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, will do!
lib/Driver/Compilation.cpp
Outdated
/// It would probably be safe and simpler to markTransitive on the start | ||
/// nodes in the "Always" condition from the start instead of using | ||
/// markIntransitive and having later functions call markTransitive. That | ||
/// way markInstransitive would be an implemenation detail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not belong in a doc comment because it's not relevant to callers. Maybe it belongs next to markIntransitive instead?
(Also typo: "implemenation".)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Done.
@jrose-apple Thank you for take the time to look at these comments. So helpful to get a review! |
@@ -121,6 +121,13 @@ class DependencyGraphImpl { | |||
llvm::StringMap<std::pair<std::vector<DependencyEntryTy>, DependencyMaskTy>> Dependencies; | |||
|
|||
/// The set of marked nodes. | |||
/// "Marked" means that everything provided by this node (i.e. Job) is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Can you put an extra newline in here? We're formatting our comments as Doxygen (even if we never actually run the generator) and so the first "paragraph" is taken as a short summary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
@@ -121,6 +121,13 @@ class DependencyGraphImpl { | |||
llvm::StringMap<std::pair<std::vector<DependencyEntryTy>, DependencyMaskTy>> Dependencies; | |||
|
|||
/// The set of marked nodes. | |||
/// "Marked" means that everything provided by this node (i.e. Job) is | |||
/// dirty. Thus any file using any of these provides must be recompiled. | |||
/// (Only non-private entities are output as provides.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This particular note doesn't really belong here. The dependency graph (and the driver in general) doesn't know about what in a file gives rise to links in the graph, and if the logic did output private entities as "provides", they'd be marked differently somehow anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard to figure out where to put it, as there is no central declaration I found besides this one.
However, I've moved it into reloadAndRemarkDeps. If you have a better idea, please let me know!
/// (Only non-private entities are output as provides.) | ||
/// In other words, this Job "cascades"; the need to recompile it causes other | ||
/// recompilations. It is possible that the current code marks things that do | ||
/// not need to be marked. Nothing would break if that were the case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Nothing would break" seems a bit too generic; the effect of over-marking is unnecessary recompilation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
/// | ||
/// Do not confused "Marked" with "Visited". | ||
/// "Marked" does NOT influence the traversal. The traversal routines use | ||
/// "Visited" to avoid endless "recursion". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't correct; already-marked nodes do not end up in visited
, and it's not just to avoid endless recursion. I got that wrong.
(Also, another Doxygen note: parameters can be referred to inline with \p visited
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Fixed.
include/swift/Driver/Job.h
Outdated
@@ -230,9 +230,20 @@ class CommandOutput { | |||
class Job { | |||
public: | |||
enum class Condition { | |||
// There was no information about the previous build (i.e., an input map), | |||
// or the map marked this Job as dirty | |||
// but the input didn't change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't correct; the job being marked as "dirty + cascading" takes priority over whether or not the input changed. (At least, I hope it does.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Fixed!
include/swift/Driver/Job.h
Outdated
CheckDependencies, | ||
// Pessimal: Run no matter what (but may or may not cascade). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think "pessimal" is appropriate. As mentioned before, this is usually equivalent to RunWithoutCascading; it just means we don't compare against a previous swiftdeps file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
@@ -206,8 +206,9 @@ namespace driver { | |||
/// Jobs that incremental-mode has decided it can skip. | |||
CommandSet DeferredCommands; | |||
|
|||
/// Jobs in the initial set with Condition::Always, or lacking existing | |||
/// Jobs in the initial set with Condition::Always, and having an existing | |||
/// .swiftdeps files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, given that this is the only place this gets set, I suggest "InitialCascadingCommands" or something.
lib/Driver/Compilation.cpp
Outdated
// It would probably be safe and simpler to markTransitive on the | ||
// start nodes in the "Always" condition from the start instead of | ||
// using markIntransitive and having later functions call | ||
// markTransitive. That way markInstransitive would be an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "markInstransitive". Also, it's probably worth saying saying that it would be an implementation detail of DependencyGraph, since the comment is no longer in DependencyGraph.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Fixed.
@swift-ci please smoke test |
@jrose-apple @graydon I'd like to land this if it's OK with you. Any more suggestions? TIA. |
/// Assumes that the starting node is "cascading"; that all dependencies must | ||
/// be dirty if the start is dirty. Therefore, mark the start. For each | ||
/// visited node, add it to visited, and mark it if it cascades. The start | ||
/// node is NOT added to visited. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this graph model, nodes aren't cascading or not; edges are. (Also, please be consistent about use of \p visited
!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch on "visited!" I've fixed that.
include/swift/Driver/Job.h
Outdated
// build | ||
// but didn't get to run. | ||
// The scheduled-but-didn't-run condition is detected when the job was not | ||
// dirty but its primary output was missing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't the only such case, so I'm not sure why you're calling it out here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seemed to be worthwhile for the sake of clarity. I can delete it if you prefer. (Not exactly sure what the antecedent for "this" was in your comment.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I keep doing that. "the job is not dirty but the primary output is missing" is one case where RunWithoutCascading can happen, but it's not the only one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I get it and removed that sentence.
/// be dirty if the start is dirty. Therefore, mark the start. For each | ||
/// visited node, add it to visited, and mark it if it cascades. The start | ||
/// node is NOT added to visited. | ||
/// Assumes that some edge into the starting node is "cascading." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this better, but since no such edge has to actually exist maybe there's still another way to phrase it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I've reworded.
@jrose-apple @graydon Thanks for your comments. I'd like to land this. Anything else before I do? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yep! Looks good.
Thanks, @jrose-apple . I'll go ahead and test and land, but if @graydon has any more, I'll put it in in another PR. |
@swift-ci please smoke test |
Based on my own investigation, and conversations with Jordan, have added some comments. Zero changes to actual code. Pay particular attention to the comment for
InitialOutOfDateCommands
, where (if I read the code right) I had to reverse the sense of a comment. Either the code or the comment was wrong before.