pub struct Type(/* private fields */);Expand description
An IR type.
Four bytes, packed, because a type sits on every value in a function and a function has a great many values. The alternative, an enum holding a lane type and a lane count, comes out at twelve bytes for the same information, and the tables this goes in are walked often enough for that to show.
The packing is the low sixteen bits for the width in bits, the next fourteen for the lane
count biased by one, and the top two for which of the four kinds it is. That gives a
largest integer of Type::MAX_BITS and a widest vector of Type::MAX_LANES, both of
which are past anything a target has.
use rucc_ir::{Float, Type};
assert_eq!(Type::int(32).to_string(), "i32");
assert_eq!(Type::float(Float::F64).to_string(), "f64");
assert_eq!(Type::PTR.to_string(), "ptr");
assert_eq!(Type::vector(Type::int(8), 16).to_string(), "i8x16");
assert_eq!(size_of::<Type>(), 4);Implementations§
Source§impl Type
impl Type
Sourcepub const MAX_BITS: u32 = BITS_MASK
pub const MAX_BITS: u32 = BITS_MASK
The widest integer that can be represented, which is what limits _BitInt.
Sixteen bits of width is more than any target’s BITINT_MAXWIDTH and more than any
vector register, and it leaves room in the same four bytes for the lane count.
Sourcepub const fn int(bits: u32) -> Self
pub const fn int(bits: u32) -> Self
An integer bits wide.
§Panics
Panics if bits is zero or above Type::MAX_BITS. A zero-width integer is not a
thing the IR has, and a caller that computed one has a bug that gets much harder to
find if it is allowed to travel.
Sourcepub const fn vector(lane: Self, lanes: u32) -> Self
pub const fn vector(lane: Self, lanes: u32) -> Self
A vector of lanes copies of lane.
§Panics
Panics if lane is not an integer or a floating point type, if it is itself a vector,
or if lanes is zero or above Type::MAX_LANES. A vector of pointers is not in the
instruction set, so admitting the type would mean admitting a value nothing can be done
with.
Sourcepub const fn bits(self) -> u32
pub const fn bits(self) -> u32
The width of one lane in bits, which for a scalar is the width of the type.
Zero for void and for ptr, since the width of an address is a property of the
target and not of the type. Ask the target for it.
Sourcepub const fn with_lane(self, lane: Self) -> Self
pub const fn with_lane(self, lane: Self) -> Self
The same shape as this, with the lane type replaced.
This is what a comparison does: icmp over i32x4 produces i1x4, and the rule that
the lane count is carried across is easier to get right in one place than at every
instruction that needs it.
§Panics
Panics under the same conditions as Type::vector.
Sourcepub const fn is_ptr(self) -> bool
pub const fn is_ptr(self) -> bool
Whether this is an address. A vector of pointers cannot be built, so this is scalar.
Sourcepub fn parse(text: &str) -> Option<Self>
pub fn parse(text: &str) -> Option<Self>
Parses the textual form, which is what the printer writes.
use rucc_ir::Type;
assert_eq!(Type::parse("i32"), Some(Type::int(32)));
assert_eq!(Type::parse("f32x4"), Some(Type::vector(Type::float(rucc_ir::Float::F32), 4)));
assert_eq!(Type::parse("i0"), None);
assert_eq!(Type::parse("i32 "), None);