[nll] remove duplicate outlives edges #51821
Labels
NLL-performant
Working towards the "performance is good" goal
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone
Solving region constraints currently accounts for 8% of MIR borrowck time in clap-rs. However, we are doing more work than we need to do. This part of the inference engine processes outlives constraints like
'a: 'b
, which says that the region'a
outlives'b
and therefore should be a superset of the points in'b
. To process such a constraint we therefore take all the points in'b
and add them to'a
:rust/src/librustc_mir/borrow_check/nll/region_infer/values.rs
Lines 246 to 250 in 2808460
You can see therefore that a constraint like
'a: 'a
is pretty uninteresting. It is also uninterested to have two of the same constraints ('b: 'c
,'b: 'c
), since processing the first one will also solve the second one.However, a cursory examination of the constraints from many examples reveals that we have both a lot of duplicates and a lot of
X: X
identity constraints. I find about ~30% of the constraints are duplicated.Part of the reason for this is that, in the original NLL proposal and in Polonius, we distinguished not only
'a: 'b
but also the location where it occurs ('a: 'b @ P
). We are no longer using thisP
information so it would be good to discard it (and the next gen region inference engine, polonius, uses a different data structures for its constraints anyway). (Interestingly, even if we take the locationP
into account, it is still true that most of the constraints are duplicated, so there is likely a win here waiting for polonius as well at some future point.)The constraints in question are instances of this struct:
rust/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Lines 120 to 146 in 2808460
They are stored in a vector here:
rust/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Lines 70 to 71 in 2808460
Most elements of this vector I believe are given in
RegionInferenceContext::new
:rust/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Line 272 in 2808460
but some are later added via
add_outlives
:rust/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Lines 390 to 407 in 2808460
The initial vector is populated by the MIR type check in this call here:
rust/src/librustc_mir/borrow_check/nll/type_check/mod.rs
Lines 759 to 768 in 7008a95
So to solve this problem we would want to detect duplicates somehow, probably taking just sub+sup into account. The only reason to also include the location is that it may be useful in reporting errors later. It probably makes sense to do this by adding a
FxHashSet<(RegionVid, RegionVid)>
to detect duplicates, though it might make sense to extract the vector itself from both theRegionInferenceContext
and the MIR type check into a common data structure (OutlivesConstraintSet
or something) that keeps theFxHashSet
and theVec
in one.The text was updated successfully, but these errors were encountered: