-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Add Finalize statement to make deaggregation "reversible" by storing all information in MIR #96043
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
Some changes occured to rustc_codegen_cranelift cc @bjorn3 Some changes occured to the CTFE / Miri engine cc @rust-lang/miri |
(rust-highfive has picked a reviewer for you, use r? to override) |
r? rust-lang/wg-mir-opt |
hmm that didn't work r? @wesleywiser cc @rust-lang/wg-mir-opt |
StatementKind::Finalize(place) => { | ||
self.visit_place( | ||
place, | ||
PlaceContext::MutatingUse(MutatingUseContext::Store), |
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 MIR like this:
_1.0 = val;
Finalize(_1);
Won't MaybeLiveLocals
now report _1
as being dead before the finalize?
If the semantics of this were that it was just a read, we could have this be a NonMutatingUseContext::Inspect
or something like that.
Finalize(place) => { | ||
if M::enforce_validity(self) { | ||
let place = self.eval_place(**place)?; | ||
// Invariant: when `Finalize` is invoked on a place, that place is fully valid | ||
self.validate_operand(&self.place_to_op(&place)?)?; | ||
} | ||
} |
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.
Does this implement the semantics documented below? This does not look like it reports a mutation/store for the place
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 unreachable, I'm erasing all Finalize
before going into optimized_mir
, because it's not useful after that
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.
RemoveFinalize
looks like it's currently gated on mir_opt_level > 0
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, I remember why I added it. The const propagator runs on MIR that still has Finalize
statements
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.
Should Miri run this, or not?
enforce_validity
is anyway false for CTFE.
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 think that's just unsound? If you have a variable of type MaybeUninit
that is initialized but the value it is initialized to is unknown, then validation will be like "sure uninit is fine here" but actually the optimization of replacing it by uninit is wrong.
There is a big difference between "this memory is definitely uninit" and "we don't know the contents of this memory", and it sounds like const prop is conflating these two things?
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.
Yea, we knew this wasn't going to scale to some types. We'd need a different kind of marker for unknown data, but I also don't know if we can do that without complicating the interpreter. Maybe const prop should be its own thing... but it's also sad if we duplicate work.
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.
const prop does symbolic evaluation. It is not surprising that a concrete interpreter is not up for the task.
It might be possible to generalize parts of the interpreter to support symbolic and concrete evaluation, but we probably don't want that for the full thing. (const prop doesn't hit all parts of the interpreter anyway.)
Currently, what do we do to prevent soundness issues like the one I described?
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 avoid propagating most aggregates.
I think the right level of code sharing would be to call the various math operations manually and not reuse any of the functions that evaluate a mir statement or rvalue
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, I agree. Basically operator.rs
and cast.rs
.
Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL | ||
(_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL | ||
Retag((_13.0: &usize)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL | ||
(_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL | ||
Retag((_13.1: &usize)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL | ||
Finalize(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL |
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.
The fact that we now emit the additional retags is interesting. I think this is the behavior that we always should have had, but I'm not sure. cc @RalfJung
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.
jup, there are now some minor diagnostics changes in miri where we point to more precise locations
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.
Miri currently only retags bare references, not references inside aggregrates. This change here "surfaced" more bare references, hence there are more retags.
This comment has been minimized.
This comment has been minimized.
67ed1a1
to
f37e227
Compare
93ec58d
to
d316ab5
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit d316ab5b1fa8d310b9d6601f40bb9d2ee6b1d9c3 with merge 8d16576297d5544e5e8cccfe1ba734fccfe63dc9... |
☀️ Try build successful - checks-actions |
Queued 8d16576297d5544e5e8cccfe1ba734fccfe63dc9 with parent e7575f9, future comparison URL. |
Finished benchmarking commit (8d16576297d5544e5e8cccfe1ba734fccfe63dc9): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Footnotes |
41c3ae7
to
28274fe
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit 28274fe with merge 5c48387be095c501f8ff9b8c36f8487870f1acc3... |
☀️ Try build successful - checks-actions |
Queued 5c48387be095c501f8ff9b8c36f8487870f1acc3 with parent 756ffb8, future comparison URL. |
Finished benchmarking commit (5c48387be095c501f8ff9b8c36f8487870f1acc3): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Footnotes |
I don't think these performance regressions are avoidable. I'm abandoning this work |
cc @JakobDegen
cc @compiler-errors (Due to the additional information encodable for temporaries, once we stop emitting aggregates during mir building, this should improve diagnostics in borrowck, and especially around opaque types)
This PR can stand on its own, but I'm not sure its valuable on its own. I'm planning to continue moving the deaggregation pass earlier, until it runs right after mir building. Then I will remove it and make mir building generate deaggregated MIR