]> git.lizzy.rs Git - rust.git/commitdiff
emit !nonnull metadata on loaded fat pointers when possible
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Tue, 4 Oct 2016 14:44:31 +0000 (17:44 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Wed, 5 Oct 2016 10:58:04 +0000 (13:58 +0300)
cc #36920 (in addition to LLVM PR30597, should fix the &&[i32] case)

src/librustc_trans/base.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/lvalue.rs
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/operand.rs
src/librustc_trans/mir/rvalue.rs

index d80ed5e27cc6d20b27b62fea42c0d98fa5577b65..2dde81bbaa319d537b0ca8ca42732994c282ae39 100644 (file)
@@ -183,6 +183,14 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
     StructGEP(bcx, fat_ptr, abi::FAT_PTR_ADDR)
 }
 
+pub fn get_meta_builder(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
+    b.struct_gep(fat_ptr, abi::FAT_PTR_EXTRA)
+}
+
+pub fn get_dataptr_builder(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
+    b.struct_gep(fat_ptr, abi::FAT_PTR_ADDR)
+}
+
 fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, info_ty: Ty<'tcx>, it: LangItem) -> DefId {
     match bcx.tcx().lang_items.require(it) {
         Ok(id) => id,
@@ -708,11 +716,36 @@ pub fn store_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
 
 pub fn load_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                 src: ValueRef,
-                                _ty: Ty<'tcx>)
-                                -> (ValueRef, ValueRef) {
-    // FIXME: emit metadata
-    (Load(cx, get_dataptr(cx, src)),
-     Load(cx, get_meta(cx, src)))
+                                ty: Ty<'tcx>)
+                                -> (ValueRef, ValueRef)
+{
+    if cx.unreachable.get() {
+        // FIXME: remove me
+        return (Load(cx, get_dataptr(cx, src)),
+                Load(cx, get_meta(cx, src)));
+    }
+
+    load_fat_ptr_builder(&B(cx), src, ty)
+}
+
+pub fn load_fat_ptr_builder<'a, 'tcx>(
+    b: &Builder<'a, 'tcx>,
+    src: ValueRef,
+    t: Ty<'tcx>)
+    -> (ValueRef, ValueRef)
+{
+
+    let ptr = get_dataptr_builder(b, src);
+    let ptr = if t.is_region_ptr() || t.is_unique() {
+        b.load_nonnull(ptr)
+    } else {
+        b.load(ptr)
+    };
+
+    // FIXME: emit metadata on `meta`.
+    let meta = b.load(get_meta_builder(b, src));
+
+    (ptr, meta)
 }
 
 pub fn from_immediate(bcx: Block, val: ValueRef) -> ValueRef {
index 9e2d947c5e56342647bdeaaa9053275f07b65e45..9edb489decc735f3c361c19b00940d046e528799 100644 (file)
@@ -35,7 +35,7 @@
 use super::{MirContext, LocalRef};
 use super::analyze::CleanupKind;
 use super::constant::Const;
-use super::lvalue::{LvalueRef, load_fat_ptr};
+use super::lvalue::{LvalueRef};
 use super::operand::OperandRef;
 use super::operand::OperandValue::*;
 
@@ -703,7 +703,7 @@ fn trans_arguments_untupled(&mut self,
                 for (n, &ty) in arg_types.iter().enumerate() {
                     let ptr = adt::trans_field_ptr_builder(bcx, tuple.ty, base, Disr(0), n);
                     let val = if common::type_is_fat_ptr(bcx.tcx(), ty) {
-                        let (lldata, llextra) = load_fat_ptr(bcx, ptr);
+                        let (lldata, llextra) = base::load_fat_ptr_builder(bcx, ptr, ty);
                         Pair(lldata, llextra)
                     } else {
                         // trans_argument will load this if it needs to
index 7102bd81caf36e3d5243ab5a3014d11aa1650f6c..8e65eac2e80894943b86e3cfe836346c6e3008cd 100644 (file)
 use rustc::mir::repr as mir;
 use rustc::mir::tcx::LvalueTy;
 use rustc_data_structures::indexed_vec::Idx;
-use abi;
 use adt;
 use base;
-use builder::Builder;
 use common::{self, BlockAndBuilder, CrateContext, C_uint, C_undef};
 use consts;
 use machine;
@@ -69,18 +67,6 @@ pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
     }
 }
 
-pub fn get_meta(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
-    b.struct_gep(fat_ptr, abi::FAT_PTR_EXTRA)
-}
-
-pub fn get_dataptr(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
-    b.struct_gep(fat_ptr, abi::FAT_PTR_ADDR)
-}
-
-pub fn load_fat_ptr(b: &Builder, fat_ptr: ValueRef) -> (ValueRef, ValueRef) {
-    (b.load(get_dataptr(b, fat_ptr)), b.load(get_meta(b, fat_ptr)))
-}
-
 impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
     pub fn trans_lvalue(&mut self,
                         bcx: &BlockAndBuilder<'bcx, 'tcx>,
index fe71023ea34dea34dc16af6908eaee6cc12f5da6..d5828f7c56c25ec2b382145ae221e1c2be56bea0 100644 (file)
@@ -34,7 +34,7 @@
 
 pub use self::constant::trans_static_initializer;
 
-use self::lvalue::{LvalueRef, get_dataptr, get_meta};
+use self::lvalue::{LvalueRef};
 use rustc::mir::traversal;
 
 use self::operand::{OperandRef, OperandValue};
@@ -384,8 +384,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
                     // they are the two sub-fields of a single aggregate field.
                     let meta = &fcx.fn_ty.args[idx];
                     idx += 1;
-                    arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, dst));
-                    meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, dst));
+                    arg.store_fn_arg(bcx, &mut llarg_idx,
+                                     base::get_dataptr_builder(bcx, dst));
+                    meta.store_fn_arg(bcx, &mut llarg_idx,
+                                      base::get_meta_builder(bcx, dst));
                 } else {
                     arg.store_fn_arg(bcx, &mut llarg_idx, dst);
                 }
@@ -466,8 +468,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
                 // so make an alloca to store them in.
                 let meta = &fcx.fn_ty.args[idx];
                 idx += 1;
-                arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, lltemp));
-                meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, lltemp));
+                arg.store_fn_arg(bcx, &mut llarg_idx,
+                                 base::get_dataptr_builder(bcx, lltemp));
+                meta.store_fn_arg(bcx, &mut llarg_idx,
+                                  base::get_meta_builder(bcx, lltemp));
             } else  {
                 // otherwise, arg is passed by value, so make a
                 // temporary and store it there
index 4f1ec40398ca97659d1bbcf2881a199981c82dcc..c9d83a3375258df830c0141cb3d38cadb886b40f 100644 (file)
@@ -143,20 +143,18 @@ pub fn trans_load(&mut self,
     {
         debug!("trans_load: {:?} @ {:?}", Value(llval), ty);
 
-        let val = if common::type_is_imm_pair(bcx.ccx(), ty) {
+        let val = if common::type_is_fat_ptr(bcx.tcx(), ty) {
+            let (lldata, llextra) = base::load_fat_ptr_builder(bcx, llval, ty);
+            OperandValue::Pair(lldata, llextra)
+        } else if common::type_is_imm_pair(bcx.ccx(), ty) {
+            let [a_ty, b_ty] = common::type_pair_fields(bcx.ccx(), ty).unwrap();
             let a_ptr = bcx.struct_gep(llval, 0);
             let b_ptr = bcx.struct_gep(llval, 1);
 
-            // This is None only for fat pointers, which don't
-            // need any special load-time behavior anyway.
-            let pair_fields = common::type_pair_fields(bcx.ccx(), ty);
-            let (a, b) = if let Some([a_ty, b_ty]) = pair_fields {
-                (base::load_ty_builder(bcx, a_ptr, a_ty),
-                 base::load_ty_builder(bcx, b_ptr, b_ty))
-            } else {
-                (bcx.load(a_ptr), bcx.load(b_ptr))
-            };
-            OperandValue::Pair(a, b)
+            OperandValue::Pair(
+                base::load_ty_builder(bcx, a_ptr, a_ty),
+                base::load_ty_builder(bcx, b_ptr, b_ty)
+            )
         } else if common::type_is_immediate(bcx.ccx(), ty) {
             OperandValue::Immediate(base::load_ty_builder(bcx, llval, ty))
         } else {
index b643dcd9871b0bd798536bfe98f2401f757c134c..53538f9fc85fc0eeb862d1f3a2ca07ebf30d190d 100644 (file)
@@ -28,7 +28,7 @@
 use super::MirContext;
 use super::constant::const_scalar_checked_binop;
 use super::operand::{OperandRef, OperandValue};
-use super::lvalue::{LvalueRef, get_dataptr};
+use super::lvalue::{LvalueRef};
 
 impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
     pub fn trans_rvalue(&mut self,
@@ -98,7 +98,7 @@ pub fn trans_rvalue(&mut self,
                 let tr_elem = self.trans_operand(&bcx, elem);
                 let size = count.value.as_u64(bcx.tcx().sess.target.uint_type);
                 let size = C_uint(bcx.ccx(), size);
-                let base = get_dataptr(&bcx, dest.llval);
+                let base = base::get_dataptr_builder(&bcx, dest.llval);
                 let bcx = bcx.map_block(|block| {
                     tvec::slice_for_each(block, base, tr_elem.ty, size, |block, llslot| {
                         self.store_operand_direct(block, llslot, tr_elem);