Skip to content

Commit 17e3e9c

Browse files
committed
Do not hash opaques in GVN.
1 parent 6c108aa commit 17e3e9c

File tree

1 file changed

+72
-37
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+72
-37
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,17 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
153153
}
154154

155155
newtype_index! {
156+
#[debug_format = "_v{}"]
156157
struct VnIndex {}
157158
}
158159

160+
newtype_index! {
161+
#[debug_format = "_o{}"]
162+
struct VnOpaque {}
163+
}
164+
165+
const DETERMINISTIC: VnOpaque = VnOpaque::MAX;
166+
159167
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
160168
enum AddressKind {
161169
Ref(BorrowKind),
@@ -167,14 +175,14 @@ enum Value<'tcx> {
167175
// Root values.
168176
/// Used to represent values we know nothing about.
169177
/// The `usize` is a counter incremented by `new_opaque`.
170-
Opaque(usize),
178+
Opaque(VnOpaque),
171179
/// Evaluated or unevaluated constant value.
172180
Constant {
173181
value: Const<'tcx>,
174182
/// Some constants do not have a deterministic value. To avoid merging two instances of the
175183
/// same `Const`, we assign them an additional integer index.
176-
// `disambiguator` is 0 iff the constant is deterministic.
177-
disambiguator: usize,
184+
// `disambiguator` is `DETERMINISTIC` iff the constant is deterministic.
185+
disambiguator: VnOpaque,
178186
},
179187
/// An aggregate value, either tuple/closure/struct/enum.
180188
/// This does not contain unions, as we cannot reason with the value.
@@ -193,7 +201,7 @@ enum Value<'tcx> {
193201
place: Place<'tcx>,
194202
kind: AddressKind,
195203
/// Give each borrow and pointer a different provenance, so we don't merge them.
196-
provenance: usize,
204+
provenance: VnOpaque,
197205
},
198206

199207
// Extractions.
@@ -219,8 +227,7 @@ struct ValueSet<'tcx> {
219227
hashes: IndexVec<VnIndex, u64>,
220228
values: IndexVec<VnIndex, Value<'tcx>>,
221229
types: IndexVec<VnIndex, Ty<'tcx>>,
222-
/// Counter to generate different values.
223-
next_opaque: usize,
230+
opaques: IndexVec<VnOpaque, VnIndex>,
224231
}
225232

226233
impl<'tcx> ValueSet<'tcx> {
@@ -230,10 +237,25 @@ impl<'tcx> ValueSet<'tcx> {
230237
hashes: IndexVec::with_capacity(num_values),
231238
values: IndexVec::with_capacity(num_values),
232239
types: IndexVec::with_capacity(num_values),
233-
next_opaque: 1,
240+
opaques: IndexVec::with_capacity(num_values),
234241
}
235242
}
236243

