Skip to content

Commit 9fb6c16

Browse files
committed
make BorrowedLocalsResultsCursor compatible with #108293
1 parent 2208981 commit 9fb6c16

File tree

3 files changed

+59
-77
lines changed

3 files changed

+59
-77
lines changed

compiler/rustc_mir_dataflow/src/impls/live_borrows.rs

+38-51
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,9 @@
242242
243243
use super::*;
244244

245-
use crate::framework::{Analysis, Results, ResultsCursor};
245+
use crate::framework::{Analysis, Results, ResultsClonedCursor, ResultsCursor};
246246
use crate::impls::MaybeBorrowedLocals;
247-
use crate::{
248-
AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKillAnalysis, ResultsRefCursor,
249-
};
247+
use crate::{AnalysisDomain, Backward, CallReturnPlaces, CloneAnalysis, GenKill, GenKillAnalysis};
250248
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
251249
use rustc_data_structures::graph;
252250
use rustc_data_structures::graph::implementation::{Graph, NodeIndex};
@@ -257,7 +255,6 @@ use rustc_middle::mir::*;
257255
use rustc_middle::ty::TypeVisitable;
258256
use rustc_middle::ty::{self, Ty, TypeSuperVisitable};
259257

260-
use std::cell::RefCell;
261258
use std::ops::{ControlFlow, Deref, DerefMut};
262259

263260
// FIXME Properly determine a reasonable value
@@ -890,7 +887,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowDependencies<'a, 'tcx> {
890887
}
891888
}
892889

893-
pub struct BorrowedLocalsResults<'a, 'mir, 'tcx> {
890+
pub struct BorrowedLocalsResults<'mir, 'tcx> {
894891
/// the results of the liveness analysis of `LiveBorrows`
895892
borrows_analysis_results: Results<'tcx, LiveBorrows<'mir, 'tcx>>,
896893

@@ -900,36 +897,26 @@ pub struct BorrowedLocalsResults<'a, 'mir, 'tcx> {
900897
/// to the set of `Local`s that are borrowed through those references, pointers or composite values.
901898
borrowed_local_to_locals_to_keep_alive: FxHashMap<Local, FxHashSet<Local>>,
902899

903-
/// The results cursor of the `MaybeBorrowedLocals` analysis. Needed as an upper bound, since
900+
/// The results of the `MaybeBorrowedLocals` analysis. Needed as an upper bound, since
904901
/// to ensure soundness the `LiveBorrows` analysis would keep more `Local`s alive than
905902
/// strictly necessary.
906-
maybe_borrowed_locals_results_cursor: RefCell<
907-
ResultsCursor<'mir, 'tcx, MaybeBorrowedLocals, &'a Results<'tcx, MaybeBorrowedLocals>>,
908-
>,
903+
maybe_borrowed_locals_results: Results<'tcx, MaybeBorrowedLocals>,
909904
}
910905

