Skip to content

Commit e655fb6

Browse files
committed
Auto merge of #82936 - oli-obk:valtree, r=RalfJung,lcnr,matthewjasper
Implement (but don't use) valtree and refactor in preparation of use This PR does not cause any functional change. It refactors various things that are needed to make valtrees possible. This refactoring got big enough that I decided I'd want it reviewed as a PR instead of trying to make one huge PR with all the changes. cc `@rust-lang/wg-const-eval` on the following commits: * 2027184 implement valtree * eeecea9 fallible Scalar -> ScalarInt * 042f663 ScalarInt convenience methods cc `@eddyb` on ef04a6d cc `@rust-lang/wg-mir-opt` for cf1700c (`mir::Constant` can now represent either a `ConstValue` or a `ty::Const`, and it is totally possible to have two different representations for the same value)
2 parents f5d8117 + c4d564c commit e655fb6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+769
-317
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
88
use rustc_middle::mir::interpret::{
99
read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, Scalar,
1010
};
11-
use rustc_middle::ty::{Const, ConstKind};
11+
use rustc_middle::ty::ConstKind;
1212

1313
use cranelift_codegen::ir::GlobalValueData;
1414
use cranelift_module::*;
@@ -39,7 +39,10 @@ impl ConstantCx {
3939
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
4040
let mut all_constants_ok = true;
4141
for constant in &fx.mir.required_consts {
42-
let const_ = fx.monomorphize(constant.literal);
42+
let const_ = match fx.monomorphize(constant.literal) {
43+
ConstantKind::Ty(ct) => ct,
44+
ConstantKind::Val(..) => continue,
45+
};
4346
match const_.val {
4447
ConstKind::Value(_) => {}
4548
ConstKind::Unevaluated(def, ref substs, promoted) => {
@@ -113,19 +116,17 @@ pub(crate) fn codegen_constant<'tcx>(
113116
fx: &mut FunctionCx<'_, '_, 'tcx>,
114117
constant: &Constant<'tcx>,
115118
) -> CValue<'tcx> {
116-
let const_ = fx.monomorphize(constant.literal);
119+
let const_ = match fx.monomorphize(constant.literal) {
120+
ConstantKind::Ty(ct) => ct,
121+
ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
122+
};
117123
let const_val = match const_.val {
118124
ConstKind::Value(const_val) => const_val,
119125
ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => {
120126
assert!(substs.is_empty());
121127
assert!(promoted.is_none());
122128

123-
return codegen_static_ref(
124-
fx,
125-
def.did,
126-
fx.layout_of(fx.monomorphize(&constant.literal.ty)),
127-
)
128-
.to_cvalue(fx);
129+
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
129130
}
130131
ConstKind::Unevaluated(def, ref substs, promoted) => {
131132
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
@@ -422,11 +423,14 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
422423
pub(crate) fn mir_operand_get_const_val<'tcx>(
423424
fx: &FunctionCx<'_, '_, 'tcx>,
424425
operand: &Operand<'tcx>,
425-
) -> Option<&'tcx Const<'tcx>> {
426+
) -> Option<ConstValue<'tcx>> {
426427
match operand {
427428
Operand::Copy(_) | Operand::Move(_) => None,
428-
Operand::Constant(const_) => {
429-
Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all()))
430-
}
429+
Operand::Constant(const_) => match const_.literal {
430+
ConstantKind::Ty(const_) => {
431+
fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value()
432+
}
433+
ConstantKind::Val(val, _) => Some(val),
434+
},
431435
}
432436
}

compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
5353
};
5454
llvm.x86.sse2.cmp.ps | llvm.x86.sse2.cmp.pd, (c x, c y, o kind) {
5555
let kind_const = crate::constant::mir_operand_get_const_val(fx, kind).expect("llvm.x86.sse2.cmp.* kind not const");
56-
let flt_cc = match kind_const.val.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) {
56+
let flt_cc = match kind_const.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) {
5757
0 => FloatCC::Equal,
5858
1 => FloatCC::LessThan,
5959
2 => FloatCC::LessThanOrEqual,
@@ -84,7 +84,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
8484
llvm.x86.sse2.psrli.d, (c a, o imm8) {
8585
let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const");
8686
simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| {
87-
let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) {
87+
let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) {
8888
imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)),
8989
_ => fx.bcx.ins().iconst(types::I32, 0),
9090
};
@@ -94,7 +94,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
9494
llvm.x86.sse2.pslli.d, (c a, o imm8) {
9595
let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const");
9696
simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| {
97-
let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) {
97+
let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) {
9898
imm8 if imm8 < 32 => fx.bcx.ins().ishl_imm(lane, i64::from(imm8 as u8)),
9999
_ => fx.bcx.ins().iconst(types::I32, 0),
100100
};

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
8585
use rustc_middle::mir::interpret::*;
8686
let idx_const = crate::constant::mir_operand_get_const_val(fx, idx).expect("simd_shuffle* idx not const");
8787

88-
let idx_bytes = match idx_const.val {
89-
ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) => {
88+
let idx_bytes = match idx_const {
89+
ConstValue::ByRef { alloc, offset } => {
9090
let ptr = Pointer::new(AllocId(0 /* dummy */), offset);
9191
let size = Size::from_bytes(4 * u64::from(ret_lane_count) /* size_of([u32; ret_lane_count]) */);
9292
alloc.get_bytes(fx, ptr, size).unwrap()
@@ -130,7 +130,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
130130
);
131131
};
132132

133-
let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
133+
let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
134134
let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx);
135135
if idx >= lane_count.into() {
136136
fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count));
@@ -159,7 +159,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
159159
return;
160160
};
161161