244+
#[inline]
245+
fn insert_unique(
246+
&mut self,
247+
ty: Ty<'tcx>,
248+
value: impl FnOnce(VnOpaque) -> Value<'tcx>,
249+
) -> VnIndex {
250+
let index = self.hashes.push(0);
251+
let _index = self.types.push(ty);
252+
debug_assert_eq!(index, _index);
253+
let opaque = self.opaques.push(index);
254+
let _index = self.values.push(value(opaque));
255+
debug_assert_eq!(index, _index);
256+
index
257+
}
258+
237259
#[allow(rustc::pass_by_value)]
238260
fn insert(&mut self, value: Value<'tcx>, ty: Ty<'tcx>) -> (VnIndex, bool) {
239261
let hash: u64 = {
@@ -262,13 +284,6 @@ impl<'tcx> ValueSet<'tcx> {
262284
}
263285
}
264286

265-
#[inline]
266-
fn next_opaque(&mut self) -> usize {
267-
let next_opaque = self.next_opaque;
268-
self.next_opaque += 1;
269-
next_opaque
270-
}
271-
272287
#[inline]
273288
fn value(&self, index: VnIndex) -> &Value<'tcx> {
274289
&self.values[index]
@@ -281,7 +296,7 @@ impl<'tcx> ValueSet<'tcx> {
281296

282297
#[inline]
283298
fn forget(&mut self, index: VnIndex) {
284-
let opaque = self.next_opaque();
299+
let opaque = self.opaques.push(index);
285300
self.values[index] = Value::Opaque(opaque);
286301
}
287302
}
@@ -360,8 +375,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
360375
/// from all the others.
361376
#[instrument(level = "trace", skip(self), ret)]
362377
fn new_opaque(&mut self, ty: Ty<'tcx>) -> VnIndex {
363-
let value = Value::Opaque(self.values.next_opaque());
364-
self.insert(ty, value)
378+
let index = self.values.insert_unique(ty, Value::Opaque);
379+
let _index = self.evaluated.push(None);
380+
debug_assert_eq!(index, _index);
381+
let _index = self.rev_locals.push(SmallVec::new());
382+
debug_assert_eq!(index, _index);
383+
index
365384
}
366385

367386
/// Create a new `Value::Address` distinct from all the others.
@@ -374,8 +393,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
374393
}
375394
AddressKind::Address(mutbl) => Ty::new_ptr(self.tcx, pty, mutbl.to_mutbl_lossy()),
376395
};
377-
let value = Value::Address { place, kind, provenance: self.values.next_opaque() };
378-
self.insert(ty, value)
396+
let index =
397+
self.values.insert_unique(ty, |provenance| Value::Address { place, kind, provenance });
398+
let evaluated = self.eval_to_const(index);
399+
let _index = self.evaluated.push(evaluated);
400+
debug_assert_eq!(index, _index);
401+
let _index = self.rev_locals.push(SmallVec::new());
402+
debug_assert_eq!(index, _index);
403+
index
404+
}
405+
406+
#[instrument(level = "trace", skip(self), ret)]
407+
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
408+
let (index, new) = if value.is_deterministic() {
409+
// The constant is deterministic, no need to disambiguate.
410+
let constant = Value::Constant { value, disambiguator: DETERMINISTIC };
411+
self.values.insert(constant, value.ty())
412+
} else {
413+
// Multiple mentions of this constant will yield different values,
414+
// so assign a different `disambiguator` to ensure they do not get the same `VnIndex`.
415+
let index = self.values.insert_unique(value.ty(), |disambiguator| {
416+
debug_assert_ne!(disambiguator, DETERMINISTIC);
417+
Value::Constant { value, disambiguator }
418+
});
419+
(index, true)
420+
};
421+
if new {
422+
let evaluated = self.eval_to_const(index);
423+
let _index = self.evaluated.push(evaluated);
424+
debug_assert_eq!(index, _index);
425+
let _index = self.rev_locals.push(SmallVec::new());
426+
debug_assert_eq!(index, _index);
427+
}
428+
index
379429
}
380430

381431
#[inline]
@@ -396,33 +446,18 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
396446
self.rev_locals[value].push(local);
397447
}
398448

399-
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
400-
let disambiguator = if value.is_deterministic() {
401-
// The constant is deterministic, no need to disambiguate.
402-
0
403-
} else {
404-
// Multiple mentions of this constant will yield different values,
405-
// so assign a different `disambiguator` to ensure they do not get the same `VnIndex`.
406-
let disambiguator = self.values.next_opaque();
407-
// `disambiguator: 0` means deterministic.
408-
debug_assert_ne!(disambiguator, 0);
409-
disambiguator
410-
};
411-
self.insert(value.ty(), Value::Constant { value, disambiguator })
412-
}
413-
414449
fn insert_bool(&mut self, flag: bool) -> VnIndex {
415450
// Booleans are deterministic.
416451
let value = Const::from_bool(self.tcx, flag);
417452
debug_assert!(value.is_deterministic());
418-
self.insert(self.tcx.types.bool, Value::Constant { value, disambiguator: 0 })
453+
self.insert(self.tcx.types.bool, Value::Constant { value, disambiguator: DETERMINISTIC })
419454
}
420455

421456
fn insert_scalar(&mut self, ty: Ty<'tcx>, scalar: Scalar) -> VnIndex {
422457
// Scalars are deterministic.
423458
let value = Const::from_scalar(self.tcx, scalar, ty);
424459
debug_assert!(value.is_deterministic());
425-
self.insert(ty, Value::Constant { value, disambiguator: 0 })
460+
self.insert(ty, Value::Constant { value, disambiguator: DETERMINISTIC })
426461
}
427462

428463
fn insert_tuple(&mut self, ty: Ty<'tcx>, values: Vec<VnIndex>) -> VnIndex {
@@ -1678,7 +1713,7 @@ impl<'tcx> VnState<'_, 'tcx> {
16781713
// This was already constant in MIR, do not change it. If the constant is not
16791714
// deterministic, adding an additional mention of it in MIR will not give the same value as
16801715
// the former mention.
1681-
if let Value::Constant { value, disambiguator: 0 } = *self.get(index) {
1716+
if let Value::Constant { value, disambiguator: DETERMINISTIC } = *self.get(index) {
16821717
debug_assert!(value.is_deterministic());
16831718
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
16841719
}

0 commit comments

Comments
 (0)