From cca91024298b92f5bff5fc7353155aff0eef38e5 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Thu, 29 Jul 2021 04:55:28 +0000 Subject: [PATCH] Change bitmasks to use less opaque type --- crates/core_simd/src/lane_count.rs | 7 ++++++- crates/core_simd/src/masks.rs | 4 ++-- crates/core_simd/src/masks/bitmask.rs | 10 ++++++---- crates/core_simd/src/masks/full_masks.rs | 10 +++++----- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index 8fe204dff98..b017e7d137e 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -6,9 +6,14 @@ pub trait Sealed {} /// A type representing a vector lane count. pub struct LaneCount; +impl LaneCount { + /// The number of bytes in a bitmask with this many lanes. + pub const BITMASK_LEN: usize = (LANES + 7) / 8; +} + /// Helper trait for vector lane counts. pub trait SupportedLaneCount: Sealed { - /// The bitmask representation of a mask. + #[doc(hidden)] type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; #[doc(hidden)] diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index d3338a6d366..ba7da704f61 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -160,12 +160,12 @@ pub fn set(&mut self, lane: usize, value: bool) { } /// Convert this mask to a bitmask, with one bit set per lane. - pub fn to_bitmask(self) -> as crate::SupportedLaneCount>::BitMask { + pub fn to_bitmask(self) -> [u8; crate::LaneCount::::BITMASK_LEN] { self.0.to_bitmask() } /// Convert a bitmask to a mask. - pub fn from_bitmask(bitmask: as crate::SupportedLaneCount>::BitMask) -> Self { + pub fn from_bitmask(bitmask: [u8; crate::LaneCount::::BITMASK_LEN]) -> Self { Self(<$inner_ty>::from_bitmask(bitmask)) } } diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index b6897728988..69edd523587 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -128,13 +128,15 @@ pub unsafe fn from_int_unchecked(value: V) -> Self } #[inline] - pub fn to_bitmask(self) -> as SupportedLaneCount>::BitMask { - self.0 + pub fn to_bitmask(self) -> [u8; LaneCount::::BITMASK_LEN] { + // Safety: these are the same type and we are laundering the generic + unsafe { core::mem::transmute_copy(&self.0) } } #[inline] - pub fn from_bitmask(bitmask: as SupportedLaneCount>::BitMask) -> Self { - Self(bitmask) + pub fn from_bitmask(bitmask: [u8; LaneCount::::BITMASK_LEN]) -> Self { + // Safety: these are the same type and we are laundering the generic + Self(unsafe { core::mem::transmute_copy(&bitmask) }) } #[inline] diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index af36571134e..2923cf1964a 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -103,15 +103,15 @@ pub unsafe fn from_int_unchecked(value: crate::$type) -> Self { } #[inline] - pub fn to_bitmask(self) -> as crate::SupportedLaneCount>::BitMask { + pub fn to_bitmask(self) -> [u8; crate::LaneCount::::BITMASK_LEN] { unsafe { // TODO remove the transmute when rustc can use arrays of u8 as bitmasks assert_eq!( - core::mem::size_of::< as crate::SupportedLaneCount>::BitMask>(), core::mem::size_of::< as crate::SupportedLaneCount>::IntBitMask>(), + crate::LaneCount::::BITMASK_LEN, ); let bitmask: as crate::SupportedLaneCount>::IntBitMask = crate::intrinsics::simd_bitmask(self.0); - let mut bitmask: as crate::SupportedLaneCount>::BitMask = core::mem::transmute_copy(&bitmask); + let mut bitmask: [u8; crate::LaneCount::::BITMASK_LEN] = core::mem::transmute_copy(&bitmask); // There is a bug where LLVM appears to implement this operation with the wrong // bit order. @@ -127,7 +127,7 @@ pub fn to_bitmask(self) -> as crate::SupportedLaneCou } #[inline] - pub fn from_bitmask(mut bitmask: as crate::SupportedLaneCount>::BitMask) -> Self { + pub fn from_bitmask(mut bitmask: [u8; crate::LaneCount::::BITMASK_LEN]) -> Self { unsafe { // There is a bug where LLVM appears to implement this operation with the wrong // bit order. @@ -140,8 +140,8 @@ pub fn from_bitmask(mut bitmask: as crate::SupportedL // TODO remove the transmute when rustc can use arrays of u8 as bitmasks assert_eq!( - core::mem::size_of::< as crate::SupportedLaneCount>::BitMask>(), core::mem::size_of::< as crate::SupportedLaneCount>::IntBitMask>(), + crate::LaneCount::::BITMASK_LEN, ); let bitmask: as crate::SupportedLaneCount>::IntBitMask = core::mem::transmute_copy(&bitmask);