-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[nll] fewer allocations in liveness, use dirty list #51819
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
In addition, while we are modifying liveness, we can probably adjust the main computation to be less naive: rust/src/librustc_mir/util/liveness.rs Lines 135 to 155 in 764232c
Here you can see we repeatedly iterate over all the basic blocks and propagate them. We should avoid propagating bits from basic blocks whose "out set" did not change in the previous iteration. |
@nikomatsakis: are you able to make these changes? |
@nnethercote I haven't been able to get to it yet; if you want to take a stab at it, please feel free! |
Ok, I've started looking at this. I see various possibilities, most of which don't overlap with the things you've identified above :)
I think I see why this code does it this way -- it has various uses of solo bitsets, and it makes the code simpler if the per-BB bitsets can have the same form. The
I don't understand this sentence... is there a typo, or does "take" have a meaning in this context that I'm not familiar with? I can also see how to avoid some more allocations in Also, in the common case |
OK, @nnethercote I left a few comments on those PRs. Good catch in both cases. (Indeed I may have been wrong about which allocations are most important! =) I still think it'd be good to make the other changes I described, in particular perhaps the dirty list (which isn't necessarily about allocations -- I hope we're not allocating per block in that inner loop!), so let's not close the bug until we're fully satisfied. |
@nnethercote I'm going to take a stab at introducing a dirty list into the propagation, unless you are doing so already. It seems orthogonal enough from your existing PRs. Would that step on your toes at all? |
In progress branch: https://github.com/nikomatsakis/rust/tree/nll-liveness-dirty-list |
Branch now contains (a) a dirty list and (b) it removes the |
Now that #51896 etc has landed I'm going to close this as we don't have immediately actionable stuff in here. |
@nnethercote reports that the liveness computations do a lot of allocations. Indeed, the liveness results are stored in a
Vec<IdxSetBuf>
:rust/src/librustc_mir/util/liveness.rs
Line 59 in 2808460
rust/src/librustc_mir/util/liveness.rs
Line 49 in 2808460
This means that we will allocate a separate bitset for the ins (and outs!) of each basic block. This is rather inefficient. The other
dataflow
implementations use a different setup. They have just one big index set which has the bits for every basic block in one allocation. They also avoid allocating both anins
andouts
-- since liveness is a reverse analysis, they would basically have only the singleouts
vector (what is live on exit).The
ins
vector is only used during generation of the liveness results here (as well as some assertions and debug printouts later on):rust/src/librustc_mir/util/liveness.rs
Lines 139 to 144 in 2808460
In fact, you don't really need it there -- instead, when you process a block X, you would compute take
outs[X]
, subtract the kills and add the defs, and then take that resulting bit set and propagate it to each predecessor ofX
.The text was updated successfully, but these errors were encountered: