Stop counting opaques.

This commit is contained in:
Camille Gillot
2025-09-09 01:37:48 +00:00
parent 7f34f6e25f
commit 0a911ec97f
+24 -25
View File
@@ -100,7 +100,7 @@
use rustc_data_structures::graph::dominators::Dominators;
use rustc_hir::def::DefKind;
use rustc_index::bit_set::DenseBitSet;
use rustc_index::{Idx, IndexVec, newtype_index};
use rustc_index::{IndexVec, newtype_index};
use rustc_middle::bug;
use rustc_middle::mir::interpret::GlobalAlloc;
use rustc_middle::mir::visit::*;
@@ -158,11 +158,16 @@ fn is_required(&self) -> bool {
struct VnIndex {}
}
newtype_index! {
/// Counter type to ensure that all unique values are created using `insert_unique`.
#[debug_format = "_o{}"]
struct VnOpaque {
const DETERMINISTIC = 0;
#[derive(Copy, Clone, Debug, Eq)]
struct VnOpaque;
impl PartialEq for VnOpaque {
fn eq(&self, _: &VnOpaque) -> bool {
unreachable!()
}
}
impl Hash for VnOpaque {
fn hash<T: Hasher>(&self, _: &mut T) {
unreachable!()
}
}
@@ -183,8 +188,8 @@ enum Value<'tcx> {
value: Const<'tcx>,
/// Some constants do not have a deterministic value. To avoid merging two instances of the
/// same `Const`, we assign them an additional integer index.
// `disambiguator` is `DETERMINISTIC` iff the constant is deterministic.
disambiguator: VnOpaque,
// `disambiguator` is `None` iff the constant is deterministic.
disambiguator: Option<VnOpaque>,
},
/// An aggregate value, either tuple/closure/struct/enum.
/// This does not contain unions, as we cannot reason with the value.
@@ -234,8 +239,6 @@ struct ValueSet<'tcx> {
hashes: IndexVec<VnIndex, u64>,
values: IndexVec<VnIndex, Value<'tcx>>,
types: IndexVec<VnIndex, Ty<'tcx>>,
/// Counter to generate different values.
next_opaque: VnOpaque,
}
impl<'tcx> ValueSet<'tcx> {
@@ -245,8 +248,6 @@ fn new(num_values: usize) -> ValueSet<'tcx> {
hashes: IndexVec::with_capacity(num_values),
values: IndexVec::with_capacity(num_values),
types: IndexVec::with_capacity(num_values),
// The first opaque is 1, as 0 means deterministic constant.
next_opaque: VnOpaque::from_u32(1),
}
}
@@ -257,12 +258,11 @@ fn insert_unique(
ty: Ty<'tcx>,
value: impl FnOnce(VnOpaque) -> Value<'tcx>,
) -> VnIndex {
let value = value(self.next_opaque);
self.next_opaque.increment_by(1);
let value = value(VnOpaque);
debug_assert!(match value {
Value::Opaque(_) | Value::Address { .. } => true,
Value::Constant { disambiguator, .. } => disambiguator != DETERMINISTIC,
Value::Constant { disambiguator, .. } => disambiguator.is_some(),
_ => false,
});
@@ -280,7 +280,7 @@ fn insert_unique(
fn insert(&mut self, ty: Ty<'tcx>, value: Value<'tcx>) -> (VnIndex, bool) {
debug_assert!(match value {
Value::Opaque(_) | Value::Address { .. } => false,
Value::Constant { disambiguator, .. } => disambiguator == DETERMINISTIC,
Value::Constant { disambiguator, .. } => disambiguator.is_none(),
_ => true,
});
@@ -325,8 +325,7 @@ fn ty(&self, index: VnIndex) -> Ty<'tcx> {
/// Replace the value associated with `index` with an opaque value.
#[inline]
fn forget(&mut self, index: VnIndex) {
self.values[index] = Value::Opaque(self.next_opaque);
self.next_opaque.increment_by(1);
self.values[index] = Value::Opaque(VnOpaque);
}
}
@@ -436,14 +435,14 @@ fn new_pointer(&mut self, place: Place<'tcx>, kind: AddressKind) -> VnIndex {
fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex {
let (index, new) = if value.is_deterministic() {
// The constant is deterministic, no need to disambiguate.
let constant = Value::Constant { value, disambiguator: DETERMINISTIC };
let constant = Value::Constant { value, disambiguator: None };
self.values.insert(value.ty(), constant)
} else {
// Multiple mentions of this constant will yield different values,
// so assign a different `disambiguator` to ensure they do not get the same `VnIndex`.
let index = self.values.insert_unique(value.ty(), |disambiguator| {
debug_assert_ne!(disambiguator, DETERMINISTIC);
Value::Constant { value, disambiguator }
let index = self.values.insert_unique(value.ty(), |disambiguator| Value::Constant {
value,
disambiguator: Some(disambiguator),
});
(index, true)
};
@@ -479,14 +478,14 @@ fn insert_bool(&mut self, flag: bool) -> VnIndex {
// Booleans are deterministic.
let value = Const::from_bool(self.tcx, flag);
debug_assert!(value.is_deterministic());
self.insert(self.tcx.types.bool, Value::Constant { value, disambiguator: DETERMINISTIC })
self.insert(self.tcx.types.bool, Value::Constant { value, disambiguator: None })
}
fn insert_scalar(&mut self, ty: Ty<'tcx>, scalar: Scalar) -> VnIndex {
// Scalars are deterministic.
let value = Const::from_scalar(self.tcx, scalar, ty);
debug_assert!(value.is_deterministic());
self.insert(ty, Value::Constant { value, disambiguator: DETERMINISTIC })
self.insert(ty, Value::Constant { value, disambiguator: None })
}
fn insert_tuple(&mut self, ty: Ty<'tcx>, values: Vec<VnIndex>) -> VnIndex {
@@ -1731,7 +1730,7 @@ fn try_as_constant(&mut self, index: VnIndex) -> Option<ConstOperand<'tcx>> {
// This was already constant in MIR, do not change it. If the constant is not
// deterministic, adding an additional mention of it in MIR will not give the same value as
// the former mention.
if let Value::Constant { value, disambiguator: DETERMINISTIC } = *self.get(index) {
if let Value::Constant { value, disambiguator: None } = *self.get(index) {
debug_assert!(value.is_deterministic());
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
}