提交 8590336d 编写于 作者: D Denis Merigoux 提交者: Eduard-Mihai Burtescu

Generalized RealPredicate

上级 51b7f273
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use traits::{IntPredicate, BuilderMethods}; use traits::{IntPredicate, RealPredicate, BuilderMethods};
use llvm::BasicBlock; use llvm::BasicBlock;
use std::any::Any; use std::any::Any;
...@@ -143,14 +143,14 @@ pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, ...@@ -143,14 +143,14 @@ pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind,
} }
} }
pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate { pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> RealPredicate {
match op { match op {
hir::BinOpKind::Eq => llvm::RealOEQ, hir::BinOpKind::Eq => RealPredicate::RealOEQ,
hir::BinOpKind::Ne => llvm::RealUNE, hir::BinOpKind::Ne => RealPredicate::RealUNE,
hir::BinOpKind::Lt => llvm::RealOLT, hir::BinOpKind::Lt => RealPredicate::RealOLT,
hir::BinOpKind::Le => llvm::RealOLE, hir::BinOpKind::Le => RealPredicate::RealOLE,
hir::BinOpKind::Gt => llvm::RealOGT, hir::BinOpKind::Gt => RealPredicate::RealOGT,
hir::BinOpKind::Ge => llvm::RealOGE, hir::BinOpKind::Ge => RealPredicate::RealOGE,
op => { op => {
bug!("comparison_op_to_fcmp_predicate: expected comparison operator, \ bug!("comparison_op_to_fcmp_predicate: expected comparison operator, \
found {:?}", found {:?}",
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{RealPredicate, False, OperandBundleDef}; use llvm::{False, OperandBundleDef};
use llvm::{self, BasicBlock}; use llvm::{self, BasicBlock};
use common::*; use common::*;
use type_::Type; use type_::Type;
...@@ -697,7 +697,7 @@ fn icmp(&self, op: traits::IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &' ...@@ -697,7 +697,7 @@ fn icmp(&self, op: traits::IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'
} }
} }
fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { fn fcmp(&self, op: traits::RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
self.count_insn("fcmp"); self.count_insn("fcmp");
unsafe { unsafe {
llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname()) llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
......
...@@ -181,6 +181,29 @@ pub enum RealPredicate { ...@@ -181,6 +181,29 @@ pub enum RealPredicate {
RealPredicateTrue = 15, RealPredicateTrue = 15,
} }
impl traits::RealPredicateMethods for RealPredicate {
fn convert_to_backend_specific(realpred: traits::RealPredicate) -> Self {
match realpred {
traits::RealPredicate::RealPredicateFalse => RealPredicate::RealPredicateFalse,
traits::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
traits::RealPredicate::RealOGT => RealPredicate::RealOGT,
traits::RealPredicate::RealOGE => RealPredicate::RealOGE,
traits::RealPredicate::RealOLT => RealPredicate::RealOLT,
traits::RealPredicate::RealOLE => RealPredicate::RealOLE,
traits::RealPredicate::RealONE => RealPredicate::RealONE,
traits::RealPredicate::RealORD => RealPredicate::RealORD,
traits::RealPredicate::RealUNO => RealPredicate::RealUNO,
traits::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
traits::RealPredicate::RealUGT => RealPredicate::RealUGT,
traits::RealPredicate::RealUGE => RealPredicate::RealUGE,
traits::RealPredicate::RealULT => RealPredicate::RealULT,
traits::RealPredicate::RealULE => RealPredicate::RealULE,
traits::RealPredicate::RealUNE => RealPredicate::RealUNE,
traits::RealPredicate::RealPredicateTrue => RealPredicate::RealPredicateTrue
}
}
}
/// LLVMTypeKind /// LLVMTypeKind
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)] #[repr(C)]
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use llvm;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::layout::{self, LayoutOf}; use rustc::ty::layout::{self, LayoutOf};
...@@ -28,7 +27,7 @@ ...@@ -28,7 +27,7 @@
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use value::Value; use value::Value;
use traits::{IntPredicate,BuilderMethods}; use traits::{IntPredicate, RealPredicate, BuilderMethods};
use super::{FunctionCx, LocalRef}; use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue}; use super::operand::{OperandRef, OperandValue};
...@@ -962,8 +961,8 @@ fn int_min(signed: bool, int_ty: &Type) -> i128 { ...@@ -962,8 +961,8 @@ fn int_min(signed: bool, int_ty: &Type) -> i128 {
// negation, and the negation can be merged into the select. Therefore, it not necessarily any // negation, and the negation can be merged into the select. Therefore, it not necessarily any
// more expensive than a ordered ("normal") comparison. Whether these optimizations will be // more expensive than a ordered ("normal") comparison. Whether these optimizations will be
// performed is ultimately up to the backend, but at least x86 does perform them. // performed is ultimately up to the backend, but at least x86 does perform them.
let less_or_nan = bx.fcmp(llvm::RealULT, x, f_min); let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
let greater = bx.fcmp(llvm::RealOGT, x, f_max); let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
let int_max = C_uint_big(int_ty, int_max(signed, int_ty)); let int_max = C_uint_big(int_ty, int_max(signed, int_ty));
let int_min = C_uint_big(int_ty, int_min(signed, int_ty) as u128); let int_min = C_uint_big(int_ty, int_min(signed, int_ty) as u128);
let s0 = bx.select(less_or_nan, int_min, fptosui_result); let s0 = bx.select(less_or_nan, int_min, fptosui_result);
...@@ -974,7 +973,7 @@ fn int_min(signed: bool, int_ty: &Type) -> i128 { ...@@ -974,7 +973,7 @@ fn int_min(signed: bool, int_ty: &Type) -> i128 {
// Therefore we only need to execute this step for signed integer types. // Therefore we only need to execute this step for signed integer types.
if signed { if signed {
// LLVM has no isNaN predicate, so we use (x == x) instead // LLVM has no isNaN predicate, so we use (x == x) instead
bx.select(bx.fcmp(llvm::RealOEQ, x, x), s1, C_uint(int_ty, 0)) bx.select(bx.fcmp(RealPredicate::RealOEQ, x, x), s1, C_uint(int_ty, 0))
} else { } else {
s1 s1
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{RealPredicate, OperandBundleDef}; use llvm::OperandBundleDef;
use common::*; use common::*;
use type_::Type; use type_::Type;
use libc::c_char; use libc::c_char;
...@@ -38,6 +38,30 @@ pub trait IntPredicateMethods { ...@@ -38,6 +38,30 @@ pub trait IntPredicateMethods {
fn convert_to_backend_specific(intpre : IntPredicate) -> Self; fn convert_to_backend_specific(intpre : IntPredicate) -> Self;
} }
#[allow(dead_code)]
pub enum RealPredicate {
RealPredicateFalse,
RealOEQ,
RealOGT,
RealOGE,
RealOLT,
RealOLE,
RealONE,
RealORD,
RealUNO,
RealUEQ,
RealUGT,
RealUGE,
RealULT,
RealULE,
RealUNE,
RealPredicateTrue,
}
pub trait RealPredicateMethods {
fn convert_to_backend_specific(realpred : RealPredicate) -> Self;
}
pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll, pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll,
Value : ?Sized, Value : ?Sized,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册