Skip to content

Commit a259605

Browse files
committed
Switch to MaybeUninitializedLocals
1 parent 89563b0 commit a259605

13 files changed

+53
-36
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ use rustc_middle::mir::visit::*;
104104
use rustc_middle::mir::*;
105105
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
106106
use rustc_middle::ty::{self, Ty, TyCtxt};
107-
use rustc_mir_dataflow::impls::{MaybeStorageDead, always_storage_live_locals};
107+
use rustc_mir_dataflow::impls::MaybeUninitializedLocals;
108108
use rustc_mir_dataflow::{Analysis, ResultsCursor};
109109
use rustc_span::DUMMY_SP;
110110
use rustc_span::def_id::DefId;
@@ -145,16 +145,14 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
145145
// If we emit storage annotations, use `MaybeStorageDead` to check which reused locals
146146
// require storage removal (making them alive for the duration of the function).
147147
let storage_to_remove = if tcx.sess.emit_lifetime_markers() {
148-
let always_live_locals = always_storage_live_locals(body);
149-
150-
let maybe_storage_dead = MaybeStorageDead::new(Cow::Owned(always_live_locals))
151-
.iterate_to_fixpoint(tcx, body, None)
148+
let maybe_uninit = MaybeUninitializedLocals::new()
149+
.iterate_to_fixpoint(tcx, body, "mir_opt::gvn")
152150
.into_results_cursor(body);
153151

154152
let mut storage_checker = StorageChecker {
155153
storage_to_check: state.reused_locals.clone(),
156154
storage_to_remove: DenseBitSet::new_empty(body.local_decls.len()),
157-
maybe_storage_dead,
155+
maybe_uninit,
158156
};
159157

160158
storage_checker.visit_body(body);
@@ -1882,20 +1880,33 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
18821880
struct StorageChecker<'a, 'tcx> {
18831881
storage_to_check: DenseBitSet<Local>,
18841882
storage_to_remove: DenseBitSet<Local>,
1885-
maybe_storage_dead: ResultsCursor<'a, 'tcx, MaybeStorageDead<'a>>,
1883+
maybe_uninit: ResultsCursor<'a, 'tcx, MaybeUninitializedLocals>,
18861884
}
18871885

18881886
impl<'a, 'tcx> Visitor<'tcx> for StorageChecker<'a, 'tcx> {
18891887
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
1890-
if !context.is_use() {
1891-
return;
1888+
match context {
1889+
// These mutating uses do not require the local to be initialized.
1890+
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)
1891+
| PlaceContext::MutatingUse(MutatingUseContext::Call)
1892+
| PlaceContext::MutatingUse(MutatingUseContext::Store)
1893+
| PlaceContext::MutatingUse(MutatingUseContext::Yield)
1894+
| PlaceContext::NonUse(_) => {
1895+
return;
1896+
}
1897+
// Must check validity for other mutating usages and all non-mutating uses.
1898+
PlaceContext::MutatingUse(_) | PlaceContext::NonMutatingUse(_) => {}
18921899
}
18931900

18941901
if self.storage_to_check.contains(local) {
1895-
self.maybe_storage_dead.seek_after_primary_effect(location);
1896-
1897-
if self.maybe_storage_dead.get().contains(local) {
1898-
debug!(?location, ?local, "local is maybe dead in this location, removing storage");
1902+
self.maybe_uninit.seek_before_primary_effect(location);
1903+
1904+
if self.maybe_uninit.get().contains(local) {
1905+
debug!(
1906+
?location,
1907+
?local,
1908+
"local is maybe uninit in this location, removing storage"
1909+
);
18991910
self.storage_to_remove.insert(local);
19001911
self.storage_to_check.remove(local);
19011912
}

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@
7878
- _12 = AlignOf(());
7979
+ _11 = const 0_usize;
8080
+ _12 = const 1_usize;
81-
StorageLive(_14);
8281
StorageLive(_16);
83-
StorageLive(_17);
82+
StorageLive(_14);
8483
StorageLive(_19);
8584
_19 = const false;
8685
- switchInt(move _19) -> [0: bb6, otherwise: bb5];
@@ -103,15 +102,16 @@
103102
}
104103

105104
bb4: {
105+
StorageLive(_17);
106106
_17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>);
107107
StorageLive(_22);
108108
_22 = copy _17 as *mut [u8] (Transmute);
109109
_13 = copy _22 as *mut u8 (PtrToPtr);
110110
StorageDead(_22);
111-
StorageDead(_15);
112111
StorageDead(_17);
113-
StorageDead(_16);
112+
StorageDead(_15);
114113
StorageDead(_14);
114+
StorageDead(_16);
115115
_3 = ShallowInitBox(move _13, ());
116116
StorageDead(_13);
117117
StorageDead(_12);

tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@
7878
- _12 = AlignOf(());
7979
+ _11 = const 0_usize;
8080
+ _12 = const 1_usize;
81-
StorageLive(_14);
8281
StorageLive(_16);
83-
StorageLive(_17);
82+
StorageLive(_14);
8483
StorageLive(_19);
8584
_19 = const false;
8685
- switchInt(move _19) -> [0: bb6, otherwise: bb5];
@@ -103,15 +102,16 @@
103102
}
104103

105104
bb4: {
105+
StorageLive(_17);
106106
_17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>);
107107
StorageLive(_22);
108108
_22 = copy _17 as *mut [u8] (Transmute);
109109
_13 = copy _22 as *mut u8 (PtrToPtr);
110110
StorageDead(_22);
111-
StorageDead(_15);
112111
StorageDead(_17);
113-
StorageDead(_16);
112+
StorageDead(_15);
114113
StorageDead(_14);
114+
StorageDead(_16);
115115
_3 = ShallowInitBox(move _13, ());
116116
StorageDead(_13);
117117
StorageDead(_12);

tests/mir-opt/gvn_storage_twice.repeat_local_dead_live.GVN.diff

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
bb0: {
1010
_4 = [copy _3; 5];
1111
_5 = &_4[_1];
12-
StorageDead(_3);
13-
StorageLive(_3);
12+
- StorageDead(_3);
13+
- StorageLive(_3);
1414
- _0 = copy (*_5);
15+
+ nop;
16+
+ nop;
1517
+ _0 = copy _3;
1618
return;
1719
}

tests/mir-opt/gvn_storage_twice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn repeat_local_dead(_1: usize, _2: usize, _3: i32) -> i32 {
4343
}
4444
}
4545

