Skip to content

Commit f534d9f

Browse files
committed
Stop invalidating predecessors cache when accessing unique basic block, invalidate cache when accessing unique terminator
1 parent ce29f43 commit f534d9f

File tree

17 files changed

+112
-73
lines changed

17 files changed

+112
-73
lines changed

src/librustc/mir/mod.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,38 @@ impl<'tcx> Body<'tcx> {
203203

204204
#[inline]
205205
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
206-
self.predecessors_cache = None;
207-
// self.cache.invalidate();
208206
&mut self.basic_blocks
209207
}
210208

209+
pub fn basic_block_terminator_opt_mut(&mut self, bb: BasicBlock) -> &mut Option<Terminator<'tcx>> {
210+
self.predecessors_cache = None;
211+
&mut self.basic_blocks[bb].terminator
212+
}
213+
214+
pub fn basic_block_terminator_mut(&mut self, bb: BasicBlock) -> &mut Terminator<'tcx> {
215+
self.predecessors_cache = None;
216+
/*
217+
let data = &mut self.basic_blocks[bb];
218+
if let Some(cache) = self.predecessors_cache.as_mut() {
219+
for successor in data.terminator().successors() {
220+
let successor_vec = &mut cache[*successor];
221+
for i in (0..successor_vec.len()).rev() {
222+
if successor_vec[i] == bb {
223+
successor_vec.swap_remove(i);
224+
break;
225+
}
226+
}
227+
}
228+
}
229+
*/
230+
231+
self.basic_blocks[bb].terminator_mut()
232+
}
233+
211234
#[inline]
212235
pub fn basic_blocks_and_local_decls_mut(
213236
&mut self,
214237
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
215-
self.predecessors_cache = None;
216-
// self.cache.invalidate();
217238
(&mut self.basic_blocks, &mut self.local_decls)
218239
}
219240

@@ -1358,6 +1379,10 @@ impl<'tcx> BasicBlockData<'tcx> {
13581379
BasicBlockData { statements: vec![], terminator, is_cleanup: false }
13591380
}
13601381

1382+
pub fn terminator_opt(&self) -> &Option<Terminator<'tcx>> {
1383+
&self.terminator
1384+
}
1385+
13611386
/// Accessor for terminator.
13621387
///
13631388
/// Terminator may not be None after construction of the basic block is complete. This accessor
@@ -1366,10 +1391,17 @@ impl<'tcx> BasicBlockData<'tcx> {
13661391
self.terminator.as_ref().expect("invalid terminator state")
13671392
}
13681393

1369-
pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
1394+
// This cannot be public since changing the terminator will break the predecessors cache in Body
1395+
// To do so outside of this module, use Body::basic_block_terminator_mut(BasicBlock)
1396+
fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
13701397
self.terminator.as_mut().expect("invalid terminator state")
13711398
}
13721399

