weirflow 0.1.0

GPU-first dataflow analysis primitives for Vyre and Santh compiler pipelines.
Documentation
//! `weir::def_use`  -  def-use chain query over a constructed SsaForm.
//!
//! Op id: `weir::tests::df::def_use`. Soundness: `Exact`  -  the
//! query is a pure lookup into the SSA form's def_use_chains map
//! plus dense bitset packing. Tests pin the lookup, sort+dedup
//! contract, unknown-definition rejection, and bitset packing against
//! hand-constructed SsaForm values.

use std::collections::HashMap;

use weir::def_use::{try_def_use_chain, try_def_use_chain_bitset};
use weir::ssa::SsaForm;

fn make_form(chains: &[(u32, Vec<u32>)]) -> SsaForm {
    let mut def_use_chains = HashMap::new();
    for (def_version, uses) in chains {
        def_use_chains.insert(*def_version, uses.clone());
    }
    SsaForm {
        phi_nodes: HashMap::new(),
        renamed_usages: HashMap::new(),
        def_use_chains,
    }
}

#[test]
fn unknown_def_version_is_rejected_not_treated_as_empty() {
    let form = make_form(&[]);
    let err = try_def_use_chain(&form, 99).expect_err("unknown def version must fail");
    assert!(
        err.contains("unknown SSA definition version 99"),
        "unexpected diagnostic: {err}"
    );
}

#[test]
fn def_use_chain_sorts_and_dedupes() {
    let form = make_form(&[(1, vec![5, 2, 5, 8, 2])]);
    assert_eq!(
        try_def_use_chain(&form, 1).expect("known def version must resolve"),
        vec![2, 5, 8]
    );
}

#[test]
fn def_use_chain_bitset_packs_uses_correctly() {
    let form = make_form(&[(1, vec![0, 5, 17])]);
    // bits 0, 5, 17 → word 0 has bit 0 + bit 5 = 0x21, word 0 also has bit 17 = 0x21 | 0x20000.
    let bits =
        try_def_use_chain_bitset(&form, 1, 64).expect("known def version bitset must resolve");
    assert!(!bits.is_empty());
    let combined: u32 = bits[0];
    assert!(combined & 1 != 0, "bit 0 set");
    assert!(combined & (1 << 5) != 0, "bit 5 set");
    assert!(combined & (1 << 17) != 0, "bit 17 set");
}

#[test]
fn def_use_chain_bitset_drops_uses_beyond_node_count() {
    let form = make_form(&[(1, vec![0, 1000])]);
    // node_count=64 → max addressable bit is 63; use 1000 dropped.
    let bits =
        try_def_use_chain_bitset(&form, 1, 64).expect("known def version bitset must resolve");
    let combined: u32 = bits[0];
    assert!(combined & 1 != 0, "bit 0 set");
    // bit for use_id=1000 should not appear anywhere in the bitset.
    assert!(
        bits.iter().all(|w| (*w & !1) == 0),
        "no bits beyond node_count should be set; got {bits:?}"
    );
}

#[test]
fn def_use_chain_bitset_handles_zero_node_count() {
    let form = make_form(&[(1, vec![0, 1, 2])]);
    let bits =
        try_def_use_chain_bitset(&form, 1, 0).expect("known def version bitset must resolve");
    assert!(bits.iter().all(|w| *w == 0));
}