From: Denis Merigoux Date: Mon, 20 Aug 2018 16:16:51 +0000 (+0200) Subject: Generalized IntPredicate in the BuilderMethods trait X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=51b7f2739b4fcf1c40335b59a15b1105df27f743;p=rust.git Generalized IntPredicate in the BuilderMethods trait --- diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 9af77aa7953..31884e0748b 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -75,7 +75,7 @@ use rustc_data_structures::sync::Lrc; use rustc_data_structures::indexed_vec::Idx; -use traits::BuilderMethods; +use traits::{IntPredicate, BuilderMethods}; use llvm::BasicBlock; use std::any::Any; @@ -127,14 +127,14 @@ fn drop(&mut self) { pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, signed: bool) - -> llvm::IntPredicate { + -> IntPredicate { match op { - hir::BinOpKind::Eq => llvm::IntEQ, - hir::BinOpKind::Ne => llvm::IntNE, - hir::BinOpKind::Lt => if signed { llvm::IntSLT } else { llvm::IntULT }, - hir::BinOpKind::Le => if signed { llvm::IntSLE } else { llvm::IntULE }, - hir::BinOpKind::Gt => if signed { llvm::IntSGT } else { llvm::IntUGT }, - hir::BinOpKind::Ge => if signed { llvm::IntSGE } else { llvm::IntUGE }, + hir::BinOpKind::Eq => IntPredicate::IntEQ, + hir::BinOpKind::Ne => IntPredicate::IntNE, + hir::BinOpKind::Lt => if signed { IntPredicate::IntSLT } else { IntPredicate::IntULT }, + hir::BinOpKind::Le => if signed { IntPredicate::IntSLE } else { IntPredicate::IntULE }, + hir::BinOpKind::Gt => if signed { IntPredicate::IntSGT } else { IntPredicate::IntUGT }, + hir::BinOpKind::Ge => if signed { IntPredicate::IntSGE } else { IntPredicate::IntUGE }, op => { bug!("comparison_op_to_icmp_predicate: expected comparison operator, \ found {:?}", diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8750b67f78a..640067fd6a3 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; -use llvm::{IntPredicate, RealPredicate, False, OperandBundleDef}; +use llvm::{RealPredicate, False, OperandBundleDef}; use llvm::{self, BasicBlock}; use common::*; use type_::Type; @@ -19,7 +19,7 @@ use rustc::ty::layout::{Align, Size}; use rustc::session::{config, Session}; use rustc_data_structures::small_c_str::SmallCStr; -use traits::BuilderMethods; +use traits::{self, BuilderMethods}; use std::borrow::Cow; use std::ops::Range; @@ -689,8 +689,9 @@ fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { } /* Comparisons */ - fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { + fn icmp(&self, op: traits::IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("icmp"); + let op : llvm::IntPredicate = traits::IntPredicateMethods::convert_to_backend_specific(op); unsafe { llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname()) } @@ -1048,8 +1049,9 @@ fn atomic_cmpxchg( src: &'ll Value, order: AtomicOrdering, failure_order: AtomicOrdering, - weak: llvm::Bool, + weak: bool, ) -> &'ll Value { + let weak = if weak { llvm::True } else { llvm::False }; unsafe { llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order, failure_order, weak) diff --git a/src/librustc_codegen_llvm/glue.rs b/src/librustc_codegen_llvm/glue.rs index 9144e3f07a1..5a19fd9aa99 100644 --- a/src/librustc_codegen_llvm/glue.rs +++ b/src/librustc_codegen_llvm/glue.rs @@ -16,12 +16,11 @@ use builder::Builder; use common::*; -use llvm; use meth; use rustc::ty::layout::LayoutOf; use rustc::ty::{self, Ty}; use value::Value; -use traits::BuilderMethods; +use traits::{IntPredicate,BuilderMethods}; pub fn size_and_align_of_dst( bx: &Builder<'_, 'll, 'tcx>, @@ -100,7 +99,7 @@ pub fn size_and_align_of_dst( // pick the correct alignment statically. C_usize(cx, std::cmp::max(sized_align, unsized_align) as u64) } - _ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align), + _ => bx.select(bx.icmp(IntPredicate::IntUGT, sized_align, unsized_align), sized_align, unsized_align) }; diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 48afda73d79..9f43a95c446 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -478,7 +478,7 @@ pub fn codegen_intrinsic_call( "cxchg" | "cxchgweak" => { let ty = substs.type_at(0); if int_type_width_signed(ty, cx).is_some() { - let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False }; + let weak = split[1] == "cxchgweak"; let pair = bx.atomic_cmpxchg( args[0].immediate(), args[1].immediate(), diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 612581c1ac6..9c0ffd2b7ac 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -19,6 +19,7 @@ use libc::{c_ulonglong, c_void}; use std::marker::PhantomData; +use traits; use super::RustString; @@ -141,6 +142,23 @@ pub enum IntPredicate { IntSLE = 41, } +impl traits::IntPredicateMethods for IntPredicate { + fn convert_to_backend_specific(intpre: traits::IntPredicate) -> Self { + match intpre { + traits::IntPredicate::IntEQ => IntPredicate::IntEQ, + traits::IntPredicate::IntNE => IntPredicate::IntNE, + traits::IntPredicate::IntUGT => IntPredicate::IntUGT, + traits::IntPredicate::IntUGE => IntPredicate::IntUGE, + traits::IntPredicate::IntULT => IntPredicate::IntULT, + traits::IntPredicate::IntULE => IntPredicate::IntULE, + traits::IntPredicate::IntSGT => IntPredicate::IntSGT, + traits::IntPredicate::IntSGE => IntPredicate::IntSGE, + traits::IntPredicate::IntSLT => IntPredicate::IntSLT, + traits::IntPredicate::IntSLE => IntPredicate::IntSLE, + } + } +} + /// LLVMRealPredicate #[derive(Copy, Clone)] #[repr(C)] diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 5f7f138cb6e..22be854659e 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -26,7 +26,7 @@ use type_::Type; use value::Value; -use traits::BuilderMethods; +use traits::{IntPredicate,BuilderMethods}; use syntax::symbol::Symbol; use syntax_pos::Pos; @@ -210,7 +210,7 @@ fn codegen_terminator(&mut self, } else { let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx); let llval = C_uint_big(switch_llty, values[0]); - let cmp = bx.icmp(llvm::IntEQ, discr.immediate(), llval); + let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); bx.cond_br(cmp, lltrue, llfalse); } } else { diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index b9bd0749965..66129783549 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -23,7 +23,7 @@ use glue; use mir::constant::const_alloc_to_llvm; -use traits::BuilderMethods; +use traits::{IntPredicate,BuilderMethods}; use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; @@ -332,7 +332,7 @@ pub fn codegen_get_discr( } else { C_uint_big(niche_llty, niche_start) }; - bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval), + bx.select(bx.icmp(IntPredicate::IntEQ, lldiscr, niche_llval), C_uint(cast_to, niche_variants.start().as_u32() as u64), C_uint(cast_to, dataful_variant.as_u32() as u64)) } else { @@ -340,7 +340,7 @@ pub fn codegen_get_discr( let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128); let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta)); let lldiscr_max = C_uint(niche_llty, niche_variants.end().as_u32() as u64); - bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max), + bx.select(bx.icmp(IntPredicate::IntULE, lldiscr, lldiscr_max), bx.intcast(lldiscr, cast_to, false), C_uint(cast_to, dataful_variant.as_u32() as u64)) } diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index 017b13410cd..35e0fd396ee 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -28,7 +28,7 @@ use type_of::LayoutLlvmExt; use value::Value; -use traits::BuilderMethods; +use traits::{IntPredicate,BuilderMethods}; use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; @@ -135,7 +135,7 @@ pub fn codegen_rvalue(&mut self, bx.br(header_bx.llbb()); let current = header_bx.phi(common::val_ty(start), &[start], &[bx.llbb()]); - let keep_going = header_bx.icmp(llvm::IntNE, current, end); + let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end); header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); cg_elem.val.store(&body_bx, @@ -337,7 +337,7 @@ pub fn codegen_rvalue_operand( // convenient place to put the `assume`. base::call_assume(&bx, bx.icmp( - llvm::IntULE, + IntPredicate::IntULE, llval, C_uint_big(ll_t_in, *scalar.valid_range.end()) )); @@ -639,31 +639,31 @@ pub fn codegen_fat_ptr_binop( match op { mir::BinOp::Eq => { bx.and( - bx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), - bx.icmp(llvm::IntEQ, lhs_extra, rhs_extra) + bx.icmp(IntPredicate::IntEQ, lhs_addr, rhs_addr), + bx.icmp(IntPredicate::IntEQ, lhs_extra, rhs_extra) ) } mir::BinOp::Ne => { bx.or( - bx.icmp(llvm::IntNE, lhs_addr, rhs_addr), - bx.icmp(llvm::IntNE, lhs_extra, rhs_extra) + bx.icmp(IntPredicate::IntNE, lhs_addr, rhs_addr), + bx.icmp(IntPredicate::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), + mir::BinOp::Lt => (IntPredicate::IntULT, IntPredicate::IntULT), + mir::BinOp::Le => (IntPredicate::IntULE, IntPredicate::IntULT), + mir::BinOp::Gt => (IntPredicate::IntUGT, IntPredicate::IntUGT), + mir::BinOp::Ge => (IntPredicate::IntUGE, IntPredicate::IntUGT), _ => bug!(), }; bx.or( bx.icmp(strict_op, lhs_addr, rhs_addr), bx.and( - bx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), + bx.icmp(IntPredicate::IntEQ, lhs_addr, rhs_addr), bx.icmp(op, lhs_extra, rhs_extra) ) ) @@ -710,7 +710,7 @@ pub fn codegen_scalar_checked_binop(&mut self, let invert_mask = common::shift_mask_val(&bx, lhs_llty, rhs_llty, true); let outer_bits = bx.and(rhs, invert_mask); - let of = bx.icmp(llvm::IntNE, outer_bits, C_null(rhs_llty)); + let of = bx.icmp(IntPredicate::IntNE, outer_bits, C_null(rhs_llty)); let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty); (val, of) @@ -838,7 +838,7 @@ fn cast_int_to_float(bx: &Builder<'_, 'll, '_>, const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1) << (Single::MAX_EXP - Single::PRECISION as i16); let max = C_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP); - let overflow = bx.icmp(llvm::IntUGE, x, max); + let overflow = bx.icmp(IntPredicate::IntUGE, x, max); let infinity_bits = C_u32(bx.cx, ieee::Single::INFINITY.to_bits() as u32); let infinity = consts::bitcast(infinity_bits, float_ty); bx.select(overflow, infinity, bx.uitofp(x, float_ty)) diff --git a/src/librustc_codegen_llvm/traits.rs b/src/librustc_codegen_llvm/traits.rs index 308677fcb73..e35669dc383 100644 --- a/src/librustc_codegen_llvm/traits.rs +++ b/src/librustc_codegen_llvm/traits.rs @@ -9,8 +9,7 @@ // except according to those terms. use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; -use llvm::{IntPredicate, RealPredicate, OperandBundleDef}; -use llvm; +use llvm::{RealPredicate, OperandBundleDef}; use common::*; use type_::Type; use libc::c_char; @@ -22,6 +21,23 @@ use std::borrow::Cow; use std::ops::Range; +pub enum IntPredicate { + IntEQ, + IntNE, + IntUGT, + IntUGE, + IntULT, + IntULE, + IntSGT, + IntSGE, + IntSLT, + IntSLE, +} + +pub trait IntPredicateMethods { + fn convert_to_backend_specific(intpre : IntPredicate) -> Self; +} + pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll, Value : ?Sized, @@ -251,7 +267,7 @@ fn atomic_cmpxchg( src: &'ll Value, order: AtomicOrdering, failure_order: AtomicOrdering, - weak: llvm::Bool, + weak: bool, ) -> &'ll Value; fn atomic_rmw( &self,