cache Ty::is_simd
This commit is contained in:
parent
612760bea0
commit
015300109d
@ -3179,11 +3179,12 @@ impl<'tcx> TraitDef<'tcx> {
|
||||
bitflags! {
|
||||
flags ADTFlags: u32 {
|
||||
const NO_ADT_FLAGS = 0,
|
||||
const IS_FUNDAMENTAL = 1 << 0,
|
||||
const IS_PHANTOM_DATA = 1 << 1,
|
||||
const IS_DTORCK = 1 << 2, // is this a dtorck type?
|
||||
const IS_DTORCK_VALID = 1 << 3,
|
||||
const IS_ENUM = 1 << 4
|
||||
const IS_ENUM = 1 << 0,
|
||||
const IS_DTORCK = 1 << 1, // is this a dtorck type?
|
||||
const IS_DTORCK_VALID = 1 << 2,
|
||||
const IS_PHANTOM_DATA = 1 << 3,
|
||||
const IS_SIMD = 1 << 4,
|
||||
const IS_FUNDAMENTAL = 1 << 5,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3244,9 +3245,13 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
||||
kind: ADTKind,
|
||||
variants: Vec<VariantDef_<'tcx, 'lt>>) -> Self {
|
||||
let mut flags = ADTFlags::NO_ADT_FLAGS;
|
||||
if tcx.has_attr(did, "fundamental") {
|
||||
let attrs = tcx.get_attrs(did);
|
||||
if attrs.iter().any(|item| item.check_name("fundamental")) {
|
||||
flags = flags | ADTFlags::IS_FUNDAMENTAL;
|
||||
}
|
||||
if attrs.iter().any(|item| item.check_name("simd")) {
|
||||
flags = flags | ADTFlags::IS_SIMD;
|
||||
}
|
||||
if Some(did) == tcx.lang_items.phantom_data() {
|
||||
flags = flags | ADTFlags::IS_PHANTOM_DATA;
|
||||
}
|
||||
@ -3289,6 +3294,11 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> {
|
||||
self.flags.get().intersects(ADTFlags::IS_FUNDAMENTAL)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_simd(&self) -> bool {
|
||||
self.flags.get().intersects(ADTFlags::IS_SIMD)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_phantom_data(&self) -> bool {
|
||||
self.flags.get().intersects(ADTFlags::IS_PHANTOM_DATA)
|
||||
@ -4203,9 +4213,10 @@ impl<'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_simd(&self, cx: &ctxt) -> bool {
|
||||
#[inline]
|
||||
pub fn is_simd(&self) -> bool {
|
||||
match self.sty {
|
||||
TyStruct(def, _) => cx.lookup_simd(def.did),
|
||||
TyStruct(def, _) => def.is_simd(),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -5979,7 +5990,6 @@ impl<'tcx> ctxt<'tcx> {
|
||||
|
||||
/// Obtain the representation annotation for a struct definition.
|
||||
pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
|
||||
// TODO: remove
|
||||
memoized(&self.repr_hint_cache, did, |did: DefId| {
|
||||
Rc::new(if did.krate == LOCAL_CRATE {
|
||||
self.get_attrs(did).iter().flat_map(|meta| {
|
||||
|
@ -621,7 +621,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
|
||||
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false);
|
||||
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false)
|
||||
}
|
||||
ty::TyStruct(_, _) if rhs_t.is_simd(cx.tcx()) => {
|
||||
ty::TyStruct(def, _) if def.is_simd() => {
|
||||
let mut res = C_bool(cx.ccx(), false);
|
||||
for i in 0 .. rhs_t.simd_size(cx.tcx()) {
|
||||
res = Or(cx, res,
|
||||
|
@ -192,7 +192,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
|
||||
let simple = ty.is_scalar() ||
|
||||
ty.is_unique() || ty.is_region_ptr() ||
|
||||
type_is_newtype_immediate(ccx, ty) ||
|
||||
ty.is_simd(tcx);
|
||||
ty.is_simd();
|
||||
if simple && !type_is_fat_ptr(tcx, ty) {
|
||||
return true;
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
debug!("const_expr_unadjusted: te1={}, ty={:?}",
|
||||
cx.tn().val_to_string(te1),
|
||||
ty);
|
||||
let is_simd = ty.is_simd(cx.tcx());
|
||||
let is_simd = ty.is_simd();
|
||||
let intype = if is_simd {
|
||||
ty.simd_type(cx.tcx())
|
||||
} else {
|
||||
@ -754,7 +754,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
(_, None) => cx.sess().span_bug(e.span, "missing struct field"),
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
if ety.is_simd(cx.tcx()) {
|
||||
if ety.is_simd() {
|
||||
C_vector(&cs[..])
|
||||
} else {
|
||||
adt::trans_const(cx, &*repr, discr, &cs[..])
|
||||
@ -850,7 +850,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs)
|
||||
}
|
||||
def::DefStruct(_) => {
|
||||
if ety.is_simd(cx.tcx()) {
|
||||
if ety.is_simd() {
|
||||
C_vector(&arg_vals[..])
|
||||
} else {
|
||||
let repr = adt::represent_type(cx, ety);
|
||||
|
@ -1175,7 +1175,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
StructMDF(StructMemberDescriptionFactory {
|
||||
variant: variant,
|
||||
substs: substs,
|
||||
is_simd: struct_type.is_simd(cx.tcx()),
|
||||
is_simd: struct_type.is_simd(),
|
||||
span: span,
|
||||
})
|
||||
)
|
||||
|
@ -1453,7 +1453,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
// panic occur before the ADT as a whole is ready.
|
||||
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
|
||||
|
||||
if ty.is_simd(bcx.tcx()) {
|
||||
if ty.is_simd() {
|
||||
// Issue 23112: The original logic appeared vulnerable to same
|
||||
// order-of-eval bug. But, SIMD values are tuple-structs;
|
||||
// i.e. functional record update (FRU) syntax is unavailable.
|
||||
@ -1697,7 +1697,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let _icx = push_ctxt("trans_eager_binop");
|
||||
|
||||
let tcx = bcx.tcx();
|
||||
let is_simd = lhs_t.is_simd(tcx);
|
||||
let is_simd = lhs_t.is_simd();
|
||||
let intype = if is_simd {
|
||||
lhs_t.simd_type(tcx)
|
||||
} else {
|
||||
@ -2502,7 +2502,7 @@ fn build_unchecked_rshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// #1877, #10183: Ensure that input is always valid
|
||||
let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc);
|
||||
let tcx = bcx.tcx();
|
||||
let is_simd = lhs_t.is_simd(tcx);
|
||||
let is_simd = lhs_t.is_simd();
|
||||
let intype = if is_simd {
|
||||
lhs_t.simd_type(tcx)
|
||||
} else {
|
||||
|
@ -449,7 +449,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) {
|
||||
if !tcx.sess.features.borrow().simd_ffi {
|
||||
let check = |ast_ty: &ast::Ty, ty: ty::Ty| {
|
||||
if ty.is_simd(tcx) {
|
||||
if ty.is_simd() {
|
||||
tcx.sess.span_err(ast_ty.span,
|
||||
&format!("use of SIMD type `{}` in FFI is highly experimental and \
|
||||
may result in invalid code",
|
||||
|
@ -419,7 +419,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in
|
||||
let ccx = bcx.ccx();
|
||||
// First get the size of all statically known fields.
|
||||
// Don't use type_of::sizing_type_of because that expects t to be sized.
|
||||
assert!(!t.is_simd(bcx.tcx()));
|
||||
assert!(!t.is_simd());
|
||||
let repr = adt::represent_type(ccx, t);
|
||||
let sizing_type = adt::sizing_type_context_of(ccx, &*repr, true);
|
||||
debug!("DST {} sizing_type: {}", t, sizing_type.to_string());
|
||||
|
@ -222,7 +222,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
||||
}
|
||||
|
||||
ty::TyStruct(..) => {
|
||||
if t.is_simd(cx.tcx()) {
|
||||
if t.is_simd() {
|
||||
let llet = type_of(cx, t.simd_type(cx.tcx()));
|
||||
let n = t.simd_size(cx.tcx()) as u64;
|
||||
ensure_array_fits_in_address_space(cx, llet, n, t);
|
||||
@ -404,7 +404,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
|
||||
adt::type_of(cx, &*repr)
|
||||
}
|
||||
ty::TyStruct(def, ref substs) => {
|
||||
if t.is_simd(cx.tcx()) {
|
||||
if t.is_simd() {
|
||||
let llet = in_memory_type_of(cx, t.simd_type(cx.tcx()));
|
||||
let n = t.simd_size(cx.tcx()) as u64;
|
||||
ensure_array_fits_in_address_space(cx, llet, n, t);
|
||||
@ -436,7 +436,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
|
||||
// If this was an enum or struct, fill in the type now.
|
||||
match t.sty {
|
||||
ty::TyEnum(..) | ty::TyStruct(..) | ty::TyClosure(..)
|
||||
if !t.is_simd(cx.tcx()) => {
|
||||
if !t.is_simd() => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
adt::finish_type_of(cx, &*repr, &mut llty);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use super::{
|
||||
structurally_resolved_type,
|
||||
};
|
||||
use middle::traits;
|
||||
use middle::ty::{self, Ty, HasTypeFlags};
|
||||
use middle::ty::{Ty, HasTypeFlags};
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::parse::token;
|
||||
@ -41,7 +41,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
let lhs_ty = structurally_resolved_type(fcx, lhs_expr.span, fcx.expr_ty(lhs_expr));
|
||||
let rhs_ty = structurally_resolved_type(fcx, rhs_expr.span, fcx.expr_ty(rhs_expr));
|
||||
|
||||
if is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op) {
|
||||
if is_builtin_binop(lhs_ty, rhs_ty, op) {
|
||||
enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
|
||||
fcx.write_nil(expr.id);
|
||||
} else {
|
||||
@ -86,7 +86,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
// traits, because their return type is not bool. Perhaps this
|
||||
// should change, but for now if LHS is SIMD we go down a
|
||||
// different path that bypassess all traits.
|
||||
if lhs_ty.is_simd(fcx.tcx()) {
|
||||
if lhs_ty.is_simd() {
|
||||
check_expr_coercable_to_type(fcx, rhs_expr, lhs_ty);
|
||||
let rhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr));
|
||||
let return_ty = enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
|
||||
@ -123,7 +123,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
let rhs_ty = fcx.resolve_type_vars_if_possible(rhs_ty);
|
||||
if
|
||||
!lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() &&
|
||||
is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op)
|
||||
is_builtin_binop(lhs_ty, rhs_ty, op)
|
||||
{
|
||||
let builtin_return_ty =
|
||||
enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
|
||||
@ -143,7 +143,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
op: ast::BinOp)
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
debug_assert!(is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op));
|
||||
debug_assert!(is_builtin_binop(lhs_ty, rhs_ty, op));
|
||||
|
||||
let tcx = fcx.tcx();
|
||||
match BinOpCategory::from(op) {
|
||||
@ -156,7 +156,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
BinOpCategory::Shift => {
|
||||
// For integers, the shift amount can be of any integral
|
||||
// type. For simd, the type must match exactly.
|
||||
if lhs_ty.is_simd(tcx) {
|
||||
if lhs_ty.is_simd() {
|
||||
demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty);
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty);
|
||||
|
||||
// if this is simd, result is same as lhs, else bool
|
||||
if lhs_ty.is_simd(tcx) {
|
||||
if lhs_ty.is_simd() {
|
||||
let unit_ty = lhs_ty.simd_type(tcx);
|
||||
debug!("enforce_builtin_binop_types: lhs_ty={:?} unit_ty={:?}",
|
||||
lhs_ty,
|
||||
@ -415,8 +415,7 @@ impl BinOpCategory {
|
||||
/// Reason #2 is the killer. I tried for a while to always use
|
||||
/// overloaded logic and just check the types in constants/trans after
|
||||
/// the fact, and it worked fine, except for SIMD types. -nmatsakis
|
||||
fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
|
||||
lhs: Ty<'tcx>,
|
||||
fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>,
|
||||
rhs: Ty<'tcx>,
|
||||
op: ast::BinOp)
|
||||
-> bool
|
||||
@ -429,28 +428,28 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
|
||||
BinOpCategory::Shift => {
|
||||
lhs.references_error() || rhs.references_error() ||
|
||||
lhs.is_integral() && rhs.is_integral() ||
|
||||
lhs.is_simd(cx) && rhs.is_simd(cx)
|
||||
lhs.is_simd() && rhs.is_simd()
|
||||
}
|
||||
|
||||
BinOpCategory::Math => {
|
||||
lhs.references_error() || rhs.references_error() ||
|
||||
lhs.is_integral() && rhs.is_integral() ||
|
||||
lhs.is_floating_point() && rhs.is_floating_point() ||
|
||||
lhs.is_simd(cx) && rhs.is_simd(cx)
|
||||
lhs.is_simd() && rhs.is_simd()
|
||||
}
|
||||
|
||||
BinOpCategory::Bitwise => {
|
||||
lhs.references_error() || rhs.references_error() ||
|
||||
lhs.is_integral() && rhs.is_integral() ||
|
||||
lhs.is_floating_point() && rhs.is_floating_point() ||
|
||||
lhs.is_simd(cx) && rhs.is_simd(cx) ||
|
||||
lhs.is_simd() && rhs.is_simd() ||
|
||||
lhs.is_bool() && rhs.is_bool()
|
||||
}
|
||||
|
||||
BinOpCategory::Comparison => {
|
||||
lhs.references_error() || rhs.references_error() ||
|
||||
lhs.is_scalar() && rhs.is_scalar() ||
|
||||
lhs.is_simd(cx) && rhs.is_simd(cx)
|
||||
lhs.is_simd() && rhs.is_simd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user