-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Don't actually create a full MIR stack frame when not needed #57351
Conversation
@bors try |
☀️ Test successful - status-travis |
Together with my (still WIP) fixes to the copy propagation pass, this makes enabling copy propagation pretty much free for the test case given in #36673 I don't feel comfortable to r+ as I have essentially no idea how const eval actually works. |
This is actually not a part of const eval, but of reading fields from evaluated constants which is used for pattern matching and const propagation cc @RalfJung do you want to take this? |
@rust-timer build 0ca2dc0 |
Success: Queued 0ca2dc0 with parent 2fba17f, comparison URL. |
Finished benchmarking try commit 0ca2dc0 |
Looks like a 1-2% perf improvement on a bunch of crates with only |
src/librustc_mir/const_eval.rs
Outdated
Vec::new(), // upvar_decls | ||
DUMMY_SP, // span | ||
Vec::new(), // control_flow_destroyed | ||
); |
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.
So this function is only ever called when we don't even want to execute any code? But then why even bother pushing a stack frame at all...? Basically I don't understand why this even works.
That entire mir
variable is "fake" and takes no input, right? This could be made clearer by having a separate function to construct it.
How does this relate to mk_borrowck_eval_cx
, which creates a "less fake" frame but also for some reason cannot use push_stack_frame
. Could this function also just directly push to the stack instead?
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.
So this function is only ever called when we don't even want to execute any code? But then why even bother pushing a stack frame at all...? Basically I don't understand why this even works.
We do call all kinds of methods on the ecx
that check the current stack frame for e.g. substs
and other info. These methods would fail without a stack frame. I remember talking about this before (not sure with whom), and we decided not to hack some sort of global substitutions into the ecx
.
How does this relate to mk_borrowck_eval_cx, which creates a "less fake" frame but also for some reason cannot use push_stack_frame. Could this function also just directly push to the stack instead?
Jup, I unified it, good idea. This works much better.
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.
We do call all kinds of methods on the ecx that check the current stack frame for e.g. substs and other info. These methods would fail without a stack frame.
I know.
But somewhere we also run some actual code, and then we need a real stack frame. I guess neither of these two mk*_eval_cx
functions is called then?
Could you please add doc comments to all of these mk*_eval_cx
functions explaining when they should be called, what the difference between them is, and what can and cannot be done with the context they return (e.g., you can project to fields of a constant etc., but you cannot actually run any code)?
r? @RalfJung
How is that even possible? Isn't this doing strictly less work? |
I suspect the 2% regression on tuple-stress is indeed spurious (we could try to confirm be re-running try and perf; but I don't personally think there's really any need to -- 2% is small anyway). |
@bors r+ |
📌 Commit dec79e4 has been approved by |
⌛ Testing commit dec79e4 with merge d5c50f5d9e85cfc8c603e6b80500f6a044d99e40... |
💔 Test failed - status-appveyor |
Log is empty. Probably spurious. @bors retry |
⌛ Testing commit dec79e4 with merge 431eb66b636a03a24ef2159211e378dd064f515a... |
💔 Test failed - checks-travis |
Eh, aha?
No idea. (And the "raw log" view makes it impossible to even tell the number of failed tests, or so.) |
Don't actually create a full MIR stack frame when not needed r? @dotdash This should significantly reduce overhead during const propagation and reduce overhead *after* copy propagation (cc rust-lang#36673)
Don't actually create a full MIR stack frame when not needed r? @dotdash This should significantly reduce overhead during const propagation and reduce overhead *after* copy propagation (cc rust-lang#36673)
Rollup of 16 pull requests Successful merges: - #57351 (Don't actually create a full MIR stack frame when not needed) - #57353 (Optimise floating point `is_finite` (2x) and `is_infinite` (1.6x).) - #57412 (Improve the wording) - #57436 (save-analysis: use a fallback when access levels couldn't be computed) - #57453 (lldb_batchmode.py: try `import _thread` for Python 3) - #57454 (Some cleanups for core::fmt) - #57461 (Change `String` to `&'static str` in `ParseResult::Failure`.) - #57473 (std: Render large exit codes as hex on Windows) - #57474 (save-analysis: Get path def from parent in case there's no def for the path itself.) - #57494 (Speed up item_bodies for large match statements involving regions) - #57496 (re-do docs for core::cmp) - #57508 (rustdoc: Allow inlining of reexported crates and crate items) - #57547 (Use `ptr::eq` where applicable) - #57557 (resolve: Mark extern crate items as used in more cases) - #57560 (hygiene: Do not treat `Self` ctor as a local variable) - #57564 (Update the const fn tracking issue to the new metabug) Failed merges: r? @ghost
r? @dotdash
This should significantly reduce overhead during const propagation and reduce overhead after copy propagation (cc #36673)