Skip to content

Commit 6e2ecde

Browse files
committed
Try MaybeLiveLocals for borrows
1 parent fdb65eb commit 6e2ecde

File tree

1 file changed

+41
-8
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+41
-8
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
8787
use std::borrow::Cow;
8888
use std::hash::{Hash, Hasher};
89+
use std::ops::Range;
8990

9091
use either::Either;
9192
use hashbrown::hash_table::{Entry, HashTable};
@@ -108,6 +109,8 @@ use rustc_middle::mir::visit::*;
108109
use rustc_middle::mir::*;
109110
use rustc_middle::ty::layout::HasTypingEnv;
110111
use rustc_middle::ty::{self, Ty, TyCtxt};
112+
use rustc_mir_dataflow::impls::MaybeLiveLocals;
113+
use rustc_mir_dataflow::{Analysis as _, ResultsCursor};
111114
use rustc_span::DUMMY_SP;
112115
use smallvec::SmallVec;
113116
use tracing::{debug, instrument, trace};
@@ -130,8 +133,37 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
130133
// Clone dominators because we need them while mutating the body.
131134
let dominators = body.basic_blocks.dominators().clone();
132135

136+
let mut borrow_liveness: IndexVec<
137+
Local,
138+
Option<IndexVec<BasicBlock, Option<Range<usize>>>>,
139+
> = IndexVec::from_elem(None, body.local_decls());
140+
133141
let immutable_borrows = ImmutableBorrows::new(tcx, body, typing_env, &ssa);
134142

143+
for (local, _) in body.local_decls.iter_enumerated() {
144+
if !immutable_borrows.locals.contains(local) {
145+
continue;
146+
}
147+
if immutable_borrows.always_live.contains(local) {
148+
continue;
149+
}
150+
borrow_liveness[local] = Some(IndexVec::from_elem(None, &body.basic_blocks));
151+
}
152+
153+
let mut liveness = MaybeLiveLocals
154+
.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-GVN"))
155+
.into_results_cursor(body);
156+
157+
for (bb, bb_data) in traversal::preorder(body) {
158+
liveness.seek_to_block_end(bb);
159+
let live_locals = liveness.get();
160+
for local in live_locals.iter() {
161+
if let Some(ref mut liveness) = borrow_liveness[local] {
162+
liveness[bb] = Some(0..bb_data.statements.len());
163+
}
164+
}
165+
}
166+
135167
let arena = DroplessArena::default();
136168
let mut state = VnState::new(
137169
tcx,
@@ -141,7 +173,7 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
141173
dominators,
142174
&body.local_decls,
143175
&arena,
144-
immutable_borrows,
176+
borrow_liveness,
145177
);
146178

147179
for local in body.args_iter().filter(|&local| ssa.is_ssa(local)) {
@@ -382,7 +414,7 @@ struct VnState<'body, 'a, 'tcx> {
382414
dominators: Dominators<BasicBlock>,
383415
reused_locals: DenseBitSet<Local>,
384416
arena: &'a DroplessArena,
385-
immutable_borrows: ImmutableBorrows,
417+
borrow_liveness: IndexVec<Local, Option<IndexVec<BasicBlock, Option<Range<usize>>>>>,
386418
}
387419

388420
impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
@@ -394,7 +426,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
394426
dominators: Dominators<BasicBlock>,
395427
local_decls: &'body LocalDecls<'tcx>,
396428
arena: &'a DroplessArena,
397-
immutable_borrows: ImmutableBorrows,
429+
borrow_liveness: IndexVec<Local, Option<IndexVec<BasicBlock, Option<Range<usize>>>>>,
398430
) -> Self {
399431
// Compute a rough estimate of the number of values in the body from the number of
400432
// statements. This is meant to reduce the number of allocations, but it's all right if
@@ -416,7 +448,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
416448
dominators,
417449
reused_locals: DenseBitSet::new_empty(local_decls.len()),
418450
arena,
419-
immutable_borrows,
451+
borrow_liveness,
420452
}
421453
}
422454

@@ -1870,10 +1902,11 @@ impl<'tcx> VnState<'_, '_, 'tcx> {
18701902
if !self.ssa.assignment_dominates(&self.dominators, other, loc) {
18711903
return false;
18721904
}
1873-
if self.immutable_borrows.locals.contains(other)
1874-
&& !self.immutable_borrows.always_live.contains(other)
1875-
{
1876-
return false;
1905+
if let Some(ref liveness) = self.borrow_liveness[other] {
1906+
return liveness[loc.block]
1907+
.as_ref()
1908+
.map(|range| range.contains(&loc.statement_index))
1909+
.unwrap_or(false);
18771910
}
18781911
return true;
18791912
})

0 commit comments

Comments
 (0)