Skip to content
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

compute and cache HIR hashes at beginning #35854

Merged
merged 9 commits into from
Aug 23, 2016

Conversation

nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented Aug 20, 2016

This avoids the compile-time overhead of computing them twice. It also fixes
an issue where the hash computed after typeck is differen than the hash before,
because typeck mutates the def-map in place.

Fixes #35549.
Fixes #35593.

Some performance measurements suggest this HashesMap is very small in memory (unobservable via -Z time-passes) and very cheap to construct. I do see some (very minor) performance wins in the incremental case after the first run -- the first run costs more because loading the dep-graph didn't have any hashing to do in that case. Example timings from two runs of libsyntex-syntax -- the (1) indicates first run, (2) indicates second run, and (*) indicates both together:

Phase Master Branch
compute_hashes_map (1) N/A 0.343
load_dep_graph (1) 0 0
serialize dep graph (1) 4.190 3.920
total (1) 4.190 4.260
compute_hashes_map (2) N/A 0.344
load_dep_graph (2) 0.592 0.252
serialize dep graph (2) 4.119 3.779
total (2) 4.71 4.375
total (*) 8.9 8.635

r? @michaelwoerister

This avoids the compile-time overhead of computing them twice.  It also fixes
an issue where the hash computed after typeck is differen than the hash before,
because typeck mutates the def-map in place.

Fixes rust-lang#35549.
Fixes rust-lang#35593.
@nikomatsakis
Copy link
Contributor Author

(Hmm I may have forgotten the test.)

Experimentally, this fixes the poor re-use observed in
libsyntex-syntax. I'm not sure how to make a regression test for this,
though, given the non-deterministic nature of it.

time(time_passes,
"assert dep graph",
move || rustc_incremental::assert_dep_graph(tcx));

time(time_passes,
"serialize dep graph",
move || rustc_incremental::save_dep_graph(tcx));
move || rustc_incremental::save_dep_graph(tcx, &hashes_map));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer a less generic name than hashes_map here and above. incr_comp_hashes or ic_hashes_map or ich_map, something that makes it visible that this has to do with incr. comp.

@michaelwoerister
Copy link
Member

I'd be good to include the test case from #35593 (or something more targeted at the underlying issue).

@nikomatsakis
Copy link
Contributor Author

I'd be good to include the test case from #35593 (or something more targeted at the underlying issue).

Yeah, that's easy enough. I should probably try to make a standalone test for the trait-cache issue too.

})
.collect();
candidates.sort();
candidates.hash(self.st);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a fine way to make it deterministic. One of the million cases though where I wish we had SmallVec available in the compiler :)

@nikomatsakis
Copy link
Contributor Author

One of the million cases though where I wish we had SmallVec available in the compiler

Maybe. A fast allocator though isn't that different.

This seems like approx a 2x win on syntex_syntax.
This seems not only more correct but allows us to write tests that check
whether the krate hash as a whole is clean/dirty
// except according to those terms.

// Test incremental compilation tracking where we change field names
// in between revisions (hashing should be stable).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a leftover from another test.

@michaelwoerister
Copy link
Member

LGTM! (except for the rogue comment in the test case)
r=me with that fixed.

@nikomatsakis
Copy link
Contributor Author

@bors r=mw

@bors
Copy link
Contributor

bors commented Aug 23, 2016

📌 Commit 1cc7c90 has been approved by mw

@nikomatsakis
Copy link
Contributor Author

I added rust-lang-deprecated/rustc-benchmarks#7 to allow us to check that we are still getting reuse in syntex

@bors
Copy link
Contributor

bors commented Aug 23, 2016

⌛ Testing commit 1cc7c90 with merge 012f45e...

bors added a commit that referenced this pull request Aug 23, 2016
compute and cache HIR hashes at beginning

This avoids the compile-time overhead of computing them twice.  It also fixes
an issue where the hash computed after typeck is differen than the hash before,
because typeck mutates the def-map in place.

Fixes #35549.
Fixes #35593.

Some performance measurements suggest this `HashesMap` is very small in memory (unobservable via `-Z time-passes`) and very cheap to construct. I do see some (very minor) performance wins in the incremental case after the first run -- the first run costs more because loading the dep-graph didn't have any hashing to do in that case. Example timings from two runs  of `libsyntex-syntax` -- the (1) indicates first run, (2) indicates second run, and (*) indicates both together:

| Phase | Master | Branch |
| ---- | ---- | ---- |
| compute_hashes_map (1) | N/A | 0.343 |
| load_dep_graph (1) | 0 | 0 |
| serialize dep graph (1) | 4.190 | 3.920 |
| total (1) | 4.190 | 4.260 |
| compute_hashes_map (2) | N/A | 0.344 |
| load_dep_graph (2) | 0.592 | 0.252 |
| serialize dep graph (2) | 4.119 | 3.779 |
| total (2) | 4.71 | 4.375 |
| total (*) | 8.9 | 8.635 |

r? @michaelwoerister
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

println!() breaks incr. comp. incr. comp.: Don't compute HIR hash values twice
3 participants