diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-10-04 18:34:03 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-10-05 14:12:30 +0300 |
| commit | 923336627157eac4408b0851bf01ed20940f5582 (patch) | |
| tree | 752a54a1de0500695616d190a660388c88281ae9 | |
| parent | 6d54e0eb6be81bd1a880f44ed68a180275cfe329 (diff) | |
| download | rust-923336627157eac4408b0851bf01ed20940f5582.tar.gz rust-923336627157eac4408b0851bf01ed20940f5582.zip | |
clean up misc. uses of get_dataptr/get_meta
| -rw-r--r-- | src/librustc_trans/base.rs | 127 | ||||
| -rw-r--r-- | src/librustc_trans/mir/rvalue.rs | 91 |
2 files changed, 82 insertions, 136 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 2dde81bbaa3..5d6dd27108b 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -255,124 +255,6 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOp_) -> llvm::RealPredicate { } } -pub fn compare_fat_ptrs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - lhs_addr: ValueRef, - lhs_extra: ValueRef, - rhs_addr: ValueRef, - rhs_extra: ValueRef, - _t: Ty<'tcx>, - op: hir::BinOp_, - debug_loc: DebugLoc) - -> ValueRef { - match op { - hir::BiEq => { - let addr_eq = ICmp(bcx, llvm::IntEQ, lhs_addr, rhs_addr, debug_loc); - let extra_eq = ICmp(bcx, llvm::IntEQ, lhs_extra, rhs_extra, debug_loc); - And(bcx, addr_eq, extra_eq, debug_loc) - } - hir::BiNe => { - let addr_eq = ICmp(bcx, llvm::IntNE, lhs_addr, rhs_addr, debug_loc); - let extra_eq = ICmp(bcx, llvm::IntNE, lhs_extra, rhs_extra, debug_loc); - Or(bcx, addr_eq, extra_eq, debug_loc) - } - hir::BiLe | hir::BiLt | hir::BiGe | hir::BiGt => { - // a OP b ~ a.0 STRICT(OP) b.0 | (a.0 == b.0 && a.1 OP a.1) - let (op, strict_op) = match op { - hir::BiLt => (llvm::IntULT, llvm::IntULT), - hir::BiLe => (llvm::IntULE, llvm::IntULT), - hir::BiGt => (llvm::IntUGT, llvm::IntUGT), - hir::BiGe => (llvm::IntUGE, llvm::IntUGT), - _ => bug!(), - }; - - let addr_eq = ICmp(bcx, llvm::IntEQ, lhs_addr, rhs_addr, debug_loc); - let extra_op = ICmp(bcx, op, lhs_extra, rhs_extra, debug_loc); - let addr_eq_extra_op = And(bcx, addr_eq, extra_op, debug_loc); - - let addr_strict = ICmp(bcx, strict_op, lhs_addr, rhs_addr, debug_loc); - Or(bcx, addr_strict, addr_eq_extra_op, debug_loc) - } - _ => { - bug!("unexpected fat ptr binop"); - } - } -} - -pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - lhs: ValueRef, - rhs: ValueRef, - t: Ty<'tcx>, - op: hir::BinOp_, - debug_loc: DebugLoc) - -> ValueRef { - match t.sty { - ty::TyTuple(ref tys) if tys.is_empty() => { - // We don't need to do actual comparisons for nil. - // () == () holds but () < () does not. - match op { - hir::BiEq | hir::BiLe | hir::BiGe => return C_bool(bcx.ccx(), true), - hir::BiNe | hir::BiLt | hir::BiGt => return C_bool(bcx.ccx(), false), - // refinements would be nice - _ => bug!("compare_scalar_types: must be a comparison operator"), - } - } - ty::TyBool => { - // FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`, - // which works around some LLVM bugs - ICmp(bcx, - bin_op_to_icmp_predicate(op, false), - from_immediate(bcx, lhs), - from_immediate(bcx, rhs), - debug_loc) - } - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyUint(_) | ty::TyChar => { - ICmp(bcx, - bin_op_to_icmp_predicate(op, false), - lhs, - rhs, - debug_loc) - } - ty::TyRawPtr(mt) if common::type_is_sized(bcx.tcx(), mt.ty) => { - ICmp(bcx, - bin_op_to_icmp_predicate(op, false), - lhs, - rhs, - debug_loc) - } - ty::TyRawPtr(_) => { - let lhs_addr = Load(bcx, GEPi(bcx, lhs, &[0, abi::FAT_PTR_ADDR])); - let lhs_extra = Load(bcx, GEPi(bcx, lhs, &[0, abi::FAT_PTR_EXTRA])); - - let rhs_addr = Load(bcx, GEPi(bcx, rhs, &[0, abi::FAT_PTR_ADDR])); - let rhs_extra = Load(bcx, GEPi(bcx, rhs, &[0, abi::FAT_PTR_EXTRA])); - compare_fat_ptrs(bcx, - lhs_addr, - lhs_extra, - rhs_addr, - rhs_extra, - t, - op, - debug_loc) - } - ty::TyInt(_) => { - ICmp(bcx, - bin_op_to_icmp_predicate(op, true), - lhs, - rhs, - debug_loc) - } - ty::TyFloat(_) => { - FCmp(bcx, - bin_op_to_fcmp_predicate(op), - lhs, - rhs, - debug_loc) - } - // Should never get here, because t is scalar. - _ => bug!("non-scalar type passed to compare_scalar_types"), - } -} - pub fn compare_simd_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, lhs: ValueRef, rhs: ValueRef, @@ -693,12 +575,9 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t debug!("store_ty: {:?} : {:?} <- {:?}", Value(dst), t, Value(v)); if common::type_is_fat_ptr(cx.tcx(), t) { - Store(cx, - ExtractValue(cx, v, abi::FAT_PTR_ADDR), - get_dataptr(cx, dst)); - Store(cx, - ExtractValue(cx, v, abi::FAT_PTR_EXTRA), - get_meta(cx, dst)); + let lladdr = ExtractValue(cx, v, abi::FAT_PTR_ADDR); + let llextra = ExtractValue(cx, v, abi::FAT_PTR_EXTRA); + store_fat_ptr(cx, lladdr, llextra, dst, t); } else { Store(cx, from_immediate(cx, v), dst); } diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 53538f9fc85..c30a9dfdd96 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -20,6 +20,7 @@ use common::{self, val_ty, C_bool, C_null, C_uint, BlockAndBuilder, Result}; use debuginfo::DebugLoc; use adt; use machine; +use type_::Type; use type_of; use tvec; use value::Value; @@ -382,13 +383,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { match (lhs.val, rhs.val) { (OperandValue::Pair(lhs_addr, lhs_extra), OperandValue::Pair(rhs_addr, rhs_extra)) => { - bcx.with_block(|bcx| { - base::compare_fat_ptrs(bcx, - lhs_addr, lhs_extra, - rhs_addr, rhs_extra, - lhs.ty, op.to_hir_binop(), - debug_loc) - }) + self.trans_fat_ptr_binop(&bcx, op, + lhs_addr, lhs_extra, + rhs_addr, rhs_extra, + lhs.ty) } _ => bug!() } @@ -485,6 +483,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { input_ty: Ty<'tcx>) -> ValueRef { let is_float = input_ty.is_fp(); let is_signed = input_ty.is_signed(); + let is_nil = input_ty.is_nil(); + let is_bool = input_ty.is_bool(); match op { mir::BinOp::Add => if is_float { bcx.fadd(lhs, rhs) @@ -535,12 +535,79 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { DebugLoc::None) }) } - mir::BinOp::Eq | mir::BinOp::Lt | mir::BinOp::Gt | - mir::BinOp::Ne | mir::BinOp::Le | mir::BinOp::Ge => { - bcx.with_block(|bcx| { - base::compare_scalar_types(bcx, lhs, rhs, input_ty, - op.to_hir_binop(), DebugLoc::None) + mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt | + mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_nil { + C_bool(bcx.ccx(), match op { + mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false, + mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true, + _ => unreachable!() }) + } else if is_float { + bcx.fcmp( + base::bin_op_to_fcmp_predicate(op.to_hir_binop()), + lhs, rhs + ) + } else { + let (lhs, rhs) = if is_bool { + // FIXME(#36856) -- extend the bools into `i8` because + // LLVM's i1 comparisons are broken. + (bcx.zext(lhs, Type::i8(bcx.ccx())), + bcx.zext(rhs, Type::i8(bcx.ccx()))) + } else { + (lhs, rhs) + }; + + bcx.icmp( + base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), + lhs, rhs + ) + } + } + } + + pub fn trans_fat_ptr_binop(&mut self, + bcx: &BlockAndBuilder<'bcx, 'tcx>, + op: mir::BinOp, + lhs_addr: ValueRef, + lhs_extra: ValueRef, + rhs_addr: ValueRef, + rhs_extra: ValueRef, + _input_ty: Ty<'tcx>) + -> ValueRef { + match op { + mir::BinOp::Eq => { + bcx.and( + bcx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), + bcx.icmp(llvm::IntEQ, lhs_extra, rhs_extra) + ) + } + mir::BinOp::Ne => { + bcx.or( + bcx.icmp(llvm::IntNE, lhs_addr, rhs_addr), + bcx.icmp(llvm::IntNE, lhs_extra, rhs_extra) + ) + } + mir::BinOp::Le | mir::BinOp::Lt | + mir::BinOp::Ge | mir::BinOp::Gt => { + // a OP b ~ a.0 STRICT(OP) b.0 | (a.0 == b.0 && a.1 OP a.1) + let (op, strict_op) = match op { + mir::BinOp::Lt => (llvm::IntULT, llvm::IntULT), + mir::BinOp::Le => (llvm::IntULE, llvm::IntULT), + mir::BinOp::Gt => (llvm::IntUGT, llvm::IntUGT), + mir::BinOp::Ge => (llvm::IntUGE, llvm::IntUGT), + _ => bug!(), + }; + + bcx.or( + bcx.icmp(strict_op, lhs_addr, rhs_addr), + bcx.and( + bcx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), + bcx.icmp(op, lhs_extra, rhs_extra) + ) + ) + } + _ => { + bug!("unexpected fat ptr binop"); } } } |