1400+
// This can be public since changing the kind will not break the predecessors cache in Body
1401+
pub fn terminator_kind_mut(&mut self) -> &mut TerminatorKind<'tcx> {
1402+
&mut self.terminator_mut().kind
1403+
}
1404+
13731405
pub fn retain_statements<F>(&mut self, mut f: F)
13741406
where
13751407
F: FnMut(&mut Statement<'_>) -> bool,

src/librustc/mir/traversal.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
5555

5656
let data = &self.body[idx];
5757

58-
if let Some(ref term) = data.terminator {
58+
if let Some(ref term) = data.terminator_opt() {
5959
self.worklist.extend(term.successors());
6060
}
6161

@@ -117,7 +117,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
117117

118118
let data = &po.body[root];
119119

120-
if let Some(ref term) = data.terminator {
120+
if let Some(ref term) = data.terminator_opt() {
121121
po.visited.insert(root);
122122
po.visit_stack.push((root, term.successors()));
123123
po.traverse_successor();
@@ -186,7 +186,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
186186
};
187187

188188
if self.visited.insert(bb) {
189-
if let Some(term) = &self.body[bb].terminator {
189+
if let Some(term) = &self.body[bb].terminator_opt() {
190190
self.visit_stack.push((bb, term.successors()));
191191
}
192192
}

src/librustc/mir/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ macro_rules! make_mir_visitor {
793793
fn visit_location(&mut self, body: & $($mutability)? Body<'tcx>, location: Location) {
794794
let basic_block = & $($mutability)? body[location.block];
795795
if basic_block.statements.len() == location.statement_index {
796+
// TODO(nashenas88) how to ensure we clear the cache only in the mutable case...
796797
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
797798
self.visit_terminator(terminator, location)
798799
}

src/librustc_codegen_ssa/mir/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ fn create_funclets<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
265265

266266
let funclet;
267267
let ret_llbb;
268-
match mir[bb].terminator.as_ref().map(|t| &t.kind) {
268+
match mir[bb].terminator_opt().as_ref().map(|t| &t.kind) {
269269
// This is a basic block that we're aborting the program for,
270270
// notably in an `extern` function. These basic blocks are inserted
271271
// so that we assert that `extern` functions do indeed not panic,

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
497497
..
498498
},
499499
..
500-
}) = bbd.terminator {
500+
}) = bbd.terminator_opt() {
501501
if let Some(source)
502502
= BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
503503
{

src/librustc_mir/build/cfg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<'tcx> CFG<'tcx> {
6464
source_info: SourceInfo,
6565
kind: TerminatorKind<'tcx>) {
6666
debug!("terminating block {:?} <- {:?}", block, kind);
67-
debug_assert!(self.block_data(block).terminator.is_none(),
67+
debug_assert!(self.block_data(block).terminator_opt().is_none(),
6868
"terminate: block {:?}={:?} already has a terminator set",
6969
block,
7070
self.block_data(block));

src/librustc_mir/build/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
731731

732732
fn finish(self) -> Body<'tcx> {
733733
for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
734-
if block.terminator.is_none() {
734+
if block.terminator_opt().is_none() {
735735
span_bug!(self.fn_span, "no terminator on block {:?}", index);
736736
}
737737
}

src/librustc_mir/dataflow/impls/borrows.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ fn precompute_borrows_out_of_scope<'tcx>(
9898
// Add successor BBs to the work list, if necessary.
9999
let bb_data = &body[bb];
100100
assert!(hi == bb_data.statements.len());
101-
for &succ_bb in bb_data.terminator.as_ref().unwrap().successors() {
101+
for &succ_bb in bb_data.terminator().successors() {
102102
visited.entry(succ_bb)
103103
.and_modify(|lo| {
104104
// `succ_bb` has been seen before. If it wasn't

src/librustc_mir/lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn check_fn_for_unconditional_recursion(
7979

8080
let block = &basic_blocks[bb];
8181

82-
if let Some(ref terminator) = block.terminator {
82+
if let Some(ref terminator) = block.terminator_opt() {
8383
match terminator.kind {
8484
TerminatorKind::Call { ref func, .. } => {
8585
let func_ty = func.ty(body, tcx);

src/librustc_mir/transform/add_call_guards.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ impl AddCallGuards {
4646

4747
let cur_len = body.basic_blocks().len();
4848

49-
for block in body.basic_blocks_mut() {
50-
match block.terminator {
49+
for bb in body.basic_blocks().indices() {
50+
let is_cleanup = body.basic_blocks()[bb].is_cleanup;
51+
match body.basic_block_terminator_opt_mut(bb) {
5152
Some(Terminator {
5253
kind: TerminatorKind::Call {
5354
destination: Some((_, ref mut destination)),
@@ -60,9 +61,9 @@ impl AddCallGuards {
6061
// It's a critical edge, break it
6162
let call_guard = BasicBlockData {
6263
statements: vec![],
63-
is_cleanup: block.is_cleanup,
64+
is_cleanup: is_cleanup,
6465
terminator: Some(Terminator {
65-
source_info,
66+
source_info: *source_info,
6667
kind: TerminatorKind::Goto { target: *destination }
6768
})
6869
};

0 commit comments

Comments
 (0)