Skip to content

Commit ec504de

Browse files
committed
Auto merge of #57442 - oli-obk:lazy_const, r=RalfJung
Simplify `ConstValue::ScalarPair` While looking at #57432 I realized that some of our types for representing constants are very big. This reduces `LazyConst` to 3/4th of its original size and simplifies some code around slices at the same time. r? @RalfJung
2 parents da6ab95 + fe50b4e commit ec504de

File tree

14 files changed

+71
-80
lines changed

14 files changed

+71
-80
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ impl_stable_hash_for!(struct ty::FieldDef {
302302
impl_stable_hash_for!(
303303
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
304304
Scalar(val),
305-
ScalarPair(a, b),
305+
Slice(a, b),
306306
ByRef(id, alloc, offset),
307307
}
308308
);

src/librustc/mir/interpret/pointer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub struct Pointer<Tag=(),Id=AllocId> {
7676
pub tag: Tag,
7777
}
7878

79+
static_assert!(POINTER_SIZE: ::std::mem::size_of::<Pointer>() == 16);
80+
7981
/// Produces a `Pointer` which points to the beginning of the Allocation
8082
impl From<AllocId> for Pointer {
8183
#[inline(always)]

src/librustc/mir/interpret/value.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,28 @@ pub enum ConstValue<'tcx> {
2222
/// Not using the enum `Value` to encode that this must not be `Undef`
2323
Scalar(Scalar),
2424

25-
/// Used only for *fat pointers* with layout::abi::ScalarPair
25+
/// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box<str>`, ...)
2626
///
27-
/// Needed for pattern matching code related to slices and strings.
28-
ScalarPair(Scalar, Scalar),
27+
/// Empty slices don't necessarily have an address backed by an `AllocId`, thus we also need to
28+
/// enable integer pointers. The `Scalar` type covers exactly those two cases. While we could
29+
/// create dummy-`AllocId`s, the additional code effort for the conversions doesn't seem worth
30+
/// it.
31+
Slice(Scalar, u64),
2932

3033
/// An allocation + offset into the allocation.
3134
/// Invariant: The AllocId matches the allocation.
3235
ByRef(AllocId, &'tcx Allocation, Size),
3336
}
3437

38+
#[cfg(target_arch = "x86_64")]
39+
static_assert!(CONST_SIZE: ::std::mem::size_of::<ConstValue<'static>>() == 40);
40+
3541
impl<'tcx> ConstValue<'tcx> {
3642
#[inline]
3743
pub fn try_to_scalar(&self) -> Option<Scalar> {
3844
match *self {
3945
ConstValue::ByRef(..) |
40-
ConstValue::ScalarPair(..) => None,
46+
ConstValue::Slice(..) => None,
4147
ConstValue::Scalar(val) => Some(val),
4248
}
4349
}
@@ -56,17 +62,8 @@ impl<'tcx> ConstValue<'tcx> {
5662
pub fn new_slice(
5763
val: Scalar,
5864
len: u64,
59-
cx: &impl HasDataLayout
6065
) -> Self {
61-
ConstValue::ScalarPair(val, Scalar::Bits {
62-
bits: len as u128,
63-
size: cx.data_layout().pointer_size.bytes() as u8,
64-
})
65-
}
66-
67-
#[inline]
68-
pub fn new_dyn_trait(val: Scalar, vtable: Pointer) -> Self {
69-
ConstValue::ScalarPair(val, Scalar::Ptr(vtable))
66+
ConstValue::Slice(val, len)
7067
}
7168
}
7269

@@ -90,6 +87,9 @@ pub enum Scalar<Tag=(), Id=AllocId> {
9087
Ptr(Pointer<Tag, Id>),
9188
}
9289

90+
#[cfg(target_arch = "x86_64")]
91+
static_assert!(SCALAR_SIZE: ::std::mem::size_of::<Scalar>() == 24);
92+
9393
impl<Tag> fmt::Display for Scalar<Tag> {
9494
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9595
match self {

src/librustc/mir/mod.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,23 +2702,21 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
27022702
return write!(f, "{}", item_path_str(did));
27032703
}
27042704
// print string literals
2705-
if let ConstValue::ScalarPair(ptr, len) = value {
2705+
if let ConstValue::Slice(ptr, len) = value {
27062706
if let Scalar::Ptr(ptr) = ptr {
2707-
if let Scalar::Bits { bits: len, .. } = len {
2708-
if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
2709-
return ty::tls::with(|tcx| {
2710-
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
2711-
if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
2712-
assert_eq!(len as usize as u128, len);
2713-
let slice =
2714-
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
2715-
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
2716-
write!(f, "{:?}", s)
2717-
} else {
2718-
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
2719-
}
2720-
});
2721-
}
2707+
if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
2708+
return ty::tls::with(|tcx| {
2709+
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
2710+
if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
2711+
assert_eq!(len as usize as u64, len);
2712+
let slice =
2713+
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
2714+
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
2715+
write!(f, "{:?}", s)
2716+
} else {
2717+
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
2718+
}
2719+
});
27222720
}
27232721
}
27242722
}

src/librustc/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,7 @@ macro_rules! nop_list_lift {
17671767
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
17681768
type Lifted = &'tcx List<$lifted>;
17691769
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
1770-
if self.is_empty() {
1770+
if self.is_empty() {
17711771
return Some(List::empty());
17721772
}
17731773
if tcx.interners.arena.in_arena(*self as *const _) {

src/librustc/ty/structural_impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
498498
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
499499
match *self {
500500
ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
501-
ConstValue::ScalarPair(x, y) => Some(ConstValue::ScalarPair(x, y)),
501+
ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
502502
ConstValue::ByRef(x, alloc, z) => Some(ConstValue::ByRef(
503503
x, alloc.lift_to_tcx(tcx)?, z,
504504
)),

src/librustc/ty/sty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,9 @@ pub enum LazyConst<'tcx> {
20632063
Evaluated(Const<'tcx>),
20642064
}
20652065

2066+
#[cfg(target_arch = "x86_64")]
2067+
static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::<LazyConst<'static>>() == 56);
2068+
20662069
impl<'tcx> LazyConst<'tcx> {
20672070
pub fn map_evaluated<R>(self, f: impl FnOnce(Const<'tcx>) -> Option<R>) -> Option<R> {
20682071
match self {
@@ -2089,6 +2092,9 @@ pub struct Const<'tcx> {
20892092
pub val: ConstValue<'tcx>,
20902093
}
20912094

2095+
#[cfg(target_arch = "x86_64")]
2096+
static_assert!(CONST_SIZE: ::std::mem::size_of::<Const<'static>>() == 48);
2097+
20922098
impl<'tcx> Const<'tcx> {
20932099
#[inline]
20942100
pub fn from_scalar(

src/librustc_codegen_ssa/mir/operand.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,17 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
8888
);
8989
OperandValue::Immediate(llval)
9090
},
91-
ConstValue::ScalarPair(a, b) => {
92-
let (a_scalar, b_scalar) = match layout.abi {
93-
layout::Abi::ScalarPair(ref a, ref b) => (a, b),
91+
ConstValue::Slice(a, b) => {
92+
let a_scalar = match layout.abi {
93+
layout::Abi::ScalarPair(ref a, _) => a,
9494
_ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout)
9595
};
9696
let a_llval = bx.cx().scalar_to_backend(
9797
a,
9898
a_scalar,
9999
bx.cx().scalar_pair_element_backend_type(layout, 0, true),
100100
);
101-
let b_llval = bx.cx().scalar_to_backend(
102-
b,
103-
b_scalar,
104-
bx.cx().scalar_pair_element_backend_type(layout, 1, true),
105-
);
101+
let b_llval = bx.cx().const_usize(b);
106102
OperandValue::Pair(a_llval, b_llval)
107103
},
108104
ConstValue::ByRef(_, alloc, offset) => {

src/librustc_mir/const_eval.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,11 @@ pub fn op_to_const<'tcx>(
6767
op: OpTy<'tcx>,
6868
may_normalize: bool,
6969
) -> EvalResult<'tcx, ty::Const<'tcx>> {
70-
// We do not normalize just any data. Only scalar layout and fat pointers.
70+
// We do not normalize just any data. Only scalar layout and slices.
7171
let normalize = may_normalize
7272
&& match op.layout.abi {
7373
layout::Abi::Scalar(..) => true,
74-
layout::Abi::ScalarPair(..) => {
75-
// Must be a fat pointer
76-
op.layout.ty.builtin_deref(true).is_some()
77-
},
74+
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
7875
_ => false,
7976
};
8077
let normalized_op = if normalize {
@@ -103,7 +100,7 @@ pub fn op_to_const<'tcx>(
103100
Ok(Immediate::Scalar(x)) =>
104101
ConstValue::Scalar(x.not_undef()?),
105102
Ok(Immediate::ScalarPair(a, b)) =>
106-
ConstValue::ScalarPair(a.not_undef()?, b.not_undef()?),
103+
ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
107104
};
108105
Ok(ty::Const { val, ty: op.layout.ty })
109106
}

src/librustc_mir/hair/constant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
3535
LitKind::Str(ref s, _) => {
3636
let s = s.as_str();
3737
let id = tcx.allocate_bytes(s.as_bytes());
38-
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
38+
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64)
3939
},
4040
LitKind::Err(ref s) => {
4141
let s = s.as_str();
4242
let id = tcx.allocate_bytes(s.as_bytes());
4343
return Ok(ty::Const {
44-
val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx),
44+
val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64),
4545
ty: tcx.types.err,
4646
});
4747
},

0 commit comments

Comments
 (0)