1
Fork 0

move out of scope precomputer code

this addresses review comments while:
- keeping the symmetry between the NLL and Polonius out of scope
  precomputers
- keeping the unstable `calculate_borrows_out_of_scope_at_location`
  function to avoid churn for consumers
This commit is contained in:
Rémy Rakic 2025-01-10 08:42:00 +00:00
parent 735013d281
commit 8ac045dd4c

View file

@ -187,19 +187,28 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
} }
impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> { impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { fn compute(
OutOfScopePrecomputer { body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &BorrowSet<'tcx>,
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
let mut prec = OutOfScopePrecomputer {
visited: DenseBitSet::new_empty(body.basic_blocks.len()), visited: DenseBitSet::new_empty(body.basic_blocks.len()),
visit_stack: vec![], visit_stack: vec![],
body, body,
regioncx, regioncx,
borrows_out_of_scope_at_location: FxIndexMap::default(), borrows_out_of_scope_at_location: FxIndexMap::default(),
};
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
let borrow_region = borrow_data.region;
let location = borrow_data.reserve_location;
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
} }
}
}
impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> { prec.borrows_out_of_scope_at_location
}
fn precompute_borrows_out_of_scope( fn precompute_borrows_out_of_scope(
&mut self, &mut self,
borrow_index: BorrowIndex, borrow_index: BorrowIndex,
@ -280,15 +289,7 @@ pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
regioncx: &RegionInferenceContext<'tcx>, regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
) -> FxIndexMap<Location, Vec<BorrowIndex>> { ) -> FxIndexMap<Location, Vec<BorrowIndex>> {
let mut prec = OutOfScopePrecomputer::new(body, regioncx); OutOfScopePrecomputer::compute(body, regioncx, borrow_set)
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
let borrow_region = borrow_data.region;
let location = borrow_data.reserve_location;
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
}
prec.borrows_out_of_scope_at_location
} }
struct PoloniusOutOfScopePrecomputer<'a, 'tcx> { struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
@ -300,19 +301,30 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
} }
impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> { impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { fn compute(
Self { body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &BorrowSet<'tcx>,
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
// The in-tree polonius analysis computes loans going out of scope using the
// set-of-loans model.
let mut prec = PoloniusOutOfScopePrecomputer {
visited: DenseBitSet::new_empty(body.basic_blocks.len()), visited: DenseBitSet::new_empty(body.basic_blocks.len()),
visit_stack: vec![], visit_stack: vec![],
body, body,
regioncx, regioncx,
loans_out_of_scope_at_location: FxIndexMap::default(), loans_out_of_scope_at_location: FxIndexMap::default(),
};
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
let issuing_region = loan_data.region;
let loan_issued_at = loan_data.reserve_location;
prec.precompute_loans_out_of_scope(loan_idx, issuing_region, loan_issued_at);
} }
}
}
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> { prec.loans_out_of_scope_at_location
}
/// Loans are in scope while they are live: whether they are contained within any live region. /// Loans are in scope while they are live: whether they are contained within any live region.
/// In the location-insensitive analysis, a loan will be contained in a region if the issuing /// In the location-insensitive analysis, a loan will be contained in a region if the issuing
/// region can reach it in the subset graph. So this is a reachability problem. /// region can reach it in the subset graph. So this is a reachability problem.
@ -464,21 +476,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set) calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set)
} else { } else {
// The in-tree polonius analysis computes loans going out of scope using the PoloniusOutOfScopePrecomputer::compute(body, regioncx, borrow_set)
// set-of-loans model.
let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx);
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
let issuing_region = loan_data.region;
let loan_issued_at = loan_data.reserve_location;
polonius_prec.precompute_loans_out_of_scope(
loan_idx,
issuing_region,
loan_issued_at,
);
}
polonius_prec.loans_out_of_scope_at_location
}; };
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location } Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
} }