metal2vulkan 0.1.0

Translate Metal AIR / LLVM IR to Vulkan SPIR-V with a native Rust emitter
Documentation
use super::*;
mod air_calls;
mod atomics;
mod binary_ops;
mod conversions;
mod freeze_unary;
mod intrinsics;
mod operands;

fn is_coherent_air_store(callee: &str) -> bool {
    callee.starts_with("air.store.device_coherent.")
        || callee.starts_with("air.store.system_coherent.")
}

fn is_coherent_air_load(callee: &str) -> bool {
    callee.starts_with("air.load.device_coherent.")
        || callee.starts_with("air.load.system_coherent.")
}

fn air_i32_literal(value: &LlValue) -> Option<i64> {
    match value {
        LlValue::Int(value) => Some(*value as i64),
        LlValue::SignedInt(value) => Some(*value),
        _ => None,
    }
}

/// Element lane count if `ty` is a bf16 scalar/vector (bf16 has no SPIR-V float type — it is modeled as
/// its `Int(16)` bit pattern, so arithmetic must round-trip through f32). Returns `1` for a scalar
/// `BFloat`, `N` for `Vector(BFloat, N)`, and `None` for any non-bf16 type. Purely structural (element
/// type + shape), never keyed on a name.
fn bfloat_lanes(ty: &LlType) -> Option<u32> {
    match ty {
        LlType::BFloat => Some(1),
        LlType::Vector(elem, n) if **elem == LlType::BFloat => Some(*n),
        _ => None,
    }
}

/// `elem` for `n <= 1`, else `Vector(elem, n)` — the scalar-or-vector shape used by the shaped bf16
/// widen/narrow helpers.
fn shaped_type(elem: LlType, n: u32) -> LlType {
    if n <= 1 {
        elem
    } else {
        LlType::Vector(Box::new(elem), n)
    }
}