-
Notifications
You must be signed in to change notification settings - Fork 13k
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
[MIR] Cache drops for early scope exits #34307
Conversation
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
cc @eddyb (the patch you wanted to see) |
/// each of those has their own cached-blocks, which will branch | ||
/// to this point. | ||
cached_block: Option<BasicBlock> | ||
/// The cache for drop chain on “normal” exit into a particular BasicBlock. |
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.
Are the fancy quotes intentional 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.
Yes. These are preferred characters for quotation characters in english prose.
Previously we would rebuild all drops on every early exit from a scope, which for code like: ```rust match x { a => return 1, b => return 2, ... z => return 27 } ``` would produce 27 exactly same chains of drops for each return, a O(n*m) explosion in drops.
@bors r+ |
📌 Commit 04d63cc has been approved by |
[MIR] Cache drops for early scope exits Previously we would rebuild all drops on every early exit from a scope, which for code like: ```rust match x { A => return 1, B => return 2, ... C => return 27 } ``` would produce 27 exactly same chains of drops for each return, basically a `O(n*m)` explosion. [This](https://cloud.githubusercontent.com/assets/679122/16125192/3355e32c-33fb-11e6-8564-c37cab2477a0.png) is such a case for a match on 80-variant enum with 3 droppable variables in scope. For [`::core::iter::Iterator::partial_cmp`](https://github.com/rust-lang/rust/blob/6edea2cfda2818f0a76f4bac2d18a30feb54c137/src/libcore/iter/iterator.rs#L1909) the CFG looked like [this](https://cloud.githubusercontent.com/assets/679122/16122708/ce0024d8-33f0-11e6-93c2-e1c44b910db2.png) (after initial SimplifyCfg). With this patch the CFG looks like [this](https://cloud.githubusercontent.com/assets/679122/16122806/294fb16e-33f1-11e6-95f6-16c5438231af.png) instead. Some numbers (overall very small wins, however neither of the crates have many cases which abuse this corner case): | | old time | old rss | new time | new rss | |-------------------------|----------|---------|----------|----------| | core dump | 0.879 | 224MB | 0.871 | 223MB | | core MIR passes | 0.759 | 224MB | 0.718 | 223MB | | core MIR codegen passes | 1.762 | 230MB | 1.442 | 228MB | | core trans | 3.263 | 279MB | 3.116 | 278MB | | core llvm passes | 5.611 | 263MB | 5.565 | 263MB | | std dump | 0.487 | 190MB | 0.475 | 192MB | | std MIR passes | 0.311 | 190MB | 0.288 | 192MB | | std MIR codegen passes | 0.753 | 195MB | 0.720 | 197MB | | std trans | 2.589 | 287MB | 2.523 | 287MB | | std llvm passes | 7.268 | 245MB | 7.447 | 246MB |
Fix the invalidation of the MIR early exit cache ~~The rust-lang#34307 introduced a cache for early exits in order to help with O(n*m) explosion of cleanup blocks but the cache is invalidated incorrectly and I can’t seem to figure out why (caching is hard!)~~ ~~Remove the cache for now to fix the immediate correctness issue and worry about the performance later.~~ Cache invalidation got fixed. Fixes rust-lang#35737 r? @nikomatsakis
Previously we would rebuild all drops on every early exit from a scope, which for code like:
would produce 27 exactly same chains of drops for each return, basically a
O(n*m)
explosion. This is such a case for a match on 80-variant enum with 3 droppable variables in scope.For
::core::iter::Iterator::partial_cmp
the CFG looked like this (after initial SimplifyCfg). With this patch the CFG looks like this instead.Some numbers (overall very small wins, however neither of the crates have many cases which abuse this corner case):