about summary refs log tree commit diff
path: root/src/librustc_trans
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-04-26 09:18:19 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-05-11 13:01:44 +0200
commitfdd9787777dac5db6bd555df08038e3c191999e4 (patch)
treec69aed643a634de3d037ce9ea53be02c92c992fb /src/librustc_trans
parent41707d8df9a441e19387a4a61415ee0af58a9e48 (diff)
downloadrust-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.rs18
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/debuginfo/type_names.rs2
-rw-r--r--src/librustc_trans/mir/constant.rs106
-rw-r--r--src/librustc_trans/mir/operand.rs32
-rw-r--r--src/librustc_trans/mir/rvalue.rs2
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);
                 }
             }