911-
impl<'a, 'mir, 'tcx> BorrowedLocalsResults<'a, 'mir, 'tcx>
906+
impl<'mir, 'tcx> BorrowedLocalsResults<'mir, 'tcx>
912907
where
913908
'tcx: 'mir,
914-
'tcx: 'a,
915909
{
916910
fn new(
917911
borrows_analysis_results: Results<'tcx, LiveBorrows<'mir, 'tcx>>,
918-
maybe_borrowed_locals_results_cursor: ResultsCursor<
919-
'mir,
920-
'tcx,
921-
MaybeBorrowedLocals,
922-
&'a Results<'tcx, MaybeBorrowedLocals>,
923-
>,
912+
maybe_borrowed_locals_results: Results<'tcx, MaybeBorrowedLocals>,
924913
dep_graph: BorrowDepGraph,
925914
) -> Self {
926915
let borrowed_local_to_locals_to_keep_alive = Self::get_locals_to_keep_alive_map(dep_graph);
927916
Self {
928917
borrows_analysis_results,
929918
borrowed_local_to_locals_to_keep_alive,
930-
maybe_borrowed_locals_results_cursor: RefCell::new(
931-
maybe_borrowed_locals_results_cursor,
932-
),
919+
maybe_borrowed_locals_results,
933920
}
934921
}
935922

@@ -1051,17 +1038,12 @@ where
10511038

10521039
/// The function gets the results of the borrowed locals analysis in this module. See the module
10531040
/// doc-comment for information on what exactly this analysis does.
1054-
#[instrument(skip(tcx, maybe_borrowed_locals_cursor, body), level = "debug")]
1055-
pub fn get_borrowed_locals_results<'a, 'mir, 'tcx>(
1041+
#[instrument(skip(tcx, maybe_borrowed_locals, body), level = "debug")]
1042+
pub fn get_borrowed_locals_results<'mir, 'tcx>(
10561043
body: &'mir Body<'tcx>,
10571044
tcx: TyCtxt<'tcx>,
1058-
maybe_borrowed_locals_cursor: ResultsCursor<
1059-
'mir,
1060-
'tcx,
1061-
MaybeBorrowedLocals,
1062-
&'a Results<'tcx, MaybeBorrowedLocals>,
1063-
>,
1064-
) -> BorrowedLocalsResults<'a, 'mir, 'tcx> {
1045+
maybe_borrowed_locals: Results<'tcx, MaybeBorrowedLocals>,
1046+
) -> BorrowedLocalsResults<'mir, 'tcx> {
10651047
debug!("body: {:#?}", body);
10661048

10671049
let mut borrow_deps = BorrowDependencies::new(body.local_decls(), tcx);
@@ -1111,19 +1093,24 @@ pub fn get_borrowed_locals_results<'a, 'mir, 'tcx>(
11111093
let live_borrows_results =
11121094
live_borrows.into_engine(tcx, body).pass_name("borrowed_locals").iterate_to_fixpoint();
11131095

1114-
BorrowedLocalsResults::new(
1115-
live_borrows_results,
1116-
maybe_borrowed_locals_cursor,
1117-
borrow_deps.dep_graph,
1118-
)
1096+
BorrowedLocalsResults::new(live_borrows_results, maybe_borrowed_locals, borrow_deps.dep_graph)
11191097
}
11201098

11211099
/// The `ResultsCursor` equivalent for the borrowed locals analysis. Since this analysis doesn't
11221100
/// require convergence, we expose the set of borrowed `Local`s for a `Location` directly via
11231101
/// the `get` method without the need for any prior 'seek' calls.
11241102
pub struct BorrowedLocalsResultsCursor<'a, 'mir, 'tcx> {
11251103
// The cursor for the liveness analysis performed by `LiveBorrows`
1126-
borrows_analysis_cursor: ResultsRefCursor<'a, 'mir, 'tcx, LiveBorrows<'mir, 'tcx>>,
1104+
borrows_analysis_cursor: ResultsCursor<
1105+
'mir,
1106+
'tcx,
1107+
LiveBorrows<'mir, 'tcx>,
1108+
Results<
1109+
'tcx,
1110+
LiveBorrows<'mir, 'tcx>,
1111+
&'a rustc_index::IndexVec<BasicBlock, BitSet<Local>>,
1112+
>,
1113+
>,
11271114

11281115
// Maps each `Local` corresponding to a reference or pointer to the set of `Local`s
11291116
// that are borrowed through the ref/ptr. Additionally contains entries for `Local`s
@@ -1132,14 +1119,13 @@ pub struct BorrowedLocalsResultsCursor<'a, 'mir, 'tcx> {
11321119
borrowed_local_to_locals_to_keep_alive: &'a FxHashMap<Local, FxHashSet<Local>>,
11331120

11341121
// the cursor of the conservative borrowed locals analysis
1135-
maybe_borrowed_locals_results_cursor: &'a RefCell<
1136-
ResultsCursor<'mir, 'tcx, MaybeBorrowedLocals, &'a Results<'tcx, MaybeBorrowedLocals>>,
1137-
>,
1122+
maybe_borrowed_locals_results_cursor: ResultsClonedCursor<'a, 'mir, 'tcx, MaybeBorrowedLocals>,
11381123
}
11391124

