Skip to content

Commit 1317dcc

Browse files
committed
Use MaybeUninitializedLocals analysis in GVN mir-opt to remove fewer storage statements
1 parent da07f36 commit 1317dcc

File tree

132 files changed

+1232
-1651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+1232
-1651
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ use rustc_middle::mir::visit::*;
108108
use rustc_middle::mir::*;
109109
use rustc_middle::ty::layout::HasTypingEnv;
110110
use rustc_middle::ty::{self, Ty, TyCtxt};
111+
use rustc_mir_dataflow::impls::MaybeUninitializedLocals;
112+
use rustc_mir_dataflow::{Analysis, ResultsCursor};
111113
use rustc_span::DUMMY_SP;
112114
use smallvec::SmallVec;
113115
use tracing::{debug, instrument, trace};
@@ -151,10 +153,31 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
151153
state.visit_basic_block_data(bb, data);
152154
}
153155

154-
// For each local that is reused (`y` above), we remove its storage statements do avoid any
155-
// difficulty. Those locals are SSA, so should be easy to optimize by LLVM without storage
156-
// statements.
157-
StorageRemover { tcx, reused_locals: state.reused_locals }.visit_body_preserves_cfg(body);
156+
// If we emit storage annotations, use `MaybeStorageDead` to check which reused locals
157+
// require storage removal (making them alive for the duration of the function).
158+
let storage_to_remove = if tcx.sess.emit_lifetime_markers() {
159+
let maybe_uninit = MaybeUninitializedLocals::new()
160+
.iterate_to_fixpoint(tcx, body, Some("mir_opt::gvn"))
161+
.into_results_cursor(body);
162+
163+
let mut storage_checker = StorageChecker {
164+
storage_to_check: state.reused_locals.clone(),
165+
storage_to_remove: DenseBitSet::new_empty(body.local_decls.len()),
166+
maybe_uninit,
167+
};
168+
169+
storage_checker.visit_body(body);
170+
171+
storage_checker.storage_to_remove
172+
} else {
173+
// Conservatively remove all storage statements for reused locals.
174+
state.reused_locals.clone()
175+
};
176+
177+
debug!(?storage_to_remove);
178+
179+
StorageRemover { tcx, reused_locals: state.reused_locals, storage_to_remove }
180+
.visit_body_preserves_cfg(body);
158181
}
159182

160183
fn is_required(&self) -> bool {
@@ -1931,6 +1954,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
19311954
struct StorageRemover<'tcx> {
19321955
tcx: TyCtxt<'tcx>,
19331956
reused_locals: DenseBitSet<Local>,
1957+
storage_to_remove: DenseBitSet<Local>,
19341958
}
19351959

19361960
impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
@@ -1951,11 +1975,48 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
19511975
match stmt.kind {
19521976
// When removing storage statements, we need to remove both (#107511).
19531977
StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
1954-
if self.reused_locals.contains(l) =>
1978+
if self.storage_to_remove.contains(l) =>
19551979
{
19561980
stmt.make_nop(true)
19571981
}
19581982
_ => self.super_statement(stmt, loc),
19591983
}
19601984
}
19611985
}
1986+
1987+
struct StorageChecker<'a, 'tcx> {
1988+
storage_to_check: DenseBitSet<Local>,
1989+
storage_to_remove: DenseBitSet<Local>,
1990+
maybe_uninit: ResultsCursor<'a, 'tcx, MaybeUninitializedLocals>,
1991+
}
1992+
1993+
impl<'a, 'tcx> Visitor<'tcx> for StorageChecker<'a, 'tcx> {
1994+
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
1995+
match context {
1996+
// These mutating uses do not require the local to be initialized.
1997+
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
1998+
| PlaceContext::MutatingUse(MutatingUseContext::Call)
1999+
| PlaceContext::MutatingUse(MutatingUseContext::Store)
2000+
| PlaceContext::MutatingUse(MutatingUseContext::Yield)
2001+
| PlaceContext::NonUse(_) => {
2002+
return;
2003+
}
2004+
// Must check validity for other mutating usages and all non-mutating uses.
2005+
PlaceContext::MutatingUse(_) | PlaceContext::NonMutatingUse(_) => {}
2006+
}
2007+
2008+
if self.storage_to_check.contains(local) {
2009+
self.maybe_uninit.seek_before_primary_effect(location);
2010+
2011+
if self.maybe_uninit.get().contains(local) {
2012+
debug!(
2013+
?location,
2014+
?local,
2015+
"local is maybe uninit in this location, removing storage"
2016+
);
2017+
self.storage_to_remove.insert(local);
2018+
self.storage_to_check.remove(local);
2019+
}
2020+
}
2021+
}
2022+
}

tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@
5555
}
5656

5757
bb0: {
58-
nop;
58+
StorageLive(_1);
5959
- _1 = const 1_u8;
60-
nop;
61-
- _2 = const 2_u8;
62-
nop;
63-
- _3 = const 3_u8;
6460
+ nop;
61+
StorageLive(_2);
62+
- _2 = const 2_u8;
6563
+ nop;
64+
StorageLive(_3);
65+
- _3 = const 3_u8;
6666
+ nop;
6767
StorageLive(_4);
6868
StorageLive(_5);
@@ -95,7 +95,7 @@
9595
- _12 = const Point {{ x: 32_u32, y: 32_u32 }};
9696
+ nop;
9797
StorageLive(_13);
98-
nop;
98+
StorageLive(_14);
9999
- _14 = const 32_u32;
100100
+ nop;
101101
StorageLive(_15);
@@ -104,17 +104,17 @@
104104
+ nop;
105105
+ nop;
106106
StorageDead(_15);
107-
nop;
107+
StorageDead(_14);
108108
_0 = const ();
109109
StorageDead(_13);
110110
StorageDead(_12);
111111
StorageDead(_11);
112112
StorageDead(_10);
113113
StorageDead(_9);
114114
StorageDead(_4);
115-
nop;
116-
nop;
117-
nop;
115+
StorageDead(_3);
116+
StorageDead(_2);
117+
StorageDead(_1);
118118
return;
119119
}
120120
}

