Skip to content

Commit ed5a3c0

Browse files
author
Jonathan Turner
authored
Rollup merge of rust-lang#36962 - arielb1:cast-assumptions, r=eddyb
Emit more assumptions in trans Perf numbers pending.
2 parents 1a7aa75 + 45fe3a1 commit ed5a3c0

File tree

7 files changed

+193
-176
lines changed

7 files changed

+193
-176
lines changed

src/librustc_trans/base.rs

Lines changed: 46 additions & 129 deletions
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,
@@ -247,124 +255,6 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOp_) -> llvm::RealPredicate {
247255
}
248256
}
249257

250-
pub fn compare_fat_ptrs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
251-
lhs_addr: ValueRef,
252-
lhs_extra: ValueRef,
253-
rhs_addr: ValueRef,
254-
rhs_extra: ValueRef,
255-
_t: Ty<'tcx>,
256-
op: hir::BinOp_,
257-
debug_loc: DebugLoc)
258-
-> ValueRef {
259-
match op {
260-
hir::BiEq => {
261-
let addr_eq = ICmp(bcx, llvm::IntEQ, lhs_addr, rhs_addr, debug_loc);
262-
let extra_eq = ICmp(bcx, llvm::IntEQ, lhs_extra, rhs_extra, debug_loc);
263-
And(bcx, addr_eq, extra_eq, debug_loc)
264-
}
265-
hir::BiNe => {
266-
let addr_eq = ICmp(bcx, llvm::IntNE, lhs_addr, rhs_addr, debug_loc);
267-
let extra_eq = ICmp(bcx, llvm::IntNE, lhs_extra, rhs_extra, debug_loc);
268-
Or(bcx, addr_eq, extra_eq, debug_loc)
269-
}
270-
hir::BiLe | hir::BiLt | hir::BiGe | hir::BiGt => {
271-
// a OP b ~ a.0 STRICT(OP) b.0 | (a.0 == b.0 && a.1 OP a.1)
272-
let (op, strict_op) = match op {
273-
hir::BiLt => (llvm::IntULT, llvm::IntULT),
274-
hir::BiLe => (llvm::IntULE, llvm::IntULT),
275-
hir::BiGt => (llvm::IntUGT, llvm::IntUGT),
276-
hir::BiGe => (llvm::IntUGE, llvm::IntUGT),
277-
_ => bug!(),
278-
};
279-
280-
let addr_eq = ICmp(bcx, llvm::IntEQ, lhs_addr, rhs_addr, debug_loc);
281-
let extra_op = ICmp(bcx, op, lhs_extra, rhs_extra, debug_loc);
282-
let addr_eq_extra_op = And(bcx, addr_eq, extra_op, debug_loc);
283-
284-
let addr_strict = ICmp(bcx, strict_op, lhs_addr, rhs_addr, debug_loc);
285-
Or(bcx, addr_strict, addr_eq_extra_op, debug_loc)
286-
}
287-
_ => {
288-
bug!("unexpected fat ptr binop");
289-
}
290-
}
291-
}
292-
293-
pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
294-
lhs: ValueRef,
295-
rhs: ValueRef,
296-
t: Ty<'tcx>,
297-
op: hir::BinOp_,
298-
debug_loc: DebugLoc)
299-
-> ValueRef {
300-
match t.sty {
301-
ty::TyTuple(ref tys) if tys.is_empty() => {
302-
// We don't need to do actual comparisons for nil.
303-
// () == () holds but () < () does not.
304-
match op {
305-
hir::BiEq | hir::BiLe | hir::BiGe => return C_bool(bcx.ccx(), true),
306-
hir::BiNe | hir::BiLt | hir::BiGt => return C_bool(bcx.ccx(), false),
307-
// refinements would be nice
308-
_ => bug!("compare_scalar_types: must be a comparison operator"),
309-
}
310-
}
311-
ty::TyBool => {
312-
// FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`,
313-
// which works around some LLVM bugs
314-
ICmp(bcx,
315-
bin_op_to_icmp_predicate(op, false),
316-
from_immediate(bcx, lhs),
317-
from_immediate(bcx, rhs),
318-
debug_loc)
319-
}
320-
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyUint(_) | ty::TyChar => {
321-
ICmp(bcx,
322-
bin_op_to_icmp_predicate(op, false),
323-
lhs,
324-
rhs,
325-
debug_loc)
326-
}
327-
ty::TyRawPtr(mt) if common::type_is_sized(bcx.tcx(), mt.ty) => {
328-
ICmp(bcx,
329-
bin_op_to_icmp_predicate(op, false),
330-
lhs,
331-
rhs,
332-
debug_loc)
333-
}
334-
ty::TyRawPtr(_) => {
335-
let lhs_addr = Load(bcx, GEPi(bcx, lhs, &[0, abi::FAT_PTR_ADDR]));
336-
let lhs_extra = Load(bcx, GEPi(bcx, lhs, &[0, abi::FAT_PTR_EXTRA]));
337-
338-
let rhs_addr = Load(bcx, GEPi(bcx, rhs, &[0, abi::FAT_PTR_ADDR]));
339-
let rhs_extra = Load(bcx, GEPi(bcx, rhs, &[0, abi::FAT_PTR_EXTRA]));
340-
compare_fat_ptrs(bcx,
341-
lhs_addr,
342-
lhs_extra,
343-
rhs_addr,
344-
rhs_extra,
345-
t,
346-
op,
347-
debug_loc)
348-
}
349-
ty::TyInt(_) => {
350-
ICmp(bcx,
351-
bin_op_to_icmp_predicate(op, true),
352-
lhs,
353-
rhs,
354-
debug_loc)
355-
}
356-
ty::TyFloat(_) => {
357-
FCmp(bcx,
358-
bin_op_to_fcmp_predicate(op),
359-
lhs,
360-
rhs,
361-
debug_loc)
362-
}
363-
// Should never get here, because t is scalar.
364-
_ => bug!("non-scalar type passed to compare_scalar_types"),
365-
}
366-
}
367-
368258
pub fn compare_simd_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
369259
lhs: ValueRef,
370260
rhs: ValueRef,
@@ -632,6 +522,11 @@ pub fn need_invoke(bcx: Block) -> bool {
632522
}
633523
}
634524

