Skip to content

Commit

Permalink
moved Type to u16
Browse files Browse the repository at this point in the history
  • Loading branch information
sparker-arm committed Jun 10, 2022
1 parent 597fed1 commit fbd0e5a
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 115 deletions.
41 changes: 14 additions & 27 deletions cranelift/codegen/meta/src/cdsl/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl ValueType {
}

/// Find the unique number associated with this type.
pub fn number(&self) -> u8 {
pub fn number(&self) -> u16 {
match *self {
ValueType::Lane(l) => l.number(),
ValueType::Reference(r) => r.number(),
Expand Down Expand Up @@ -185,7 +185,7 @@ impl LaneType {
}

/// Find the unique number associated with this lane type.
pub fn number(self) -> u8 {
pub fn number(self) -> u16 {
constants::LANE_BASE
+ match self {
LaneType::Bool(shared_types::Bool::B1) => 0,
Expand Down Expand Up @@ -371,16 +371,11 @@ impl VectorType {
///
/// Vector types are encoded with the lane type in the low 4 bits and
/// log2(lanes) in the high 4 bits, giving a range of 2-256 lanes.
/// Dynamic vectors have their lane type encoded similarily but 2 bits
/// are used for minimum number of lanes
/// 1: Half the number of lanes relative to a naturally packed 128-bit vector.
/// 2: A naturally packed 128-bit vector.
/// 3: Twice the number of lanes relative to a naturally packed 128-bit vector.
pub fn number(&self) -> u8 {
pub fn number(&self) -> u16 {
let lanes_log_2: u32 = 63 - self.lane_count().leading_zeros();
let base_num = u32::from(self.base.number());
let num = (lanes_log_2 << 4) + base_num;
num as u8
num as u16
}
}

Expand Down Expand Up @@ -446,23 +441,15 @@ impl DynamicVectorType {

/// Find the unique number associated with this vector type.
///
/// Dynamic vector types are encoded with the lane type in the low 4 bits and
/// 2 bits to encode the number of lanes, relative to a naturally packed 128-bit
/// vector:
/// 1 = half the number of lanes
/// 2 = natural number of lanes
/// 3 = double the number of lanes
pub fn number(&self) -> u8 {
/// Dynamic vector types are encoded in the same manner as `VectorType`,
/// with lane type in the low 4 bits and the log2(lane_count). We add the
/// `VECTOR_BASE` to move these numbers into the range beyond the fixed
/// SIMD types.
pub fn number(&self) -> u16 {
let base_num = u32::from(self.base.number());
let log2_lane_bits: u32 = 63 - self.lane_bits().leading_zeros();
assert!(log2_lane_bits <= 7);
let natural_lane_count: u32 = 128 >> log2_lane_bits;
let lane_encoding: u32 = 1 + (self.minimum_lane_count() as u32 / natural_lane_count);
assert_eq!(lane_encoding, lane_encoding & 0b11);
assert_ne!(lane_encoding, 0);
let num = 0xc0 + (lane_encoding << 4) + (0xF & base_num);
assert!(num <= 255);
num as u8
let lanes_log_2: u32 = 63 - self.minimum_lane_count().leading_zeros();
let num = 0x80 + (lanes_log_2 << 4) + base_num;
num as u16
}
}

Expand Down Expand Up @@ -514,7 +501,7 @@ impl SpecialType {
}

/// Find the unique number associated with this special type.
pub fn number(self) -> u8 {
pub fn number(self) -> u16 {
match self {
SpecialType::Flag(shared_types::Flag::IFlags) => 1,
SpecialType::Flag(shared_types::Flag::FFlags) => 2,
Expand Down Expand Up @@ -587,7 +574,7 @@ impl ReferenceType {
}

/// Find the unique number associated with this reference type.
pub fn number(self) -> u8 {
pub fn number(self) -> u16 {
constants::REFERENCE_BASE
+ match self {
ReferenceType(shared_types::Reference::R32) => 0,
Expand Down
33 changes: 26 additions & 7 deletions cranelift/codegen/meta/src/cdsl/typevar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use std::rc::Rc;

use crate::cdsl::types::{LaneType, ReferenceType, SpecialType, ValueType};

const MAX_DYNAMIC_LANES: u16 = 32;
const MAX_LANES: u16 = 256;
const MAX_BITS: u16 = 128;
const MAX_FLOAT_BITS: u16 = 64;
Expand Down Expand Up @@ -76,6 +75,8 @@ impl TypeVar {
};

builder = builder.simd_lanes(num_lanes..num_lanes);

// Only generate dynamic types for multiple lanes.
if num_lanes > 1 {
builder = builder.dynamic_simd_lanes(num_lanes..num_lanes);
}
Expand Down Expand Up @@ -710,7 +711,7 @@ impl TypeSetBuilder {

TypeSet::new(
range_to_set(self.simd_lanes.to_range(min_lanes..MAX_LANES, Some(1))),
range_to_set(self.dynamic_simd_lanes.to_range(2..MAX_DYNAMIC_LANES, None)),
range_to_set(self.dynamic_simd_lanes.to_range(2..MAX_LANES, None)),
range_to_set(self.ints.to_range(8..MAX_BITS, None)),
range_to_set(self.floats.to_range(32..64, None)),
bools,
Expand Down Expand Up @@ -848,7 +849,7 @@ fn test_typevar_builder() {
.dynamic_simd_lanes(Interval::All)
.includes_scalars(false)
.build();
assert_eq!(type_set.dynamic_lanes, num_set![2, 4, 8, 16, 32]);
assert_eq!(type_set.dynamic_lanes, num_set![2, 4, 8, 16, 32, 64, 128, 256]);
assert_eq!(type_set.ints, num_set![8, 16, 32, 64, 128]);
assert_eq!(type_set.bools, num_set![1, 8, 16, 32, 64, 128]);
assert_eq!(type_set.floats, num_set![32, 64]);
Expand All @@ -860,7 +861,7 @@ fn test_typevar_builder() {
.dynamic_simd_lanes(Interval::All)
.includes_scalars(false)
.build();
assert_eq!(type_set.dynamic_lanes, num_set![2, 4, 8, 16, 32]);
assert_eq!(type_set.dynamic_lanes, num_set![2, 4, 8, 16, 32, 64, 128, 256]);
assert_eq!(type_set.floats, num_set![32, 64]);
assert_eq!(type_set.lanes, num_set![1]);
assert!(type_set.ints.is_empty());
Expand All @@ -877,13 +878,31 @@ fn test_typevar_builder() {

#[test]
fn test_dynamic_to_vector() {
// We don't generate single lane dynamic types, so the maximum number of
// lanes we support is 128, as MAX_BITS is 256.
assert_eq!(
TypeSetBuilder::new()
.dynamic_simd_lanes(Interval::All)
.ints(Interval::All)
.build()
.dynamic_to_vector(),
TypeSetBuilder::new().simd_lanes(2..128).ints(Interval::All).build()
);
assert_eq!(
TypeSetBuilder::new()
.dynamic_simd_lanes(Interval::All)
.bools(Interval::All)
.build()
.dynamic_to_vector(),
TypeSetBuilder::new().simd_lanes(2..128).bools(Interval::All).build()
);
assert_eq!(
TypeSetBuilder::new()
.dynamic_simd_lanes(2..8)
.ints(8..32)
.dynamic_simd_lanes(Interval::All)
.floats(Interval::All)
.build()
.dynamic_to_vector(),
TypeSetBuilder::new().simd_lanes(2..8).ints(8..32).build()
TypeSetBuilder::new().simd_lanes(2..128).floats(Interval::All).build()
);
}

Expand Down
2 changes: 1 addition & 1 deletion cranelift/codegen/meta/src/gen_inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,11 +688,11 @@ pub(crate) fn gen_typesets_table(type_sets: &UniqueTable<TypeSet>, fmt: &mut For
fmt.indent(|fmt| {
fmt.comment(typeset_to_string(ts));
gen_bitset(&ts.lanes, "lanes", 16, fmt);
gen_bitset(&ts.dynamic_lanes, "dynamic_lanes", 16, fmt);
gen_bitset(&ts.ints, "ints", 8, fmt);
gen_bitset(&ts.floats, "floats", 8, fmt);
gen_bitset(&ts.bools, "bools", 8, fmt);
gen_bitset(&ts.refs, "refs", 8, fmt);
gen_bitset(&ts.dynamic_lanes, "dynamic_lanes", 8, fmt);
});
fmt.line("},");
}
Expand Down
5 changes: 1 addition & 4 deletions cranelift/codegen/meta/src/gen_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,9 @@ fn emit_types(fmt: &mut srcgen::Formatter) {
}

// Emit vector definitions for common SIMD sizes.
// Emit dynamic vector definitions.
for vec_size in &[64_u64, 128, 256, 512] {
emit_vectors(*vec_size, fmt);
}

// Emit dynamic vector definitions.
for vec_size in &[64_u64, 128, 256] {
emit_dynamic_vectors(*vec_size, fmt);
}
}
Expand Down
31 changes: 10 additions & 21 deletions cranelift/codegen/shared/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,25 @@
// Numbering scheme for value types:
//
// 0: Void
// 0x01-0x2f: Special types
// 0x30-0x3d: Lane types
// 0x3e-0x3f: Reference types
// 0x40-0xbf: Vector types
// 0xc0-0xff: Dynamic vector types
// 0x01-0x6f: Special types
// 0x70-0x7d: Lane types
// 0x7e-0x7f: Reference types
// 0x80-0xff: Vector types
// 0x100-0x17f: Dynamic Vector types
//
// Vector types are encoded with the lane type in the low 4 bits and log2(lanes)
// in the next highest 4 bits, giving a range of 2-256 lanes.

// Dynamic vector types are encoded with the lane type in the low 4 bits with 2
// bits to encode the number of minimum lanes, relative to a naturally packed 128-bit
// vector: 1 = half, 2 = natural, 3 = double.
// Dynamic vector types are encoded similarily.

/// Start of the lane types.
pub const LANE_BASE: u8 = 0x30;
pub const LANE_BASE: u16 = 0x70;

/// Base for reference types.
pub const REFERENCE_BASE: u8 = 0x3E;
pub const REFERENCE_BASE: u16 = 0x7E;

/// Start of the 2-lane vector types.
pub const VECTOR_BASE: u8 = 0x40;
pub const VECTOR_BASE: u16 = 0x80;

/// Start of the dynamic vector types.
pub const DYNAMIC_VECTOR_BASE: u8 = 0xc0;

/// Dynamic encoding of half the number of lanes, relative to a naturally packed 128-bit vector.
pub const HALF_DYNAMIC_LANES: u8 = 1;

/// Dynamic encoding of the number of lanes in a naturally packed 128-bit vector.
pub const NATURAL_DYNAMIC_LANES: u8 = 2;

/// Dynamic encoding of double the number of lanes, relative to a naturally packed 128-bit vector.
pub const DOUBLE_DYNAMIC_LANES: u8 = 3;
pub const DYNAMIC_VECTOR_BASE: u16 = 0x100;
12 changes: 6 additions & 6 deletions cranelift/codegen/src/ir/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ pub struct ValueTypeSet {
/// Allowed ref widths
pub refs: BitSet8,
/// Allowed dynamic vectors minimum lane sizes
pub dynamic_lanes: BitSet8,
pub dynamic_lanes: BitSet16,
}

impl ValueTypeSet {
Expand Down Expand Up @@ -875,7 +875,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
bools: BitSet8::from_range(3, 7),
refs: BitSet8::from_range(5, 7),
dynamic_lanes: BitSet8::from_range(0, 4),
dynamic_lanes: BitSet16::from_range(0, 4),
};
assert!(!vts.contains(I8));
assert!(vts.contains(I32));
Expand All @@ -896,7 +896,7 @@ mod tests {
floats: BitSet8::from_range(5, 7),
bools: BitSet8::from_range(3, 7),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet8::from_range(0, 8),
dynamic_lanes: BitSet16::from_range(0, 8),
};
assert_eq!(vts.example().to_string(), "f32");

Expand All @@ -906,7 +906,7 @@ mod tests {
floats: BitSet8::from_range(5, 7),
bools: BitSet8::from_range(3, 7),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet8::from_range(0, 8),
dynamic_lanes: BitSet16::from_range(0, 8),
};
assert_eq!(vts.example().to_string(), "f32x2");

Expand All @@ -916,7 +916,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
bools: BitSet8::from_range(3, 7),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet8::from_range(0, 8),
dynamic_lanes: BitSet16::from_range(0, 8),
};
assert!(!vts.contains(B32X2));
assert!(vts.contains(B32X4));
Expand All @@ -930,7 +930,7 @@ mod tests {
floats: BitSet8::from_range(0, 0),
bools: BitSet8::from_range(0, 0),
refs: BitSet8::from_range(0, 0),
dynamic_lanes: BitSet8::from_range(0, 8),
dynamic_lanes: BitSet16::from_range(0, 8),
};
assert!(vts.contains(I32));
assert!(vts.contains(I32X4));
Expand Down
46 changes: 9 additions & 37 deletions cranelift/codegen/src/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use target_lexicon::{PointerWidth, Triple};
///
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Type(u8);
pub struct Type(u16);

/// Not a valid type. Can't be loaded or stored. Can't be part of a SIMD vector.
pub const INVALID: Type = Type(0);
Expand Down Expand Up @@ -298,21 +298,15 @@ impl Type {
if self.is_dynamic_vector() {
0
} else {
self.0.saturating_sub(constants::LANE_BASE) >> 4
(self.0.saturating_sub(constants::LANE_BASE) >> 4).try_into().unwrap()
}
}

/// Get log_2 of the number of lanes in this vector/dynamic type.
pub fn log2_min_lane_count(self) -> u8 {
if self.is_dynamic_vector() {
match self.min_lane_count() {
2 => 1,
4 => 2,
8 => 3,
16 => 4,
32 => 5,
_ => unreachable!("unexpected min_lane_count: {:?}", self.min_lane_count()),
}
(self.0.saturating_sub(constants::VECTOR_BASE + constants::LANE_BASE) >> 4)
.try_into().unwrap()
} else {
self.log2_lane_count()
}
Expand All @@ -333,20 +327,7 @@ impl Type {
/// dynamic types.
pub fn min_lane_count(self) -> u16 {
if self.is_dynamic_vector() {
let log2_lane_bits: u32 = self.log2_lane_bits() as u32;
let natural_lane_count: u32 = 128 >> log2_lane_bits;
let min_lanes_encoding = (self.0 - 0xc0) >> 4;

assert!(log2_lane_bits <= 7);
assert!(natural_lane_count <= 32);
assert!(natural_lane_count * self.lane_bits() as u32 <= 256);
let min_lane_count = match min_lanes_encoding {
1 => natural_lane_count >> 1,
2 => natural_lane_count,
3 => natural_lane_count << 1,
_ => unreachable!("unexpected min_lanes_encoding: {}", min_lanes_encoding),
};
min_lane_count as u16
1 << self.log2_min_lane_count()
} else {
1 << self.log2_lane_count()
}
Expand Down Expand Up @@ -390,8 +371,8 @@ impl Type {
}
let log2_lanes: u32 = n.trailing_zeros();
let new_type = u32::from(self.0) + (log2_lanes << 4);
if new_type < 0x100 && (new_type as u8) < constants::DYNAMIC_VECTOR_BASE {
Some(Self(new_type as u8))
if new_type < 0x100 && (new_type as u16) < constants::DYNAMIC_VECTOR_BASE {
Some(Self(new_type as u16))
} else {
None
}
Expand All @@ -403,14 +384,7 @@ impl Type {
if self.bits() > 256 {
return None;
}
let lane_count: u32 = self.lane_count() as u32;
let log2_lane_bits: u32 = self.log2_lane_bits() as u32;
let natural_lane_count: u32 = 128 >> log2_lane_bits;
let lane_encoding: u32 = 1 + (lane_count / natural_lane_count);
assert_eq!(lane_encoding, lane_encoding & 0b11);
let new_ty = constants::DYNAMIC_VECTOR_BASE
+ ((lane_encoding as u8) << 4)
+ (0xF & u8::from(self.0));
let new_ty = self.0 + constants::VECTOR_BASE;
let ty = Some(Self(new_ty));
assert!(ty.unwrap().is_dynamic_vector());
return ty;
Expand All @@ -419,9 +393,7 @@ impl Type {
/// Convert a dynamic vector type to a fixed one.
pub fn dynamic_to_vector(self) -> Option<Self> {
assert!(self.is_dynamic_vector());
let lanes_log_2: u32 = 63 - self.min_lane_count().leading_zeros();
let base_num = self.lane_type().0;
Some(Self(((lanes_log_2 as u8) << 4) + base_num))
Some(Self(self.0 - constants::VECTOR_BASE))
}

/// Get a SIMD vector with half the number of lanes.
Expand Down
Loading

0 comments on commit fbd0e5a

Please sign in to comment.