162-
let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
162+
let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const));
163163
let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx);
164164
if idx >= lane_count.into() {
165165
fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count));

compiler/rustc_codegen_ssa/src/mir/analyze.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
231231
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
232232
let check = match terminator.kind {
233233
mir::TerminatorKind::Call { func: mir::Operand::Constant(ref c), ref args, .. } => {
234-
match *c.literal.ty.kind() {
234+
match *c.ty().kind() {
235235
ty::FnDef(did, _) => Some((did, args)),
236236
_ => None,
237237
}

compiler/rustc_codegen_ssa/src/mir/block.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
635635
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
636636
if let mir::Operand::Constant(constant) = arg {
637637
let c = self.eval_mir_constant(constant);
638-
let (llval, ty) = self.simd_shuffle_indices(
639-
&bx,
640-
constant.span,
641-
constant.literal.ty,
642-
c,
643-
);
638+
let (llval, ty) =
639+
self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c);
644640
return OperandRef {
645641
val: Immediate(llval),
646642
layout: bx.layout_of(ty),
@@ -830,7 +826,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
830826
let const_value = self
831827
.eval_mir_constant(constant)
832828
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
833-
let ty = constant.literal.ty;
829+
let ty = constant.ty();
834830
let size = bx.layout_of(ty).size;
835831
let scalar = match const_value {
836832
ConstValue::Scalar(s) => s,
@@ -864,7 +860,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
864860
}
865861
mir::InlineAsmOperand::SymFn { ref value } => {
866862
let literal = self.monomorphize(value.literal);
867-
if let ty::FnDef(def_id, substs) = *literal.ty.kind() {
863+
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
868864
let instance = ty::Instance::resolve_for_fn_ptr(
869865
bx.tcx(),
870866
ty::ParamEnv::reveal_all(),

compiler/rustc_codegen_ssa/src/mir/constant.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1616
constant: &mir::Constant<'tcx>,
1717
) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
1818
let val = self.eval_mir_constant(constant)?;
19-
let ty = self.monomorphize(constant.literal.ty);
19+
let ty = self.monomorphize(constant.ty());
2020
Ok(OperandRef::from_const(bx, val, ty))
2121
}
2222

2323
pub fn eval_mir_constant(
2424
&self,
2525
constant: &mir::Constant<'tcx>,
2626
) -> Result<ConstValue<'tcx>, ErrorHandled> {
27-
match self.monomorphize(constant.literal).val {
27+
let ct = self.monomorphize(constant.literal);
28+
let ct = match ct {
29+
mir::ConstantKind::Ty(ct) => ct,
30+
mir::ConstantKind::Val(val, _) => return Ok(val),
31+
};
32+
match ct.val {
2833
ty::ConstKind::Unevaluated(def, substs, promoted) => self
2934
.cx
3035
.tcx()

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
372372
(var_ty, var_kind)
373373
}
374374
mir::VarDebugInfoContents::Const(c) => {
375-
let ty = self.monomorphize(c.literal.ty);
375+
let ty = self.monomorphize(c.ty());
376376
(ty, VariableKind::LocalVariable)
377377
}
378378
};

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

+38-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::convert::TryFrom;
1+
use std::convert::{TryFrom, TryInto};
22
use std::fmt;
33

44
use rustc_apfloat::{
@@ -8,12 +8,12 @@ use rustc_apfloat::{
88
use rustc_macros::HashStable;
99
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
1010

11-
use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt};
11+
use crate::ty::{Lift, ParamEnv, ScalarInt, Ty, TyCtxt};
1212

1313
use super::{AllocId, Allocation, InterpResult, Pointer, PointerArithmetic};
1414

1515
/// Represents the result of const evaluation via the `eval_to_allocation` query.
16-
#[derive(Clone, HashStable, TyEncodable, TyDecodable, Debug)]
16+
#[derive(Copy, Clone, HashStable, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)]
1717
pub struct ConstAlloc<'tcx> {
1818
// the value lives here, at offset 0, and that allocation definitely is a `AllocKind::Memory`
1919
// (so you can use `AllocMap::unwrap_memory`).
@@ -47,6 +47,27 @@ pub enum ConstValue<'tcx> {
4747
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
4848
static_assert_size!(ConstValue<'_>, 32);
4949

50+
impl From<Scalar> for ConstValue<'tcx> {
51+
fn from(s: Scalar) -> Self {
52+
Self::Scalar(s)
53+
}
54+
}
55+
56+
impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
57+
type Lifted = ConstValue<'tcx>;
58+
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> {
59+
Some(match self {
60+
ConstValue::Scalar(s) => ConstValue::Scalar(s),
61+
ConstValue::Slice { data, start, end } => {
62+
ConstValue::Slice { data: tcx.lift(data)?, start, end }
63+
}
64+
ConstValue::ByRef { alloc, offset } => {
65+
ConstValue::ByRef { alloc: tcx.lift(alloc)?, offset }
66+
}
67+
})
68+
}
69+
}
70+
5071
impl<'tcx> ConstValue<'tcx> {
5172
#[inline]
5273
pub fn try_to_scalar(&self) -> Option<Scalar> {
@@ -56,20 +77,20 @@ impl<'tcx> ConstValue<'tcx> {
5677
}
5778
}
5879

80+
pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
81+
Some(self.try_to_scalar()?.assert_int())
82+
}
83+
5984
pub fn try_to_bits(&self, size: Size) -> Option<u128> {
60-
self.try_to_scalar()?.to_bits(size).ok()
85+
self.try_to_scalar_int()?.to_bits(size).ok()
6186
}
6287

6388
pub fn try_to_bool(&self) -> Option<bool> {
64-
match self.try_to_bits(Size::from_bytes(1))? {
65-
0 => Some(false),
66-
1 => Some(true),
67-
_ => None,
68-
}
89+
self.try_to_scalar_int()?.try_into().ok()
6990
}
7091

7192
pub fn try_to_machine_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
72-
Some(self.try_to_bits(tcx.data_layout.pointer_size)? as u64)
93+
self.try_to_scalar_int()?.try_to_machine_usize(tcx).ok()
7394
}
7495

7596
pub fn try_to_bits_for_ty(
@@ -503,6 +524,13 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
503524
}
504525
}
505526

527+
impl<Tag> From<ScalarInt> for Scalar<Tag> {
528+
#[inline(always)]
529+
fn from(ptr: ScalarInt) -> Self {
530+
Scalar::Int(ptr)
531+
}
532+
}
533+
506534
#[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)]
507535
pub enum ScalarMaybeUninit<Tag = ()> {
508536
Scalar(Scalar<Tag>),

0 commit comments

Comments
 (0)