-
Notifications
You must be signed in to change notification settings - Fork 7
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
StorageLive/StorageDead not always emmitted in Debug mode in lastest upsteam. #301
Comments
Maybe you could use the |
Can you expand on this? Does this pass not compute the position of the Lives and Deads (so we wouldn't expect any Deads beforehand, would we?) |
If there are no |
Do you mean, that when MIR doesn't emit |
I'd like to ask a more fundamental question: what does Its docstring:
I had first assumed that takes a MIR without any live/dead annotations and adds them. That would indeed be useful to us. But looking at it's implementation, it looks like it tries to remove local variables that may or may not already have live ranges annotated with If I'm right above, I'm not sure of the utility of it in helping us to add live ranges. Have I missed something? |
No, until the end of the function.
One of the uses of that dataflow pass is to determine which variables are live across yield points in a generator and thus need to be stored in the generator state.
Yeah, it doesn't help with determining when variables become dead, but it does help a bit determining when variables become live. |
Right, then I don't really see an issue with generating deads at the end of a function. Or can you think of an example where doing that would make things go wrong? |
There is no functional issue with that, but I believe it will have a performance issue with the current regalloc of Yorick. |
Agreed, because a local which lives longer than it needs to unnecessarily deprives the system of one register, potentially causing spills. Another option (which I haven't looked at yet): we could disable the code in rustc that eliminates the storagelive/deads. |
There are two kinds of locals important here. Those who have their address take. Those need to be on the stack anyway and losing the ability to not collapse stack slots when the live range doesn't overlap in debug mode isn't a huge deal. Cranelift doesn't either. And locals who don't have their address taken. For those it is possible to get live ranges as precise as when using |
Of course, but I think @vext01 and I had already agreed that as a temporary solution we can live with that. Our register allocator is pretty dumb anyway at the moment. But if @vext01 wants to have another go at dataflow analysis I won't stand in the way (on the contrary I will probably be standing very, very far away 😉 ). |
It's actually not that hard and there are lots of existing algorithms. The mistake we made last time was that we did it on the TIR trace. I suggest we do it in two phases:
I don't mind doing this work either. It's been a while since I got my teeth into something non-build-system-or-ci-related. |
Closing, as this is for the old yk design. |
Latest rustc upstream (rust-lang/rust#78360) added a change that avoids creating
StorageLive
/StorageDead
instructions if they are not required for codegen. Our previous assumption was that all locals (except arguments which live for the entirety of the function) haveStorageLive
andStorageDead
instructions. This breaks our computation of live locals which are needed for stopgap interpreter initialisation.For example, for the following function
previously,
bb0
looked like this:In latest upstream, it looks like this:
Since at this time we don't want to write our own liveness analysis (we all know how this turned out last time), a quick and dumb solution for this is to emit
StorageLive
for all locals at the beginning of a function, andStorageDead
at the end of it (unless a local already has those). Ideally, this would be done during SIR lowering so there won't be a runtime cost.The text was updated successfully, but these errors were encountered: