Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub mod mem;
pub mod qptr;
pub mod scalar;
pub mod spv;
pub mod vector;

use smallvec::SmallVec;
use std::borrow::Cow;
Expand Down Expand Up @@ -544,6 +545,13 @@ pub enum TypeKind {
#[from]
Scalar(scalar::Type),

/// Vector (small array of [`scalar`]s) type, with some limitations on the
/// supported component counts (but all standard ones should be included).
///
/// See also the [`vector`] module for more documentation and definitions.
#[from]
Vector(vector::Type),

/// "Quasi-pointer", an untyped pointer-like abstract scalar that can represent
/// both memory locations (in any address space) and other kinds of locations
/// (e.g. SPIR-V `OpVariable`s in non-memory "storage classes").
Expand Down Expand Up @@ -585,7 +593,7 @@ macro_rules! impl_intern_type_kind {
})+
}
}
impl_intern_type_kind!(TypeKind, scalar::Type);
impl_intern_type_kind!(TypeKind, scalar::Type, vector::Type);

// HACK(eddyb) this is like `Either<Type, Const>`, only used in `TypeKind::SpvInst`,
// and only because SPIR-V type definitions can references both types and consts.
Expand All @@ -603,6 +611,12 @@ impl Type {
_ => None,
}
}
pub fn as_vector(self, cx: &Context) -> Option<vector::Type> {
match cx[self].kind {
TypeKind::Vector(ty) => Some(ty),
_ => None,
}
}
}

/// Interned handle for a [`ConstDef`](crate::ConstDef) (a constant value).
Expand Down Expand Up @@ -638,6 +652,18 @@ pub enum ConstKind {
#[from]
Scalar(scalar::Const),

/// Vector (small array of [`scalar`]s) constant, which must have
/// a type of [`TypeKind::Vector`] (of the same [`vector::Type`]).
///
/// See also the [`vector`] module for more documentation and definitions.
//
// FIXME(eddyb) maybe document the 128-bit limitation inherited from `scalar::Const`?
// FIXME(eddyb) this technically makes the `vector::Type` redundant, could
// it get out of sync? (perhaps "forced canonicalization" could be used to
// enforce that interning simply doesn't allow such scenarios?).
#[from]
Vector(vector::Const),

// FIXME(eddyb) maybe merge these? however, their connection is somewhat
// tenuous (being one of the LLVM-isms SPIR-V inherited, among other things),
// there's still the need to rename "global variable" post-`Var`-refactor,
Expand Down Expand Up @@ -674,7 +700,7 @@ macro_rules! impl_intern_const_kind {
})+
}
}
impl_intern_const_kind!(scalar::Const);
impl_intern_const_kind!(scalar::Const, vector::Const);

// HACK(eddyb) on `Const` instead of `ConstDef` for ergonomics reasons.
impl Const {
Expand All @@ -684,6 +710,12 @@ impl Const {
_ => None,
}
}
pub fn as_vector(self, cx: &Context) -> Option<&vector::Const> {
match &cx[self].kind {
ConstKind::Vector(ct) => Some(ct),
_ => None,
}
}
}

/// Declarations ([`GlobalVarDecl`], [`FuncDecl`]) can contain a full definition,
Expand Down Expand Up @@ -968,6 +1000,12 @@ pub enum NodeKind {
#[from]
Scalar(scalar::Op),

/// Vector (small array of [`scalar`]s) pure operations.
///
/// See also the [`vector`] module for more documentation and definitions.
#[from]
Vector(vector::Op),

FuncCall(Func),

/// Memory-specific operations (see [`mem::MemOp`]).
Expand Down
3 changes: 2 additions & 1 deletion src/mem/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ impl<'a> GatherAccesses<'a> {
}

DataInstKind::Scalar(_)
| DataInstKind::Vector(_)
| DataInstKind::FuncCall(_)
| DataInstKind::Mem(_)
| DataInstKind::QPtr(_)
Expand All @@ -951,7 +952,7 @@ impl<'a> GatherAccesses<'a> {
unreachable!()
}

DataInstKind::Scalar(_) => {}
DataInstKind::Scalar(_) | DataInstKind::Vector(_) => {}

&DataInstKind::FuncCall(callee) => {
match self.gather_accesses_in_func(module, callee) {
Expand Down
31 changes: 19 additions & 12 deletions src/mem/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,21 @@ impl<'a> LayoutCache<'a> {
}
TypeKind::Scalar(ty) => return Ok(scalar(ty.bit_width())),

TypeKind::Vector(ty) => {
let len = u32::from(ty.elem_count.get());
return array(
cx.intern(ty.elem),
ArrayParams {
fixed_len: Some(len),
known_stride: None,

// NOTE(eddyb) this is specifically Vulkan "base alignment".
min_legacy_align: 1,
legacy_align_multiplier: if len <= 2 { 2 } else { 4 },
},
);
}

// FIXME(eddyb) treat `QPtr`s as scalars.
TypeKind::QPtr => {
return Err(LayoutError(Diag::bug(
Expand Down Expand Up @@ -362,26 +377,18 @@ impl<'a> LayoutCache<'a> {
// FIXME(eddyb) categorize `OpTypePointer` by storage class and split on
// logical vs physical here.
scalar_with_size_and_align(self.config.logical_ptr_size_align)
} else if [wk.OpTypeVector, wk.OpTypeMatrix].contains(&spv_inst.opcode) {
let len = short_imm_at(0);
let (min_legacy_align, legacy_align_multiplier) = if spv_inst.opcode == wk.OpTypeVector
{
// NOTE(eddyb) this is specifically Vulkan "base alignment".
(1, if len <= 2 { 2 } else { 4 })
} else {
(self.config.min_aggregate_legacy_align, 1)
};
} else if spv_inst.opcode == wk.OpTypeMatrix {
// NOTE(eddyb) `RowMajor` is disallowed on `OpTypeStruct` members below.
array(
match type_and_const_inputs[..] {
[TypeOrConst::Type(elem_type)] => elem_type,
_ => unreachable!(),
},
ArrayParams {
fixed_len: Some(len),
fixed_len: Some(short_imm_at(0)),
known_stride: None,
min_legacy_align,
legacy_align_multiplier,
min_legacy_align: self.config.min_aggregate_legacy_align,
legacy_align_multiplier: 1,
},
)?
} else if [wk.OpTypeArray, wk.OpTypeRuntimeArray].contains(&spv_inst.opcode) {
Expand Down
Loading
Loading