525+
pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) {
526+
let assume_intrinsic = b.ccx.get_intrinsic("llvm.assume");
527+
b.call(assume_intrinsic, &[val], None);
528+
}
529+
635530
/// Helper for loading values from memory. Does the necessary conversion if the in-memory type
636531
/// differs from the type used for SSA values. Also handles various special cases where the type
637532
/// gives us better information about what we are loading.
@@ -685,12 +580,9 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t
685580
debug!("store_ty: {:?} : {:?} <- {:?}", Value(dst), t, Value(v));
686581

687582
if common::type_is_fat_ptr(cx.tcx(), t) {
688-
Store(cx,
689-
ExtractValue(cx, v, abi::FAT_PTR_ADDR),
690-
get_dataptr(cx, dst));
691-
Store(cx,
692-
ExtractValue(cx, v, abi::FAT_PTR_EXTRA),
693-
get_meta(cx, dst));
583+
let lladdr = ExtractValue(cx, v, abi::FAT_PTR_ADDR);
584+
let llextra = ExtractValue(cx, v, abi::FAT_PTR_EXTRA);
585+
store_fat_ptr(cx, lladdr, llextra, dst, t);
694586
} else {
695587
Store(cx, from_immediate(cx, v), dst);
696588
}
@@ -708,11 +600,36 @@ pub fn store_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
708600

709601
pub fn load_fat_ptr<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
710602
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)))
603+
ty: Ty<'tcx>)
604+
-> (ValueRef, ValueRef)
605+
{
606+
if cx.unreachable.get() {
607+
// FIXME: remove me
608+
return (Load(cx, get_dataptr(cx, src)),
609+
Load(cx, get_meta(cx, src)));
610+
}
611+
612+
load_fat_ptr_builder(&B(cx), src, ty)
613+
}
614+
615+
pub fn load_fat_ptr_builder<'a, 'tcx>(
616+
b: &Builder<'a, 'tcx>,
617+
src: ValueRef,
618+
t: Ty<'tcx>)
619+
-> (ValueRef, ValueRef)
620+
{
621+
622+
let ptr = get_dataptr_builder(b, src);
623+
let ptr = if t.is_region_ptr() || t.is_unique() {
624+
b.load_nonnull(ptr)
625+
} else {
626+
b.load(ptr)
627+
};
628+
629+
// FIXME: emit metadata on `meta`.
630+
let meta = b.load(get_meta_builder(b, src));
631+
632+
(ptr, meta)
716633
}
717634

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

src/librustc_trans/mir/block.rs

Lines changed: 2 additions & 2 deletions
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

Lines changed: 0 additions & 14 deletions
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

Lines changed: 9 additions & 5 deletions
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

Lines changed: 9 additions & 11 deletions
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 {

0 commit comments

Comments
 (0)