Skip to content

Commit 7846743

Browse files
committed
Lazily calculate MaybeTransitiveLiveLocals
1 parent dddf046 commit 7846743

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

compiler/rustc_mir_transform/src/merge_branches.rs

+35-27
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
2424
let param_env = tcx.param_env_reveal_all_normalized(def_id);
2525

2626
let borrowed_locals = borrowed_locals(body);
27-
let mut maybe_live: ResultsCursor<'_, '_, MaybeTransitiveLiveLocals<'_>> =
28-
MaybeTransitiveLiveLocals::new(&borrowed_locals)
29-
.into_engine(tcx, body)
30-
.iterate_to_fixpoint()
31-
.into_results_cursor(body);
27+
let mut stmt_live_result = StatementLiveResult::new(tcx, body, &borrowed_locals);
3228
for i in 0..body.basic_blocks.len() {
3329
let bbs = &*body.basic_blocks;
3430
let switch_bb_idx = BasicBlock::from_usize(i);
@@ -75,8 +71,7 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
7571
targets,
7672
src_place,
7773
src_ty,
78-
&borrowed_locals,
79-
&mut maybe_live,
74+
&mut stmt_live_result,
8075
) {
8176
let statement_index = bbs[switch_bb_idx].statements.len();
8277
let parent_end = Location { block: switch_bb_idx, statement_index };
@@ -93,6 +88,33 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
9388
}
9489
}
9590

91+
struct StatementLiveResult<'tcx, 'mir, 'a> {
92+
tcx: TyCtxt<'tcx>,
93+
body: &'mir Body<'tcx>,
94+
result: Option<ResultsCursor<'mir, 'tcx, MaybeTransitiveLiveLocals<'a>>>,
95+
borrowed_locals: &'a BitSet<Local>,
96+
}
97+
98+
impl<'tcx, 'mir, 'a> StatementLiveResult<'tcx, 'mir, 'a> {
99+
fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, borrowed_locals: &'a BitSet<Local>) -> Self {
100+
Self { tcx, body, result: None, borrowed_locals }
101+
}
102+
103+
fn is_live(&mut self, loc: Location, local: Local) -> bool {
104+
if self.borrowed_locals.contains(local) {
105+
return true;
106+
}
107+
let maybe_live = self.result.get_or_insert_with(|| {
108+
MaybeTransitiveLiveLocals::new(&self.borrowed_locals)
109+
.into_engine(self.tcx, self.body)
110+
.iterate_to_fixpoint()
111+
.into_results_cursor(self.body)
112+
});
113+
maybe_live.seek_before_primary_effect(loc);
114+
maybe_live.get().contains(local)
115+
}
116+
}
117+
96118
/// The GVN simplified
97119
/// ```ignore (syntax-highlighting-only)
98120
/// match a {
@@ -116,22 +138,11 @@ fn can_simplify_to_copy<'tcx>(
116138
targets: &SwitchTargets,
117139
src_place: Place<'tcx>,
118140
src_ty: tcx::PlaceTy<'tcx>,
119-
borrowed_locals: &BitSet<Local>,
120-
maybe_live: &mut ResultsCursor<'_, 'tcx, MaybeTransitiveLiveLocals<'_>>,
141+
stmt_live_result: &mut StatementLiveResult<'tcx, '_, '_>,
121142
) -> Option<Place<'tcx>> {
122143
let mut targets_iter = targets.iter();
123144
let dest_place = targets_iter.next().and_then(|(index, target)| {
124-
find_copy_assign(
125-
tcx,
126-
param_env,
127-
body,
128-
index,
129-
target,
130-
src_place,
131-
src_ty,
132-
borrowed_locals,
133-
maybe_live,
134-
)
145+
find_copy_assign(tcx, param_env, body, index, target, src_place, src_ty, stmt_live_result)
135146
})?;
136147
let dest_ty = dest_place.ty(body.local_decls(), tcx);
137148
if dest_ty.ty != src_ty.ty || dest_ty.variant_index.is_some() {
@@ -147,8 +158,7 @@ fn can_simplify_to_copy<'tcx>(
147158
other_target,
148159
src_place,
149160
src_ty,
150-
borrowed_locals,
151-
maybe_live,
161+
stmt_live_result,
152162
)
153163
}) {
154164
return None;
@@ -164,8 +174,7 @@ fn find_copy_assign<'tcx>(
164174
target_block: BasicBlock,
165175
src_place: Place<'tcx>,
166176
src_ty: tcx::PlaceTy<'tcx>,
167-
borrowed_locals: &BitSet<Local>,
168-
maybe_live: &mut ResultsCursor<'_, 'tcx, MaybeTransitiveLiveLocals<'_>>,
177+
stmt_live_result: &mut StatementLiveResult<'tcx, '_, '_>,
169178
) -> Option<Place<'tcx>> {
170179
let statements = &body.basic_blocks[target_block].statements;
171180
if statements.is_empty() {
@@ -190,11 +199,10 @@ fn find_copy_assign<'tcx>(
190199
StatementKind::Assign(box (dest_place, _))
191200
| StatementKind::SetDiscriminant { place: box dest_place, .. }
192201
| StatementKind::Deinit(box dest_place) => {
193-
if dest_place.is_indirect() || borrowed_locals.contains(dest_place.local) {
202+
if dest_place.is_indirect() {
194203
return None;
195204
}
196-
maybe_live.seek_before_primary_effect(loc);
197-
if !maybe_live.get().contains(dest_place.local) {
205+
if !stmt_live_result.is_live(loc, dest_place.local) {
198206
lived_stmts.remove(statement_index);
199207
} else if matches!(statement.kind, StatementKind::Assign(_))
200208
&& expected_assign_stmt.is_none()

0 commit comments

Comments
 (0)