-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Optimize dep-graph serialization and improve meta-data hashing #35406
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
The way we do HIR inlining introduces reads of the "Hir" into the graph, but this Hir in fact belongs to other crates, so when we try to load later, we ICE because the Hir nodes in question don't belond to the crate (and we haven't done inlining yet). This pass rewrites those HIR nodes to the metadata from which the inlined HIR was loaded.
The biggest problem, actually, is krate numbers being removed entirely, which can lead to array-index-out-of-bounds errors. cc rust-lang#35123 -- not a complete fix, since really we ought to "map" the old crate numbers to the new ones, not just detect changes.
The reads will occur naturally as the HIR/MIR is fetched from the tracked tables, and this winds up adding reads to the hir of foreign def-ids somehow.
When we hash the inputs to a MetaData node, we have to hash them in a consistent order. We achieve this by sorting the stringfied `DefPath` entries. Also, micro-optimie by cache more results across the saving process.
It's nice to get a rough idea of how much work we're saving.
We now detect inlined id's earlier (in the HIR map) and rewrite a read of them to be a read of the metadata for the associated item.
I cannot figure out how to write a test for this, but I observed incorrect edges as a result of not using memoized pattern here (e.g., LateLintCheck -> SizedConstraint).
this can actually be expensive!
|
@@ -39,6 +39,14 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { | |||
} | |||
} | |||
|
|||
pub fn is_hashable(dep_node: &DepNode<DefId>) -> bool { |
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'd prefer if this was called is_input_node
or is_graph_root
to make it clearer what we are after.
Ok, I've reviewed everything after |
Per the discussion on rust-lang#34765, we make one `DepNode::Mir` variant and use it to represent both the MIR tracking map as well as passes that operate on MIR. We also track loads of cached MIR (which naturally comes from metadata). Note that the "HAIR" pass adds a read of TypeckItemBody because it uses a myriad of tables that are not individually tracked.
it now carries a def-id; supply a dummy
The new `Predecessors` type computes a set of interesting targets and their HIR predecessors, and discards everything in between.
Produces a deterministic hash, at least for a single platform / compiler-version.
This massively speeds up serialization. It also seems to produce deterministic metadata hashes (before I was seeing inconsistent results). Fixes rust-lang#35232.
@michaelwoerister OK, I addressed your nits. I will rebase atop of #35166, I think, and maybe try to land them together once you've revised the additional commits in there. |
698619a
to
ecbcf1b
Compare
// encoding, rather than having been retraced to a `DefId`. The | ||
// reason for this is that this way we can include nodes that have | ||
// been removed (which no longer have a `DefId` in the current | ||
// compilation). |
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.
👍
LGTM. |
This makes a number of related changes:
HIR -> WorkProduct
edges-Z incremental-info
, which tells you how much re-use you are getting, and tells you why you are not getting re-useThe end result is that, at least in my tests, we are now able to get 100% re-use when doing
cargo clean; cargo build
twice in a row (with an incremental directory, of course). Here are some rough performance numbers from thesyntex-syntax
crate:Note that these numbers only reflect the first phase of incremental, where we are just skipping the trans/LLVM phases. They will get better as we incrementalize more of the compiler. Also, these numbers represent the simplest case, where no actual changes were made. There is still more work to do to handle the case some small number of changes were made correctly (in particular, verifying that the dep-graph is complete etc).
r? @michaelwoerister
Fixes #35167.