Skip to content

Commit 75f1db1

Browse files
committed
Auto merge of #77227 - oli-obk:const_val_🌳_prelude, r=RalfJung
Refactorings in preparation for const value trees cc #72396 This PR changes the `Scalar::Bits { data: u128, size: u8 }` variant to `Scalar::Bits(ScalarInt)` where `ScalarInt` contains the same information, but is `repr(packed)`. The reason for using a packed struct is to allow enum variant packing to keep the original size of `Scalar` instead of adding another word to its size due to padding. Other than that the PR just gets rid of all the inspection of the internal fields of `Scalar::Bits` which were frankly scary. These fields have invariants that we need to uphold and we can't do that without making the fields private. r? `@ghost`
2 parents 601c13c + 332750f commit 75f1db1

File tree

36 files changed

+472
-292
lines changed

36 files changed

+472
-292
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ fn codegen_stmt<'tcx>(
499499
UnOp::Neg => match layout.ty.kind() {
500500
ty::Int(IntTy::I128) => {
501501
// FIXME remove this case once ineg.i128 works
502-
let zero = CValue::const_val(fx, layout, 0);
502+
let zero = CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
503503
crate::num::codegen_int_binop(fx, BinOp::Sub, zero, operand)
504504
}
505505
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
@@ -585,13 +585,11 @@ fn codegen_stmt<'tcx>(
585585
.discriminant_for_variant(fx.tcx, *index)
586586
.unwrap();
587587
let discr = if discr.ty.is_signed() {
588-
rustc_middle::mir::interpret::sign_extend(
589-
discr.val,
590-
fx.layout_of(discr.ty).size,
591-
)
588+
fx.layout_of(discr.ty).size.sign_extend(discr.val)
592589
} else {
593590
discr.val
594591
};
592+
let discr = discr.into();
595593

596594
let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr);
597595
lval.write_cvalue(fx, discr);

compiler/rustc_codegen_cranelift/src/constant.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,8 @@ pub(crate) fn codegen_const_value<'tcx>(
186186
}
187187

188188
match x {
189-
Scalar::Raw { data, size } => {
190-
assert_eq!(u64::from(size), layout.size.bytes());
191-
CValue::const_val(fx, layout, data)
189+
Scalar::Int(int) => {
190+
CValue::const_val(fx, layout, int)
192191
}
193192
Scalar::Ptr(ptr) => {
194193
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);

compiler/rustc_codegen_cranelift/src/discriminant.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
3030
.ty
3131
.discriminant_for_variant(fx.tcx, variant_index)
3232
.unwrap()
33-
.val;
33+
.val
34+
.into();
3435
let discr = CValue::const_val(fx, ptr.layout(), to);
3536
ptr.write_cvalue(fx, discr);
3637
}
@@ -49,7 +50,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
4950
let niche = place.place_field(fx, mir::Field::new(tag_field));
5051
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
5152
let niche_value = u128::from(niche_value).wrapping_add(niche_start);
52-
let niche_llval = CValue::const_val(fx, niche.layout(), niche_value);
53+
let niche_llval = CValue::const_val(fx, niche.layout(), niche_value.into());
5354
niche.write_cvalue(fx, niche_llval);
5455
}
5556
}
@@ -77,7 +78,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
7778
.ty
7879
.discriminant_for_variant(fx.tcx, *index)
7980
.map_or(u128::from(index.as_u32()), |discr| discr.val);
80-
return CValue::const_val(fx, dest_layout, discr_val);
81+
return CValue::const_val(fx, dest_layout, discr_val.into());
8182
}
8283
Variants::Multiple {
8384
tag,

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,8 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
10641064

10651065
fx.bcx.ins().call_indirect(f_sig, f, &[data]);
10661066

1067-
let ret_val = CValue::const_val(fx, ret.layout(), 0);
1067+
let layout = ret.layout();
1068+
let ret_val = CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
10681069
ret.write_cvalue(fx, ret_val);
10691070
};
10701071

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -231,22 +231,24 @@ impl<'tcx> CValue<'tcx> {
231231
pub(crate) fn const_val(
232232
fx: &mut FunctionCx<'_, 'tcx, impl Module>,
233233
layout: TyAndLayout<'tcx>,
234-
const_val: u128,
234+
const_val: ty::ScalarInt,
235235
) -> CValue<'tcx> {
236+
assert_eq!(const_val.size(), layout.size);
236237
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
237238

238239
let clif_ty = fx.clif_type(layout.ty).unwrap();
239240

240241
if let ty::Bool = layout.ty.kind() {
241242
assert!(
242-
const_val == 0 || const_val == 1,
243+
const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE,
243244
"Invalid bool 0x{:032X}",
244245
const_val
245246
);
246247
}
247248

248249
let val = match layout.ty.kind() {
249250
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
251+
let const_val = const_val.to_bits(layout.size).unwrap();
250252
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
251253
let msb = fx
252254
.bcx
@@ -259,7 +261,7 @@ impl<'tcx> CValue<'tcx> {
259261
fx
260262
.bcx
261263
.ins()
262-
.iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64)
264+
.iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64)
263265
}
264266
ty::Float(FloatTy::F32) => {
265267
fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap()))

