Skip to content

Commit a7c8edd

Browse files
committed
Invalidate all dereferences
1 parent a60983c commit a7c8edd

File tree

4 files changed

+62
-60
lines changed

4 files changed

+62
-60
lines changed

compiler/rustc_data_structures/src/fx.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
99
pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
1010
pub type IndexOccupiedEntry<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>;
1111

12+
pub use indexmap::set::MutableValues;
13+
1214
#[macro_export]
1315
macro_rules! define_id_collections {
1416
($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {

compiler/rustc_mir_transform/src/gvn.rs

+32-8
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ use rustc_const_eval::interpret::{
9393
ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
9494
intern_const_alloc_for_constprop,
9595
};
96-
use rustc_data_structures::fx::FxIndexSet;
96+
use rustc_data_structures::fx::{FxIndexSet, MutableValues};
9797
use rustc_data_structures::graph::dominators::Dominators;
9898
use rustc_hir::def::DefKind;
9999
use rustc_index::bit_set::BitSet;
@@ -235,6 +235,8 @@ struct VnState<'body, 'tcx> {
235235
evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
236236
/// Counter to generate different values.
237237
next_opaque: usize,
238+
/// Cache the deref values.
239+
derefs: Vec<VnIndex>,
238240
/// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
239241
feature_unsized_locals: bool,
240242
ssa: &'body SsaLocals,
@@ -268,6 +270,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
268270
values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()),
269271
evaluated: IndexVec::with_capacity(num_values),
270272
next_opaque: 1,
273+
derefs: Vec::new(),
271274
feature_unsized_locals: tcx.features().unsized_locals(),
272275
ssa,
273276
dominators,
@@ -362,6 +365,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
362365
self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
363366
}
364367

368+
fn insert_deref(&mut self, value: VnIndex) -> VnIndex {
369+
let value = self.insert(Value::Projection(value, ProjectionElem::Deref));
370+
self.derefs.push(value);
371+
value
372+
}
373+
374+
fn invalidate_derefs(&mut self) {
375+
let mut derefs = Vec::new();
376+
std::mem::swap(&mut derefs, &mut self.derefs);
377+
for deref in derefs {
378+
let opaque = self.next_opaque();
379+
*self.values.get_index_mut2(deref.index()).unwrap() = Value::Opaque(opaque);
380+
}
381+
}
382+
365383
#[instrument(level = "trace", skip(self), ret)]
366384
fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
367385
use Value::*;
@@ -620,7 +638,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
620638
{
621639
// An immutable borrow `_x` always points to the same value for the
622640
// lifetime of the borrow, so we can merge all instances of `*_x`.
623-
ProjectionElem::Deref
641+
return Some(self.insert_deref(value));
624642
} else {
625643
return None;
626644
}
@@ -1621,6 +1639,8 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
16211639
self.assign(local, value);
16221640
Some(value)
16231641
} else {
1642+
// Non-local assignments maybe invalidate deref.
1643+
self.invalidate_derefs();
16241644
value
16251645
};
16261646
let Some(value) = value else { return };
@@ -1640,12 +1660,16 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
16401660
}
16411661

16421662
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
1643-
if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator
1644-
&& let Some(local) = destination.as_local()
1645-
&& self.ssa.is_ssa(local)
1646-
{
1647-
let opaque = self.new_opaque();
1648-
self.assign(local, opaque);
1663+
if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator {
1664+
if let Some(local) = destination.as_local()
1665+
&& self.ssa.is_ssa(local)
1666+
{
1667+
let opaque = self.new_opaque();
1668+
self.assign(local, opaque);
1669+
}
1670+
// Function calls maybe invalidate nested deref, and non-local assignments maybe invalidate deref.
1671+
// Currently, no distinction is made between these two cases.
1672+
self.invalidate_derefs();
16491673
}
16501674
self.super_terminator(terminator, location);
16511675
}

tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff

+10-20
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,18 @@
107107
StorageLive(_18);
108108
_18 = &(*_1);
109109
StorageLive(_19);
110-
- StorageLive(_20);
111-
+ nop;
110+
StorageLive(_20);
112111
_20 = copy (*_18);
113-
- _19 = opaque::<u32>(move _20) -> [return: bb7, unwind continue];
114-
+ _19 = opaque::<u32>(copy _20) -> [return: bb7, unwind continue];
112+
_19 = opaque::<u32>(move _20) -> [return: bb7, unwind continue];
115113
}
116114

117115
bb7: {
118-
- StorageDead(_20);
119-
+ nop;
116+
StorageDead(_20);
120117
StorageDead(_19);
121118
StorageLive(_21);
122119
StorageLive(_22);
123-
- _22 = copy (*_18);
124-
- _21 = opaque::<u32>(move _22) -> [return: bb8, unwind continue];
125-
+ _22 = copy _20;
126-
+ _21 = opaque::<u32>(copy _20) -> [return: bb8, unwind continue];
120+
_22 = copy (*_18);
121+
_21 = opaque::<u32>(move _22) -> [return: bb8, unwind continue];
127122
}
128123

