Skip to content

Commit 6d54e0e

Browse files
committed
emit !nonnull metadata on loaded fat pointers when possible
cc rust-lang#36920 (in addition to LLVM PR30597, should fix the &&[i32] case)
1 parent 506f807 commit 6d54e0e

File tree

6 files changed

+60
-39
lines changed

6 files changed

+60
-39
lines changed

src/librustc_trans/base.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,14 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
183183
StructGEP(bcx, fat_ptr, abi::FAT_PTR_ADDR)
184184
}
185185

186+
pub fn get_meta_builder(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
187+
b.struct_gep(fat_ptr, abi::FAT_PTR_EXTRA)
188+
}
189+
190+
pub fn get_dataptr_builder(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
191+
b.struct_gep(fat_ptr, abi::FAT_PTR_ADDR)
192+
}
193+
186194
fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, info_ty: Ty<'tcx>, it: LangItem) -> DefId {
187195
match bcx.tcx().lang_items.require(it) {
188196
Ok(id) => id,
@@ -708,11 +716,36 @@ pub fn store_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
708716

709717
pub fn load_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
710718
src: ValueRef,
711-
_ty: Ty<'tcx>)
712-
-> (ValueRef, ValueRef) {
713-
// FIXME: emit metadata
714-
(Load(cx, get_dataptr(cx, src)),
715-
Load(cx, get_meta(cx, src)))
719+
ty: Ty<'tcx>)
720+
-> (ValueRef, ValueRef)
721+
{
722+
if cx.unreachable.get() {
723+
// FIXME: remove me
724+
return (Load(cx, get_dataptr(cx, src)),
725+
Load(cx, get_meta(cx, src)));
726+
}
727+
728+
load_fat_ptr_builder(&B(cx), src, ty)
729+
}
730+
731+
pub fn load_fat_ptr_builder<'a, 'tcx>(
732+
b: &Builder<'a, 'tcx>,
733+
src: ValueRef,
734+
t: Ty<'tcx>)
735+
-> (ValueRef, ValueRef)
736+
{
737+
738+
let ptr = get_dataptr_builder(b, src);
739+
let ptr = if t.is_region_ptr() || t.is_unique() {
740+
b.load_nonnull(ptr)
741+
} else {
742+
b.load(ptr)
743+
};
744+
745+
// FIXME: emit metadata on `meta`.
746+
let meta = b.load(get_meta_builder(b, src));
747+
748+
(ptr, meta)
716749
}
717750

718751
pub fn from_immediate(bcx: Block, val: ValueRef) -> ValueRef {

src/librustc_trans/mir/block.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use syntax::parse::token;
3535
use super::{MirContext, LocalRef};
3636
use super::analyze::CleanupKind;
3737
use super::constant::Const;
38-
use super::lvalue::{LvalueRef, load_fat_ptr};
38+
use super::lvalue::{LvalueRef};
3939
use super::operand::OperandRef;
4040
use super::operand::OperandValue::*;
4141

@@ -703,7 +703,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
703703
for (n, &ty) in arg_types.iter().enumerate() {
704704
let ptr = adt::trans_field_ptr_builder(bcx, tuple.ty, base, Disr(0), n);
705705
let val = if common::type_is_fat_ptr(bcx.tcx(), ty) {
706-
let (lldata, llextra) = load_fat_ptr(bcx, ptr);
706+
let (lldata, llextra) = base::load_fat_ptr_builder(bcx, ptr, ty);
707707
Pair(lldata, llextra)
708708
} else {
709709
// trans_argument will load this if it needs to

src/librustc_trans/mir/lvalue.rs

-14
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ use rustc::ty::{self, Ty, TypeFoldable};
1313
use rustc::mir::repr as mir;
1414
use rustc::mir::tcx::LvalueTy;
1515
use rustc_data_structures::indexed_vec::Idx;
16-
use abi;
1716
use adt;
1817
use base;
19-
use builder::Builder;
2018
use common::{self, BlockAndBuilder, CrateContext, C_uint, C_undef};
2119
use consts;
2220
use machine;
@@ -69,18 +67,6 @@ impl<'tcx> LvalueRef<'tcx> {
6967
}
7068
}
7169

72-
pub fn get_meta(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
73-
b.struct_gep(fat_ptr, abi::FAT_PTR_EXTRA)
74-
}
75-
76-
pub fn get_dataptr(b: &Builder, fat_ptr: ValueRef) -> ValueRef {
77-
b.struct_gep(fat_ptr, abi::FAT_PTR_ADDR)
78-
}
79-
80-
pub fn load_fat_ptr(b: &Builder, fat_ptr: ValueRef) -> (ValueRef, ValueRef) {
81-
(b.load(get_dataptr(b, fat_ptr)), b.load(get_meta(b, fat_ptr)))
82-
}
83-
8470
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
8571
pub fn trans_lvalue(&mut self,
8672
bcx: &BlockAndBuilder<'bcx, 'tcx>,

src/librustc_trans/mir/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
3434

3535
pub use self::constant::trans_static_initializer;
3636

37-
use self::lvalue::{LvalueRef, get_dataptr, get_meta};
37+
use self::lvalue::{LvalueRef};
3838
use rustc::mir::traversal;
3939

4040
use self::operand::{OperandRef, OperandValue};
@@ -384,8 +384,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
384384
// they are the two sub-fields of a single aggregate field.
385385
let meta = &fcx.fn_ty.args[idx];
386386
idx += 1;
387-
arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, dst));
388-
meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, dst));
387+
arg.store_fn_arg(bcx, &mut llarg_idx,
388+
base::get_dataptr_builder(bcx, dst));
389+
meta.store_fn_arg(bcx, &mut llarg_idx,
390+
base::get_meta_builder(bcx, dst));
389391
} else {
390392
arg.store_fn_arg(bcx, &mut llarg_idx, dst);
391393
}
@@ -466,8 +468,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
466468
// so make an alloca to store them in.
467469
let meta = &fcx.fn_ty.args[idx];
468470
idx += 1;
469-
arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, lltemp));
470-
meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, lltemp));
471+
arg.store_fn_arg(bcx, &mut llarg_idx,
472+
base::get_dataptr_builder(bcx, lltemp));
473+
meta.store_fn_arg(bcx, &mut llarg_idx,
474+
base::get_meta_builder(bcx, lltemp));
471475
} else {
472476
// otherwise, arg is passed by value, so make a
473477
// temporary and store it there

src/librustc_trans/mir/operand.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -143,20 +143,18 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
143143
{
144144
debug!("trans_load: {:?} @ {:?}", Value(llval), ty);
145145

146-
let val = if common::type_is_imm_pair(bcx.ccx(), ty) {
146+
let val = if common::type_is_fat_ptr(bcx.tcx(), ty) {
147+
let (lldata, llextra) = base::load_fat_ptr_builder(bcx, llval, ty);
148+
OperandValue::Pair(lldata, llextra)
149+
} else if common::type_is_imm_pair(bcx.ccx(), ty) {
150+
let [a_ty, b_ty] = common::type_pair_fields(bcx.ccx(), ty).unwrap();
147151
let a_ptr = bcx.struct_gep(llval, 0);
148152
let b_ptr = bcx.struct_gep(llval, 1);
149153

150-
// This is None only for fat pointers, which don't
151-
// need any special load-time behavior anyway.
152-
let pair_fields = common::type_pair_fields(bcx.ccx(), ty);
153-
let (a, b) = if let Some([a_ty, b_ty]) = pair_fields {
154-
(base::load_ty_builder(bcx, a_ptr, a_ty),
155-
base::load_ty_builder(bcx, b_ptr, b_ty))
156-
} else {
157-
(bcx.load(a_ptr), bcx.load(b_ptr))
158-
};
159-
OperandValue::Pair(a, b)
154+
OperandValue::Pair(
155+
base::load_ty_builder(bcx, a_ptr, a_ty),
156+
base::load_ty_builder(bcx, b_ptr, b_ty)
157+
)
160158
} else if common::type_is_immediate(bcx.ccx(), ty) {
161159
OperandValue::Immediate(base::load_ty_builder(bcx, llval, ty))
162160
} else {

src/librustc_trans/mir/rvalue.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use Disr;
2828
use super::MirContext;
2929
use super::constant::const_scalar_checked_binop;
3030
use super::operand::{OperandRef, OperandValue};
31-
use super::lvalue::{LvalueRef, get_dataptr};
31+
use super::lvalue::{LvalueRef};
3232

3333
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
3434
pub fn trans_rvalue(&mut self,
@@ -98,7 +98,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
9898
let tr_elem = self.trans_operand(&bcx, elem);
9999
let size = count.value.as_u64(bcx.tcx().sess.target.uint_type);
100100
let size = C_uint(bcx.ccx(), size);
101-
let base = get_dataptr(&bcx, dest.llval);
101+
let base = base::get_dataptr_builder(&bcx, dest.llval);
102102
let bcx = bcx.map_block(|block| {
103103
tvec::slice_for_each(block, base, tr_elem.ty, size, |block, llslot| {
104104
self.store_operand_direct(block, llslot, tr_elem);

0 commit comments

Comments
 (0)