compiler/rustc_codegen_llvm/src/common.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1212
use rustc_codegen_ssa::traits::*;
1313
use rustc_middle::bug;
1414
use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar};
15-
use rustc_middle::ty::layout::TyAndLayout;
15+
use rustc_middle::ty::{layout::TyAndLayout, ScalarInt};
1616
use rustc_span::symbol::Symbol;
1717
use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Pointer, Size};
1818

@@ -230,12 +230,12 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
230230
fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: &'ll Type) -> &'ll Value {
231231
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
232232
match cv {
233-
Scalar::Raw { size: 0, .. } => {
233+
Scalar::Int(ScalarInt::ZST) => {
234234
assert_eq!(0, layout.value.size(self).bytes());
235235
self.const_undef(self.type_ix(0))
236236
}
237-
Scalar::Raw { data, size } => {
238-
assert_eq!(size as u64, layout.value.size(self).bytes());
237+
Scalar::Int(int) => {
238+
let data = int.assert_bits(layout.value.size(self));
239239
let llval = self.const_uint_big(self.type_ix(bitsize), data);
240240
if layout.value == Pointer {
241241
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
2929
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
3030
use rustc_index::vec::{Idx, IndexVec};
3131
use rustc_middle::ich::NodeIdHashingMode;
32-
use rustc_middle::mir::interpret::truncate;
3332
use rustc_middle::mir::{self, Field, GeneratorLayout};
3433
use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
3534
use rustc_middle::ty::subst::GenericArgKind;
@@ -1693,7 +1692,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
16931692
let value = (i.as_u32() as u128)
16941693
.wrapping_sub(niche_variants.start().as_u32() as u128)
16951694
.wrapping_add(niche_start);
1696-
let value = truncate(value, tag.value.size(cx));
1695+
let value = tag.value.size(cx).truncate(value);
16971696
// NOTE(eddyb) do *NOT* remove this assert, until
16981697
// we pass the full 128-bit value to LLVM, otherwise
16991698
// truncation will be silent and remain undetected.

compiler/rustc_lint/src/types.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_hir::{is_range_literal, ExprKind, Node};
88
use rustc_index::vec::Idx;
9-
use rustc_middle::mir::interpret::{sign_extend, truncate};
109
use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
1110
use rustc_middle::ty::subst::SubstsRef;
1211
use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable};
@@ -218,11 +217,11 @@ fn report_bin_hex_error(
218217
cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| {
219218
let (t, actually) = match ty {
220219
attr::IntType::SignedInt(t) => {
221-
let actually = sign_extend(val, size) as i128;
220+
let actually = size.sign_extend(val) as i128;
222221
(t.name_str(), actually.to_string())
223222
}
224223
attr::IntType::UnsignedInt(t) => {
225-
let actually = truncate(val, size);
224+
let actually = size.truncate(val);
226225
(t.name_str(), actually.to_string())
227226
}
228227
};

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
2525
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
2626
#![feature(array_windows)]
27+
#![feature(assoc_char_funcs)]
2728
#![feature(backtrace)]
2829
#![feature(bool_to_option)]
2930
#![feature(box_patterns)]

compiler/rustc_middle/src/mir/interpret/mod.rs

+1-34
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ use rustc_hir::def_id::DefId;
110110
use rustc_macros::HashStable;
111111
use rustc_middle::ty::print::with_no_trimmed_paths;
112112
use rustc_serialize::{Decodable, Encodable};
113-
use rustc_target::abi::{Endian, Size};
113+
use rustc_target::abi::Endian;
114114

115115
use crate::mir;
116116
use crate::ty::codec::{TyDecoder, TyEncoder};
@@ -590,39 +590,6 @@ pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, i
590590
uint
591591
}
592592

593-
////////////////////////////////////////////////////////////////////////////////
594-
// Methods to facilitate working with signed integers stored in a u128
595-
////////////////////////////////////////////////////////////////////////////////
596-
597-
/// Truncates `value` to `size` bits and then sign-extend it to 128 bits
598-
/// (i.e., if it is negative, fill with 1's on the left).
599-
#[inline]
600-
pub fn sign_extend(value: u128, size: Size) -> u128 {
601-
let size = size.bits();
602-
if size == 0 {
603-
// Truncated until nothing is left.
604-
return 0;
605-
}
606-
// Sign-extend it.
607-
let shift = 128 - size;
608-
// Shift the unsigned value to the left, then shift back to the right as signed
609-
// (essentially fills with FF on the left).
610-
(((value << shift) as i128) >> shift) as u128
611-
}
612-
613-
/// Truncates `value` to `size` bits.
614-
#[inline]
615-
pub fn truncate(value: u128, size: Size) -> u128 {
616-
let size = size.bits();
617-
if size == 0 {
618-
// Truncated until nothing is left.
619-
return 0;
620-
}
621-
let shift = 128 - size;
622-
// Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
623-
(value << shift) >> shift
624-
}
625-
626593
/// Computes the unsigned absolute value without wrapping or panicking.
627594
#[inline]
628595
pub fn uabs(value: i64) -> u64 {

0 commit comments

Comments
 (0)