tests/mir-opt/const_prop/aggregate.main.GVN.panic-abort.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
}
1414

1515
bb0: {
16-
- StorageLive(_1);
17-
+ nop;
16+
StorageLive(_1);
1817
StorageLive(_2);
1918
StorageLive(_3);
2019
_3 = (const 0_i32, const 1_u8, const 2_i32);
@@ -36,8 +35,7 @@
3635
StorageDead(_5);
3736
StorageDead(_4);
3837
_0 = const ();
39-
- StorageDead(_1);
40-
+ nop;
38+
StorageDead(_1);
4139
return;
4240
}
4341
}

tests/mir-opt/const_prop/aggregate.main.GVN.panic-unwind.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
}
1414

1515
bb0: {
16-
- StorageLive(_1);
17-
+ nop;
16+
StorageLive(_1);
1817
StorageLive(_2);
1918
StorageLive(_3);
2019
_3 = (const 0_i32, const 1_u8, const 2_i32);
@@ -36,8 +35,7 @@
3635
StorageDead(_5);
3736
StorageDead(_4);
3837
_0 = const ();
39-
- StorageDead(_1);
40-
+ nop;
38+
StorageDead(_1);
4139
return;
4240
}
4341
}

tests/mir-opt/const_prop/bad_op_div_by_zero.main.GVN.panic-abort.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
}
1919

2020
bb0: {
21-
- StorageLive(_1);
22-
+ nop;
21+
StorageLive(_1);
2322
_1 = const 0_i32;
2423
StorageLive(_2);
2524
StorageLive(_3);
@@ -48,8 +47,7 @@
4847
StorageDead(_3);
4948
_0 = const ();
5049
StorageDead(_2);
51-
- StorageDead(_1);
52-
+ nop;
50+
StorageDead(_1);
5351
return;
5452
}
5553
}

tests/mir-opt/const_prop/bad_op_div_by_zero.main.GVN.panic-unwind.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
}
1919

2020
bb0: {
21-
- StorageLive(_1);
22-
+ nop;
21+
StorageLive(_1);
2322
_1 = const 0_i32;
2423
StorageLive(_2);
2524
StorageLive(_3);
@@ -48,8 +47,7 @@
4847
StorageDead(_3);
4948
_0 = const ();
5049
StorageDead(_2);
51-
- StorageDead(_1);
52-
+ nop;
50+
StorageDead(_1);
5351
return;
5452
}
5553
}

tests/mir-opt/const_prop/bad_op_mod_by_zero.main.GVN.panic-abort.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
}
1919

2020
bb0: {
21-
- StorageLive(_1);
22-
+ nop;
21+
StorageLive(_1);
2322
_1 = const 0_i32;
2423
StorageLive(_2);
2524
StorageLive(_3);
@@ -48,8 +47,7 @@
4847
StorageDead(_3);
4948
_0 = const ();
5049
StorageDead(_2);
51-
- StorageDead(_1);
52-
+ nop;
50+
StorageDead(_1);
5351
return;
5452
}
5553
}

tests/mir-opt/const_prop/bad_op_mod_by_zero.main.GVN.panic-unwind.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
}
1919

2020
bb0: {
21-
- StorageLive(_1);
22-
+ nop;
21+
StorageLive(_1);
2322
_1 = const 0_i32;
2423
StorageLive(_2);
2524
StorageLive(_3);
@@ -48,8 +47,7 @@
4847
StorageDead(_3);
4948
_0 = const ();
5049
StorageDead(_2);
51-
- StorageDead(_1);
52-
+ nop;
50+
StorageDead(_1);
5351
return;
5452
}
5553
}

tests/mir-opt/const_prop/boolean_identities.test.GVN.diff

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@
1919
}
2020

2121
bb0: {
22-
- StorageLive(_3);
23-
+ nop;
22+
StorageLive(_3);
2423
StorageLive(_4);
2524
_4 = copy _2;
2625
- _3 = BitOr(move _4, const true);
2726
+ _3 = const true;
2827
StorageDead(_4);
29-
- StorageLive(_5);
30-
+ nop;
28+
StorageLive(_5);
3129
StorageLive(_6);
3230
_6 = copy _1;
3331
- _5 = BitAnd(move _6, const false);
@@ -43,10 +41,8 @@
4341
+ _0 = const false;
4442
StorageDead(_8);
4543
StorageDead(_7);
46-
- StorageDead(_5);
47-
- StorageDead(_3);
48-
+ nop;
49-
+ nop;
44+
StorageDead(_5);
45+
StorageDead(_3);
5046
return;
5147
}
5248
}

tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919

2020
bb0: {
2121
StorageLive(_1);
22-
- StorageLive(_2);
23-
+ nop;
22+
StorageLive(_2);
2423
StorageLive(_3);
2524
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind unreachable];
2625
}
@@ -43,9 +42,8 @@
4342
_10 = copy ((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
4443
_2 = copy (*_10);
4544
- _1 = Add(move _2, const 0_i32);
46-
- StorageDead(_2);
4745
+ _1 = copy _2;
48-
+ nop;
46+
StorageDead(_2);
4947
drop(_3) -> [return: bb2, unwind unreachable];
5048
}
5149

0 commit comments

Comments
 (0)