Skip to content

Commit 04d93a6

Browse files
committed
reuse reachability allocations between computing scopes
1 parent 60c6857 commit 04d93a6

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
1313
use rustc_mir_dataflow::{Analysis, Direction, Results};
1414
use std::fmt;
1515

16+
use crate::constraints::ConstraintSccIndex;
1617
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
1718

1819
/// A tuple with named fields that can hold either the results or the transient state of the
@@ -251,6 +252,8 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
251252
regioncx: &'a RegionInferenceContext<'tcx>,
252253
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
253254
placeholders: Vec<RegionVid>,
255+
reachability: BitSet<ConstraintSccIndex>,
256+
reachability_stack: Vec<ConstraintSccIndex>,
254257
}
255258

256259
impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
@@ -261,7 +264,7 @@ impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
261264
let placeholders = regioncx
262265
.regions()
263266
.filter(|&r| {
264-
use rustc_infer::infer::*;
267+
use rustc_infer::infer::{NllRegionVariableOrigin, RegionVariableOrigin};
265268
let origin = regioncx.var_infos[r].origin;
266269
let is_placeholder = matches!(
267270
origin,
@@ -278,6 +281,8 @@ impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
278281
regioncx,
279282
loans_out_of_scope_at_location: FxIndexMap::default(),
280283
placeholders,
284+
reachability: BitSet::new_empty(regioncx.constraint_sccs.num_sccs()),
285+
reachability_stack: vec![],
281286
}
282287
}
283288
}
@@ -300,21 +305,19 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
300305
let liveness = &self.regioncx.liveness_constraints;
301306
let sccs = &self.regioncx.constraint_sccs;
302307

303-
let mut reachability = BitSet::new_empty(sccs.num_sccs());
304-
305308
let issuing_region_scc = sccs.scc(issuing_region);
306-
let mut stack = vec![issuing_region_scc];
307-
reachability.insert(issuing_region_scc);
309+
self.reachability_stack.push(issuing_region_scc);
310+
self.reachability.insert(issuing_region_scc);
308311

309312
let member_constraints = &self.regioncx.member_constraints;
310313

311-
while let Some(scc) = stack.pop() {
314+
while let Some(scc) = self.reachability_stack.pop() {
312315
// Handle successors of this SCC:
313316
//
314317
// 1. Push outlives successors to the worklist stack
315318
for &succ_scc in sccs.successors(scc) {
316-
if reachability.insert(succ_scc) {
317-
stack.push(succ_scc);
319+
if self.reachability.insert(succ_scc) {
320+
self.reachability_stack.push(succ_scc);
318321
}
319322
}
320323

@@ -327,6 +330,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
327330
// That is to say, if there are member constraints here, the loan escapes the
328331
// function and cannot go out of scope. We can early return.
329332
if member_constraints.indices(scc).next().is_some() {
333+
self.reachability_stack.clear();
334+
self.reachability.clear();
330335
return;
331336
}
332337
}
@@ -375,7 +380,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
375380
// If a single live region is reachable from the issuing region, then the loan
376381
// is still live at this point. We can stop checking other live regions at this
377382
// location, and go to the next location.
378-
if reachability.contains(live_region_scc) {
383+
if self.reachability.contains(live_region_scc) {
379384
issuing_region_can_reach_live_regions = true;
380385
break;
381386
}
@@ -423,9 +428,10 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
423428
}
424429
}
425430

426-
assert!(self.visit_stack.is_empty(), "stack should be empty");
427-
428431
self.visited.clear();
432+
self.reachability.clear();
433+
assert!(self.visit_stack.is_empty(), "visit stack should be empty");
434+
assert!(self.reachability_stack.is_empty(), "reachablity stack should be empty");
429435
}
430436
}
431437

0 commit comments

Comments
 (0)