diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-04-26 09:18:19 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-05-11 13:01:44 +0200 |
| commit | fdd9787777dac5db6bd555df08038e3c191999e4 (patch) | |
| tree | c69aed643a634de3d037ce9ea53be02c92c992fb /src/librustc_trans | |
| parent | 41707d8df9a441e19387a4a61415ee0af58a9e48 (diff) | |
| download | rust-fdd9787777dac5db6bd555df08038e3c191999e4.tar.gz rust-fdd9787777dac5db6bd555df08038e3c191999e4.zip | |
Introduce ConstValue and use it instead of miri's Value for constant values
Diffstat (limited to 'src/librustc_trans')
| -rw-r--r-- | src/librustc_trans/base.rs | 18 | ||||
| -rw-r--r-- | src/librustc_trans/debuginfo/metadata.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/debuginfo/type_names.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/mir/constant.rs | 106 | ||||
| -rw-r--r-- | src/librustc_trans/mir/operand.rs | 32 | ||||
| -rw-r--r-- | src/librustc_trans/mir/rvalue.rs | 2 |
6 files changed, 90 insertions, 72 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 33dc9b3b7ab..54177c5d5a2 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -199,7 +199,7 @@ pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, let (source, target) = cx.tcx.struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { (&ty::TyArray(_, len), &ty::TySlice(_)) => { - C_usize(cx, len.val.unwrap_u64()) + C_usize(cx, len.unwrap_usize(cx.tcx)) } (&ty::TyDynamic(..), &ty::TyDynamic(..)) => { // For now, upcasts are limited to changes in marker @@ -1372,8 +1372,7 @@ mod temp_stable_hash_impls { } fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) { - use rustc::mir::interpret::{GlobalId, Value, PrimVal}; - use rustc::middle::const_val::ConstVal; + use rustc::mir::interpret::GlobalId; info!("loading wasm section {:?}", id); @@ -1392,18 +1391,7 @@ fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) { let param_env = ty::ParamEnv::reveal_all(); let val = tcx.const_eval(param_env.and(cid)).unwrap(); - let val = match val.val { - ConstVal::Value(val) => val, - ConstVal::Unevaluated(..) => bug!("should be evaluated"), - }; - let val = match val { - Value::ByRef(ptr, _align) => ptr.into_inner_primval(), - ref v => bug!("should be ByRef, was {:?}", v), - }; - let mem = match val { - PrimVal::Ptr(mem) => mem, - ref v => bug!("should be Ptr, was {:?}", v), - }; + let mem = val.to_ptr().expect("should be pointer"); assert_eq!(mem.offset, 0); let alloc = tcx .interpret_interner diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index ae23b523cbf..4e77c0df65e 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -277,7 +277,7 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let upper_bound = match array_or_slice_type.sty { ty::TyArray(_, len) => { - len.val.unwrap_u64() as c_longlong + len.unwrap_usize(cx.tcx) as c_longlong } _ => -1 }; diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 565a9bedef0..05a74db3a6c 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -97,7 +97,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyArray(inner_type, len) => { output.push('['); push_debuginfo_type_name(cx, inner_type, true, output); - output.push_str(&format!("; {}", len.val.unwrap_u64())); + output.push_str(&format!("; {}", len.unwrap_usize(cx.tcx))); output.push(']'); }, ty::TySlice(inner_type) => { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 6e07b8e73ef..a10b7c9c9f1 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -14,7 +14,7 @@ use rustc_mir::interpret::{read_target_uint, const_val_field}; use rustc::hir::def_id::DefId; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; -use rustc::mir::interpret::{Allocation, GlobalId, MemoryPointer, PrimVal, Value as MiriValue}; +use rustc::mir::interpret::{GlobalId, MemoryPointer, PrimVal, Allocation, ConstValue}; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Scalar}; use builder::Builder; @@ -56,7 +56,7 @@ pub fn primval_to_llvm(cx: &CodegenCx, consts::get_static(cx, def_id) } else if let Some(alloc) = cx.tcx.interpret_interner .get_alloc(ptr.alloc_id) { - let init = global_initializer(cx, alloc); + let init = const_alloc_to_llvm(cx, alloc); if alloc.runtime_mutability == Mutability::Mutable { consts::addr_of_mut(cx, init, alloc.align, "byte_str") } else { @@ -81,7 +81,50 @@ pub fn primval_to_llvm(cx: &CodegenCx, } } -pub fn global_initializer(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { +fn const_value_to_llvm<'tcx>(cx: &CodegenCx<'_, 'tcx>, val: ConstValue, ty: Ty<'tcx>) -> ValueRef { + let layout = cx.layout_of(ty); + + if layout.is_zst() { + return C_undef(layout.immediate_llvm_type(cx)); + } + + match val { + ConstValue::ByVal(x) => { + let scalar = match layout.abi { + layout::Abi::Scalar(ref x) => x, + _ => bug!("const_value_to_llvm: invalid ByVal layout: {:#?}", layout) + }; + primval_to_llvm( + cx, + x, + scalar, + layout.immediate_llvm_type(cx), + ) + }, + ConstValue::ByValPair(a, b) => { + let (a_scalar, b_scalar) = match layout.abi { + layout::Abi::ScalarPair(ref a, ref b) => (a, b), + _ => bug!("const_value_to_llvm: invalid ByValPair layout: {:#?}", layout) + }; + let a_llval = primval_to_llvm( + cx, + a, + a_scalar, + layout.scalar_pair_element_llvm_type(cx, 0), + ); + let b_llval = primval_to_llvm( + cx, + b, + b_scalar, + layout.scalar_pair_element_llvm_type(cx, 1), + ); + C_struct(cx, &[a_llval, b_llval], false) + }, + ConstValue::ByRef(alloc) => const_alloc_to_llvm(cx, alloc), + } +} + +pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { let mut llvals = Vec::with_capacity(alloc.relocations.len() + 1); let layout = cx.data_layout(); let pointer_size = layout.pointer_size.bytes() as usize; @@ -96,7 +139,7 @@ pub fn global_initializer(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { let ptr_offset = read_target_uint( layout.endian, &alloc.bytes[offset..(offset + pointer_size)], - ).expect("global_initializer: could not read relocation pointer") as u64; + ).expect("const_alloc_to_llvm: could not read relocation pointer") as u64; llvals.push(primval_to_llvm( cx, PrimVal::Ptr(MemoryPointer { alloc_id, offset: ptr_offset }), @@ -128,25 +171,19 @@ pub fn trans_static_initializer<'a, 'tcx>( let param_env = ty::ParamEnv::reveal_all(); let static_ = cx.tcx.const_eval(param_env.and(cid))?; - let ptr = match static_.val { - ConstVal::Value(MiriValue::ByRef(ptr, _)) => ptr, + let val = match static_.val { + ConstVal::Value(val) => val, _ => bug!("static const eval returned {:#?}", static_), }; - - let alloc = cx - .tcx - .interpret_interner - .get_alloc(ptr.primval.to_ptr().expect("static has integer pointer").alloc_id) - .expect("miri allocation never successfully created"); - Ok(global_initializer(cx, alloc)) + Ok(const_value_to_llvm(cx, val, static_.ty)) } impl<'a, 'tcx> FunctionCx<'a, 'tcx> { - fn const_to_miri_value( + fn const_to_const_value( &mut self, bx: &Builder<'a, 'tcx>, constant: &'tcx ty::Const<'tcx>, - ) -> Result<MiriValue, ConstEvalErr<'tcx>> { + ) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> { match constant.val { ConstVal::Unevaluated(def_id, ref substs) => { let tcx = bx.tcx(); @@ -157,17 +194,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { promoted: None, }; let c = tcx.const_eval(param_env.and(cid))?; - self.const_to_miri_value(bx, c) + self.const_to_const_value(bx, c) }, - ConstVal::Value(miri_val) => Ok(miri_val), + ConstVal::Value(val) => Ok(val), } } - pub fn mir_constant_to_miri_value( + pub fn mir_constant_to_const_value( &mut self, bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>, - ) -> Result<MiriValue, ConstEvalErr<'tcx>> { + ) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> { match constant.literal { mir::Literal::Promoted { index } => { let param_env = ty::ParamEnv::reveal_all(); @@ -180,7 +217,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::Literal::Value { value } => { Ok(self.monomorphize(&value)) } - }.and_then(|c| self.const_to_miri_value(bx, c)) + }.and_then(|c| self.const_to_const_value(bx, c)) } /// process constant containing SIMD shuffle indices @@ -189,11 +226,11 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>, ) -> (ValueRef, Ty<'tcx>) { - self.mir_constant_to_miri_value(bx, constant) + self.mir_constant_to_const_value(bx, constant) .and_then(|c| { let field_ty = constant.ty.builtin_index().unwrap(); let fields = match constant.ty.sty { - ty::TyArray(_, n) => n.val.unwrap_u64(), + ty::TyArray(_, n) => n.unwrap_usize(bx.tcx()), ref other => bug!("invalid simd shuffle type: {}", other), }; let values: Result<Vec<ValueRef>, _> = (0..fields).map(|field| { @@ -206,19 +243,18 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { c, constant.ty, )?; - match field.val { - ConstVal::Value(MiriValue::ByVal(prim)) => { - let layout = bx.cx.layout_of(field_ty); - let scalar = match layout.abi { - layout::Abi::Scalar(ref x) => x, - _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) - }; - Ok(primval_to_llvm( - bx.cx, prim, scalar, - layout.immediate_llvm_type(bx.cx), - )) - }, - other => bug!("simd shuffle field {:?}, {}", other, constant.ty), + if let Some(prim) = field.to_primval() { + let layout = bx.cx.layout_of(field_ty); + let scalar = match layout.abi { + layout::Abi::Scalar(ref x) => x, + _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) + }; + Ok(primval_to_llvm( + bx.cx, prim, scalar, + layout.immediate_llvm_type(bx.cx), + )) + } else { + bug!("simd shuffle field {:?}", field) } }).collect(); let llval = C_struct(bx.cx, &values?, false); diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 656ab95a28c..432ac44e0a5 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -11,7 +11,7 @@ use llvm::ValueRef; use rustc::middle::const_val::ConstEvalErr; use rustc::mir; -use rustc::mir::interpret::Value as MiriValue; +use rustc::mir::interpret::ConstValue; use rustc::ty; use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; use rustc_data_structures::indexed_vec::Idx; @@ -22,12 +22,13 @@ use builder::Builder; use value::Value; use type_of::LayoutLlvmExt; use type_::Type; +use consts; use std::fmt; use std::ptr; use super::{FunctionCx, LocalRef}; -use super::constant::{primval_to_llvm}; +use super::constant::{primval_to_llvm, const_alloc_to_llvm}; use super::place::PlaceRef; /// The representation of a Rust value. The enum variant is in fact @@ -94,7 +95,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } pub fn from_const(bx: &Builder<'a, 'tcx>, - miri_val: MiriValue, + val: ConstValue<'tcx>, ty: ty::Ty<'tcx>) -> Result<OperandRef<'tcx>, ConstEvalErr<'tcx>> { let layout = bx.cx.layout_of(ty); @@ -103,8 +104,8 @@ impl<'a, 'tcx> OperandRef<'tcx> { return Ok(OperandRef::new_zst(bx.cx, layout)); } - let val = match miri_val { - MiriValue::ByVal(x) => { + let val = match val { + ConstValue::ByVal(x) => { let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) @@ -117,7 +118,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { ); OperandValue::Immediate(llval) }, - MiriValue::ByValPair(a, b) => { + ConstValue::ByValPair(a, b) => { let (a_scalar, b_scalar) = match layout.abi { layout::Abi::ScalarPair(ref a, ref b) => (a, b), _ => bug!("from_const: invalid ByValPair layout: {:#?}", layout) @@ -136,18 +137,11 @@ impl<'a, 'tcx> OperandRef<'tcx> { ); OperandValue::Pair(a_llval, b_llval) }, - MiriValue::ByRef(ptr, align) => { - let scalar = layout::Scalar { - value: layout::Primitive::Pointer, - valid_range: 0..=!0 - }; - let ptr = primval_to_llvm( - bx.cx, - ptr.into_inner_primval(), - &scalar, - layout.llvm_type(bx.cx).ptr_to(), - ); - return Ok(PlaceRef::new_sized(ptr, layout, align).load(bx)); + ConstValue::ByRef(alloc) => { + let init = const_alloc_to_llvm(bx.cx, alloc); + let llval = consts::addr_of(bx.cx, init, layout.align, "byte_str"); + let llval = consts::bitcast(llval, layout.llvm_type(bx.cx).ptr_to()); + return Ok(PlaceRef::new_sized(llval, layout, alloc.align).load(bx)); }, }; @@ -396,7 +390,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::Operand::Constant(ref constant) => { let ty = self.monomorphize(&constant.ty); - self.mir_constant_to_miri_value(bx, constant) + self.mir_constant_to_const_value(bx, constant) .and_then(|c| OperandRef::from_const(bx, c, ty)) .unwrap_or_else(|err| { match constant.literal { diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 0cd823391b9..3b447756450 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -516,7 +516,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { if let mir::Place::Local(index) = *place { if let LocalRef::Operand(Some(op)) = self.locals[index] { if let ty::TyArray(_, n) = op.layout.ty.sty { - let n = n.val.unwrap_u64(); + let n = n.unwrap_usize(bx.cx.tcx); return common::C_usize(bx.cx, n); } } |