11401125
impl<'a, 'mir, 'tcx> BorrowedLocalsResultsCursor<'a, 'mir, 'tcx> {
1141-
pub fn new(body: &'mir Body<'tcx>, results: &'a BorrowedLocalsResults<'a, 'mir, 'tcx>) -> Self {
1142-
let mut cursor = ResultsCursor::new(body, &results.borrows_analysis_results);
1126+
pub fn new(body: &'mir Body<'tcx>, results: &'a BorrowedLocalsResults<'mir, 'tcx>) -> Self {
1127+
let mut cursor =
1128+
ResultsCursor::new(body, results.borrows_analysis_results.clone_analysis());
11431129

11441130
// We don't care about the order of the blocks, only about the result at a given location.
11451131
// This statement is necessary since we're performing a backward analysis in `LiveBorrows`,
@@ -1149,7 +1135,10 @@ impl<'a, 'mir, 'tcx> BorrowedLocalsResultsCursor<'a, 'mir, 'tcx> {
11491135
Self {
11501136
borrows_analysis_cursor: cursor,
11511137
borrowed_local_to_locals_to_keep_alive: &results.borrowed_local_to_locals_to_keep_alive,
1152-
maybe_borrowed_locals_results_cursor: &results.maybe_borrowed_locals_results_cursor,
1138+
maybe_borrowed_locals_results_cursor: ResultsClonedCursor::new(
1139+
body,
1140+
results.maybe_borrowed_locals_results.clone_analysis(),
1141+
),
11531142
}
11541143
}
11551144

@@ -1178,11 +1167,9 @@ impl<'a, 'mir, 'tcx> BorrowedLocalsResultsCursor<'a, 'mir, 'tcx> {
11781167
// use results of conservative analysis as an "upper bound" on the borrowed locals. This
11791168
// is necessary since to guarantee soundness for this analysis we would have to keep
11801169
// more `Local`s alive than strictly necessary.
1181-
let mut maybe_borrowed_locals_cursor =
1182-
self.maybe_borrowed_locals_results_cursor.borrow_mut();
1183-
maybe_borrowed_locals_cursor.allow_unreachable();
1184-
maybe_borrowed_locals_cursor.seek_before_primary_effect(loc);
1185-
let upper_bound_borrowed_locals = maybe_borrowed_locals_cursor.get();
1170+
self.maybe_borrowed_locals_results_cursor.allow_unreachable();
1171+
self.maybe_borrowed_locals_results_cursor.seek_before_primary_effect(loc);
1172+
let upper_bound_borrowed_locals = self.maybe_borrowed_locals_results_cursor.get();
11861173
borrowed_locals.intersect(upper_bound_borrowed_locals);
11871174

11881175
debug!(?borrowed_locals);
@@ -1225,7 +1212,7 @@ impl<'mir, 'tcx> LiveBorrows<'mir, 'tcx> {
12251212
}
12261213
}
12271214

1228-
impl<'mir, 'tcx> crate::CloneAnalysis for LiveBorrows<'mir, 'tcx> {
1215+
impl<'mir, 'tcx> CloneAnalysis for LiveBorrows<'mir, 'tcx> {
12291216
fn clone_analysis(&self) -> Self {
12301217
self.clone()
12311218
}
@@ -1251,7 +1238,7 @@ impl<'a, 'tcx> GenKillAnalysis<'tcx> for LiveBorrows<'a, 'tcx> {
12511238

12521239
#[instrument(skip(self, trans), level = "debug")]
12531240
fn statement_effect(
1254-
&self,
1241+
&mut self,
12551242
trans: &mut impl GenKill<Self::Idx>,
12561243
statement: &mir::Statement<'tcx>,
12571244
location: Location,
@@ -1261,7 +1248,7 @@ impl<'a, 'tcx> GenKillAnalysis<'tcx> for LiveBorrows<'a, 'tcx> {
12611248

12621249
#[instrument(skip(self, trans), level = "debug")]
12631250
fn terminator_effect(
1264-
&self,
1251+
&mut self,
12651252
trans: &mut impl GenKill<Self::Idx>,
12661253
terminator: &mir::Terminator<'tcx>,
12671254
location: Location,
@@ -1270,7 +1257,7 @@ impl<'a, 'tcx> GenKillAnalysis<'tcx> for LiveBorrows<'a, 'tcx> {
12701257
}
12711258

12721259
fn call_return_effect(
1273-
&self,
1260+
&mut self,
12741261
_trans: &mut impl GenKill<Self::Idx>,
12751262
_block: mir::BasicBlock,
12761263
_return_places: CallReturnPlaces<'_, 'tcx>,

compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub use super::*;
22

3-
use crate::impls::{BorrowedLocalsResults, BorrowedLocalsResultsCursor};
3+
use crate::impls::BorrowedLocalsResultsCursor;
44
use crate::{CallReturnPlaces, GenKill};
55
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
66
use rustc_middle::mir::*;
@@ -151,18 +151,15 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead {
151151
/// given location; i.e. whether its storage can go away without being observed.
152152
pub struct MaybeRequiresStorage<'a, 'mir, 'tcx> {
153153
body: &'mir Body<'tcx>,
154-
borrowed_locals: RefCell<BorrowedLocalsResultsCursor<'a, 'mir, 'tcx>>,
154+
borrowed_locals_cursor: BorrowedLocalsResultsCursor<'a, 'mir, 'tcx>,
155155
}
156156

157157
impl<'a, 'mir, 'tcx> MaybeRequiresStorage<'a, 'mir, 'tcx> {
158158
pub fn new(
159159
body: &'mir Body<'tcx>,
160-
borrowed_locals: &'a BorrowedLocalsResults<'a, 'mir, 'tcx>,
160+
borrowed_locals_cursor: BorrowedLocalsResultsCursor<'a, 'mir, 'tcx>,
161161
) -> Self {
162-
MaybeRequiresStorage {
163-
body,
164-
borrowed_locals: RefCell::new(BorrowedLocalsResultsCursor::new(body, borrowed_locals)),
165-
}
162+
MaybeRequiresStorage { body, borrowed_locals_cursor }
166163
}
167164
}
168165

@@ -195,7 +192,7 @@ impl<'a, 'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'a, '
195192
loc: Location,
196193
) {
197194
// If a place is borrowed in a statement, it needs storage for that statement.
198-
let borrowed_locals_at_loc = self.borrowed_locals.borrow_mut().get(loc);
195+
let borrowed_locals_at_loc = self.borrowed_locals_cursor.get(loc);
199196
for i in 0..self.body.local_decls().len() {
200197
let local = Local::from_usize(i);
201198
if borrowed_locals_at_loc.contains(local) {
@@ -246,7 +243,7 @@ impl<'a, 'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'a, '
246243
loc: Location,
247244
) {
248245
// If a place is borrowed in a statement, it needs storage for that statement.
249-
let borrowed_locals_at_loc = self.borrowed_locals.borrow_mut().get(loc);
246+
let borrowed_locals_at_loc = self.borrowed_locals_cursor.get(loc);
250247
for i in 0..self.body.local_decls().len() {
251248
let local = Local::from_usize(i);
252249
if borrowed_locals_at_loc.contains(local) {
@@ -359,14 +356,14 @@ impl<'a, 'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'a, '
359356
impl<'a, 'mir, 'tcx> MaybeRequiresStorage<'a, 'mir, 'tcx> {
360357
/// Kill locals that are fully moved and have not been borrowed.
361358
fn check_for_move(&mut self, trans: &mut impl GenKill<Local>, loc: Location) {
362-
let body = self.borrowed_locals.body();
363-
let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals };
359+
let body = self.body;
360+
let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals_cursor };
364361
visitor.visit_location(body, loc);
365362
}
366363
}
367364

368365
struct MoveVisitor<'a, 'b, 'mir, 'tcx, T> {
369-
borrowed_locals: &'a RefCell<BorrowedLocalsResultsCursor<'b, 'mir, 'tcx>>,
366+
borrowed_locals: &'a mut BorrowedLocalsResultsCursor<'b, 'mir, 'tcx>,
370367
trans: &'a mut T,
371368
}
372369

@@ -377,7 +374,7 @@ where
377374
#[instrument(skip(self), level = "debug")]
378375
fn visit_local(&mut self, local: Local, context: PlaceContext, loc: Location) {
379376
if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
380-
let borrowed_locals = self.borrowed_locals.borrow_mut().get(loc);
377+
let borrowed_locals = self.borrowed_locals.get(loc);
381378
debug!(?borrowed_locals);
382379
if !borrowed_locals.contains(local) {
383380
self.trans.kill(local);

compiler/rustc_mir_transform/src/generator.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -594,25 +594,26 @@ fn locals_live_across_suspend_points<'tcx>(
594594
.iterate_to_fixpoint()
595595
.into_results_cursor(body_ref);
596596

597+
// conservative upper bound on borrowed locals that is needed in the `LiveBorrows` analysis
597598
let borrowed_locals_results =
598599
MaybeBorrowedLocals.into_engine(tcx, body_ref).pass_name("generator").iterate_to_fixpoint();
599-
let borrowed_locals_cursor =
600-
rustc_mir_dataflow::ResultsCursor::new(body_ref, &borrowed_locals_results);
601-
602-
let mut blc = rustc_mir_dataflow::ResultsCursor::new(body_ref, &borrowed_locals_results);
603600

604601
// Calculate the locals that are live due to outstanding references or pointers.
605-
let live_borrows_results = get_borrowed_locals_results(body_ref, tcx, borrowed_locals_cursor);
602+
let live_borrows_results = get_borrowed_locals_results(body_ref, tcx, borrowed_locals_results);
603+
606604
let mut live_borrows_cursor = BorrowedLocalsResultsCursor::new(body_ref, &live_borrows_results);
607605

608606
// Calculate the MIR locals that we actually need to keep storage around
609607
// for.
610-
let requires_storage_results = MaybeRequiresStorage::new(body, &live_borrows_results)
611-
.into_engine(tcx, body_ref)
612-
.iterate_to_fixpoint();
608+
let mut requires_storage_results = MaybeRequiresStorage::new(
609+
body,
610+
BorrowedLocalsResultsCursor::new(body_ref, &live_borrows_results),
611+
)
612+
.into_engine(tcx, body_ref)
613+
.iterate_to_fixpoint();
613614

614615
let mut requires_storage_cursor =
615-
rustc_mir_dataflow::ResultsCursor::new(body_ref, &requires_storage_results);
616+
rustc_mir_dataflow::ResultsRefCursor::new(body_ref, &mut requires_storage_results);
616617

617618
// Calculate the liveness of MIR locals ignoring borrows.
618619
let mut liveness = MaybeLiveLocals
@@ -646,8 +647,6 @@ fn locals_live_across_suspend_points<'tcx>(
646647
// forever. Note that the final liveness is still bounded by the storage liveness
647648
// of the local, which happens using the `intersect` operation below.
648649
let live_borrowed_locals = live_borrows_cursor.get(loc);
649-
blc.seek_before_primary_effect(loc);
650-
let old_borrowed_locals = blc.get();
651650

652651
let mut live_locals_stmt: BitSet<_> = BitSet::new_empty(body.local_decls.len());
653652
liveness.seek_before_primary_effect(loc);
@@ -658,7 +657,6 @@ fn locals_live_across_suspend_points<'tcx>(
658657
storage_req.union(requires_storage_cursor.get());
659658

660659
debug!(?live_borrowed_locals);
661-
debug!(?old_borrowed_locals);
662660
debug!(?live_locals_stmt);
663661
debug!(?storage_req);
664662

@@ -770,7 +768,7 @@ fn compute_storage_conflicts<'a, 'mir, 'tcx>(
770768
body: &'mir Body<'tcx>,
771769
saved_locals: &GeneratorSavedLocals,
772770
always_live_locals: BitSet<Local>,
773-
requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'a, 'mir, 'tcx>>,
771+
mut requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'a, 'mir, 'tcx>>,
774772
) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
775773
assert_eq!(body.local_decls.len(), saved_locals.domain_size());
776774

0 commit comments

Comments
 (0)