-
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] Add Storage{Live,Dead} statements to emit llvm.lifetime.{start,end}. #35409
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
f86c06c
to
19955cf
Compare
if temp_lifetime.is_some() { | ||
this.cfg.push(block, Statement { | ||
source_info: source_info, | ||
kind: StatementKind::StorageLive(temp.clone()) |
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.
Make a helper function in cfg, since you’re constructing this multiple times manually.
This should become this.cfg.push_storage_live(source_info, temp);
Test please |
Assign(Lvalue<'tcx>, Rvalue<'tcx>), | ||
|
||
/// Start a live range for the storage of the local. | ||
StorageLive(Lvalue<'tcx>), |
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.
Hmm, should this be restricted to base lvalues or something like that? Meh, I guess it's ok to use Lvalue<'tcx>
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.
Local
would be great, but even then, it would not be applicable to ReturnPointer
or args.
Seems like a good use for @scottcarr's MIR testing framework. |
} | ||
} | ||
bcx | ||
} |
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.
Is there some way to refactor the arms? The only difference is End.call or Start.call, right?
EDIT: (I edited my original note which said "why not call lvalue_trans?" -- which we do not need)
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 need to do nothing if the local is not an Lvalue
.
Using a method taking lvalue
and the base::Lifetime
would work, yeah.
OK so @eddyb convinced me that most of my concerns were moot. r=me modulo the following:
|
19955cf
to
7def9f5
Compare
@bors r=nikomatsakis p=1 (if this gets into the nightly, it may fix a couple crates) |
📌 Commit 7def9f5 has been approved by |
⌛ Testing commit 7def9f5 with merge a5973b6... |
💔 Test failed - auto-linux-64-opt |
Failures are valgrind failures:
Could be real! |
@nikomatsakis I pinged @alexcrichton but I don't think he had time to look over them yet. |
@bors retry (hoping this is spurious) |
@bors p=0 |
☔ The latest upstream changes (presumably #35348) made this pull request unmergeable. Please resolve the merge conflicts. |
7def9f5
to
02aec40
Compare
@bors r=nikomatsakis |
📌 Commit 02aec40 has been approved by |
⌛ Testing commit 02aec40 with merge 4d03edd... |
💔 Test failed - auto-linux-64-opt |
I |
Argh #26764 strikes again, this time libstd's |
@bors r=nikomatsakis |
📌 Commit 1bb1444 has been approved by |
@bors p=2 |
[MIR] Add Storage{Live,Dead} statements to emit llvm.lifetime.{start,end}. Storage live ranges are tracked for all MIR variables and temporaries with a drop scope. `StorageLive` is lowered to `llvm.lifetime.start` and `StorageDead` to `llvm.lifetime.end`. There are some improvements possible here, such as: * pack multiple storage liveness statements by using the index of first local + `u64` bitset * enforce that locals are not directly accessed outside their storage live range * shrink storage live ranges for never-borrowed locals to initialization -> last use * emit storage liveness statements for *all* temporaries * however, the remaining ones are *always* SSA immediates, so they'd be noop in MIR trans * could have a flag on the temporary that its storage is irrelevant (a la C's old `register`) * would also deny borrows if necessary * this seems like an overcompliation and with packing & optimizations it may be pointless Even in the current state, it helps stage2 `rustc` compile `boiler` without overflowing (see #35408). A later addition fixes #26764 and closes #27372 by emitting `.section` directives for dylib metadata to avoid them being allocated into memory or read as `.note`. For this PR, those bugs were tripping valgrind.
I don't know about the rest, but thanks for the incidental |
Storage live ranges are tracked for all MIR variables and temporaries with a drop scope.
StorageLive
is lowered tollvm.lifetime.start
andStorageDead
tollvm.lifetime.end
.There are some improvements possible here, such as:
u64
bitsetregister
)Even in the current state, it helps stage2
rustc
compileboiler
without overflowing (see #35408).A later addition fixes #26764 and closes #27372 by emitting
.section
directives for dylib metadata to avoid them being allocated into memory or read as.note
. For this PR, those bugs were tripping valgrind.