129124
bb8: {
@@ -157,23 +152,18 @@
157152
StorageDead(_28);
158153
StorageDead(_27);
159154
StorageLive(_29);
160-
- StorageLive(_30);
161-
+ nop;
155+
StorageLive(_30);
162156
_30 = copy ((*_3).0: u32);
163-
- _29 = opaque::<u32>(move _30) -> [return: bb12, unwind continue];
164-
+ _29 = opaque::<u32>(copy _30) -> [return: bb12, unwind continue];
157+
_29 = opaque::<u32>(move _30) -> [return: bb12, unwind continue];
165158
}
166159

167160
bb12: {
168-
- StorageDead(_30);
169-
+ nop;
161+
StorageDead(_30);
170162
StorageDead(_29);
171163
StorageLive(_31);
172164
StorageLive(_32);
173-
- _32 = copy ((*_3).0: u32);
174-
- _31 = opaque::<u32>(move _32) -> [return: bb13, unwind continue];
175-
+ _32 = copy _30;
176-
+ _31 = opaque::<u32>(copy _30) -> [return: bb13, unwind continue];
165+
_32 = copy ((*_3).0: u32);
166+
_31 = opaque::<u32>(move _32) -> [return: bb13, unwind continue];
177167
}
178168

179169
bb13: {

tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff

+18-32
Original file line numberDiff line numberDiff line change
@@ -758,39 +758,32 @@
758758
StorageLive(_126);
759759
_126 = &_3;
760760
StorageLive(_127);
761-
- StorageLive(_128);
762-
- StorageLive(_129);
763-
+ nop;
764-
+ nop;
761+
StorageLive(_128);
762+
StorageLive(_129);
765763
_129 = copy (*_126);
766764
StorageLive(_130);
767765
_130 = copy _1;
768766
- _128 = Add(move _129, move _130);
769-
+ _128 = Add(copy _129, copy _1);
767+
+ _128 = Add(move _129, copy _1);
770768
StorageDead(_130);
771-
- StorageDead(_129);
772-
- _127 = opaque::<u64>(move _128) -> [return: bb35, unwind continue];
773-
+ nop;
774-
+ _127 = opaque::<u64>(copy _128) -> [return: bb35, unwind continue];
769+
StorageDead(_129);
770+
_127 = opaque::<u64>(move _128) -> [return: bb35, unwind continue];
775771
}
776772

777773
bb35: {
778-
- StorageDead(_128);
779-
+ nop;
774+
StorageDead(_128);
780775
StorageDead(_127);
781776
StorageLive(_131);
782777
StorageLive(_132);
783778
StorageLive(_133);
784-
- _133 = copy (*_126);
785-
+ _133 = copy _129;
779+
_133 = copy (*_126);
786780
StorageLive(_134);
787781
_134 = copy _1;
788782
- _132 = Add(move _133, move _134);
789-
+ _132 = copy _128;
783+
+ _132 = Add(move _133, copy _1);
790784
StorageDead(_134);
791785
StorageDead(_133);
792-
- _131 = opaque::<u64>(move _132) -> [return: bb36, unwind continue];
793-
+ _131 = opaque::<u64>(copy _128) -> [return: bb36, unwind continue];
786+
_131 = opaque::<u64>(move _132) -> [return: bb36, unwind continue];
794787
}
795788

796789
bb36: {
@@ -906,39 +899,32 @@
906899
StorageLive(_163);
907900
_163 = &_3;
908901
StorageLive(_164);
909-
- StorageLive(_165);
910-
- StorageLive(_166);
911-
+ nop;
912-
+ nop;
902+
StorageLive(_165);
903+
StorageLive(_166);
913904
_166 = copy (*_163);
914905
StorageLive(_167);
915906
_167 = copy _1;
916907
- _165 = Add(move _166, move _167);
917-
+ _165 = Add(copy _166, copy _1);
908+
+ _165 = Add(move _166, copy _1);
918909
StorageDead(_167);
919-
- StorageDead(_166);
920-
- _164 = opaque::<u64>(move _165) -> [return: bb43, unwind continue];
921-
+ nop;
922-
+ _164 = opaque::<u64>(copy _165) -> [return: bb43, unwind continue];
910+
StorageDead(_166);
911+
_164 = opaque::<u64>(move _165) -> [return: bb43, unwind continue];
923912
}
924913

925914
bb43: {
926-
- StorageDead(_165);
927-
+ nop;
915+
StorageDead(_165);
928916
StorageDead(_164);
929917
StorageLive(_168);
930918
StorageLive(_169);
931919
StorageLive(_170);
932-
- _170 = copy (*_163);
933-
+ _170 = copy _166;
920+
_170 = copy (*_163);
934921
StorageLive(_171);
935922
_171 = copy _1;
936923
- _169 = Add(move _170, move _171);
937-
+ _169 = copy _165;
924+
+ _169 = Add(move _170, copy _1);
938925
StorageDead(_171);
939926
StorageDead(_170);
940-
- _168 = opaque::<u64>(move _169) -> [return: bb44, unwind continue];
941-
+ _168 = opaque::<u64>(copy _165) -> [return: bb44, unwind continue];
927+
_168 = opaque::<u64>(move _169) -> [return: bb44, unwind continue];
942928
}
943929

944930
bb44: {

0 commit comments

Comments
 (0)