46-
// Since _3 is uninitizaled when we access _5, GVN should _not_ optimze the code.
46+
// Since _3 is uninit due to storage when we access _5, GVN should remove the storage statements.
4747

4848
#[custom_mir(dialect = "runtime")]
4949
pub fn repeat_local_dead_live(_1: usize, _2: usize, _3: i32) -> i32 {

tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
3737
}
3838

3939
bb0: {
40-
StorageLive(_12);
4140
StorageLive(_11);
4241
StorageLive(_5);
43-
StorageLive(_6);
4442
StorageLive(_7);
43+
StorageLive(_6);
4544
StorageLive(_3);
4645
_3 = copy ((*_1).0: char);
4746
StorageLive(_4);
@@ -65,28 +64,29 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
6564
StorageDead(_8);
6665
_11 = Option::<std::cmp::Ordering>::Some(move _10);
6766
StorageDead(_10);
68-
StorageDead(_7);
6967
StorageDead(_6);
68+
StorageDead(_7);
7069
StorageDead(_5);
7170
goto -> bb3;
7271
}
7372

7473
bb2: {
7574
_11 = copy _6;
76-
StorageDead(_7);
7775
StorageDead(_6);
76+
StorageDead(_7);
7877
StorageDead(_5);
7978
goto -> bb3;
8079
}
8180

8281
bb3: {
82+
StorageLive(_12);
8383
_12 = move ((_11 as Some).0: std::cmp::Ordering);
8484
StorageLive(_13);
8585
_13 = discriminant(_12);
8686
_0 = Le(move _13, const 0_i8);
8787
StorageDead(_13);
88-
StorageDead(_11);
8988
StorageDead(_12);
89+
StorageDead(_11);
9090
return;
9191
}
9292
}

tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn <impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp(_1: &MultiField, _2: &M
2121
}
2222

2323
bb0: {
24+
StorageLive(_6);
2425
StorageLive(_3);
2526
_3 = copy ((*_1).0: char);
2627
StorageLive(_4);
@@ -53,6 +54,7 @@ fn <impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp(_1: &MultiField, _2: &M
5354
}
5455

5556
bb3: {
57+
StorageDead(_6);
5658
return;
5759
}
5860
}

tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,14 @@ fn int_range(_1: usize, _2: usize) -> () {
8989
bb3: {
9090
StorageDead(_7);
9191
StorageDead(_6);
92+
StorageLive(_11);
9293
_11 = copy (_4.0: usize);
9394
StorageLive(_12);
9495
_12 = AddUnchecked(copy _11, const 1_usize);
9596
(_4.0: usize) = move _12;
9697
StorageDead(_12);
9798
_13 = Option::<usize>::Some(copy _11);
99+
StorageDead(_11);
98100
StorageDead(_10);
99101
StorageLive(_14);
100102
_14 = copy ((_13 as Some).0: usize);

tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
5454
bb2: {
5555
StorageLive(_13);
5656
_5 = &mut _4;
57-
StorageLive(_8);
5857
StorageLive(_7);
5958
StorageLive(_6);
6059
_6 = &mut (_4.0: impl Iterator<Item = T>);
@@ -63,6 +62,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
6362

6463
bb3: {
6564
StorageDead(_6);
65+
StorageLive(_8);
6666
_8 = &mut (_4.1: impl Fn(T) -> U);
6767
StorageLive(_9);
6868
_9 = discriminant(_7);
@@ -71,8 +71,8 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
7171

7272
bb4: {
7373
StorageDead(_9);
74-
StorageDead(_7);
7574
StorageDead(_8);
75+
StorageDead(_7);
7676
StorageDead(_13);
7777
drop(_4) -> [return: bb5, unwind continue];
7878
}
@@ -97,8 +97,8 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
9797
StorageDead(_12);
9898
StorageDead(_10);
9999
StorageDead(_9);
100-
StorageDead(_7);
101100
StorageDead(_8);
101+
StorageDead(_7);
102102
StorageLive(_14);
103103
_14 = move ((_13 as Some).0: U);
104104
_15 = opaque::<U>(move _14) -> [return: bb8, unwind: bb10];

tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
3838
StorageLive(_11);
3939
StorageLive(_5);
4040
_5 = &raw mut (*_1);
41-
StorageLive(_8);
4241
StorageLive(_6);
4342
_6 = PtrMetadata(copy _1);
4443
_7 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(copy _3, copy _4, move _6) -> [return: bb1, unwind unreachable];
4544
}
4645

4746
bb1: {
4847
StorageDead(_6);
48+
StorageLive(_8);
4949
_8 = SubUnchecked(copy _4, copy _3);
5050
StorageLive(_9);
5151
_9 = copy _5 as *mut u32 (PtrToPtr);

tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
3838
StorageLive(_11);
3939
StorageLive(_5);
4040
_5 = &raw mut (*_1);
41-
StorageLive(_8);
4241
StorageLive(_6);
4342
_6 = PtrMetadata(copy _1);
4443
_7 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(copy _3, copy _4, move _6) -> [return: bb1, unwind unreachable];
4544
}
4645

4746
bb1: {
4847
StorageDead(_6);
48+
StorageLive(_8);
4949
_8 = SubUnchecked(copy _4, copy _3);
5050
StorageLive(_9);
5151
_9 = copy _5 as *mut u32 (PtrToPtr);

tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
3333
StorageLive(_4);
3434
_3 = move (_2.0: usize);
3535
_4 = move (_2.1: usize);
36-
StorageLive(_7);
3736
StorageLive(_5);
3837
_5 = PtrMetadata(copy _1);
3938
_6 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked::precondition_check(copy _3, copy _4, move _5) -> [return: bb1, unwind unreachable];
4039
}
4140

4241
bb1: {
4342
StorageDead(_5);
43+
StorageLive(_7);
4444
_7 = SubUnchecked(copy _4, copy _3);
4545
StorageLive(_8);
4646
_8 = copy _1 as *const u32 (PtrToPtr);

tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
3333
StorageLive(_4);
3434
_3 = move (_2.0: usize);
3535
_4 = move (_2.1: usize);
36-
StorageLive(_7);
3736
StorageLive(_5);
3837
_5 = PtrMetadata(copy _1);
3938
_6 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked::precondition_check(copy _3, copy _4, move _5) -> [return: bb1, unwind unreachable];
4039
}
4140

4241
bb1: {
4342
StorageDead(_5);
43+
StorageLive(_7);
4444
_7 = SubUnchecked(copy _4, copy _3);
4545
StorageLive(_8);
4646
_8 = copy _1 as *const u32 (PtrToPtr);

0 commit comments

Comments
 (0)