use vyre_foundation::ir::{BinOp, DataType};
use vyre_lower::{
rewrites::run_all_with_stats, verify, BindingLayout, BindingSlot, BindingVisibility, Dispatch,
KernelBody, KernelDescriptor, KernelOp, KernelOpKind, LiteralValue, MemoryClass,
};
fn main() {
let bindings = vec![
BindingSlot {
slot: 0,
element_type: DataType::U32,
element_count: None,
memory_class: MemoryClass::Global,
visibility: BindingVisibility::ReadWrite,
name: "output".into(),
},
BindingSlot {
slot: 1,
element_type: DataType::U32,
element_count: None,
memory_class: MemoryClass::Global,
visibility: BindingVisibility::ReadWrite,
name: "scratch_a".into(),
},
BindingSlot {
slot: 2,
element_type: DataType::U32,
element_count: None,
memory_class: MemoryClass::Global,
visibility: BindingVisibility::ReadWrite,
name: "scratch_b".into(),
},
];
let ops = vec![
KernelOp {
kind: KernelOpKind::Literal,
operands: vec![0],
result: Some(0),
},
KernelOp {
kind: KernelOpKind::Literal,
operands: vec![1],
result: Some(1),
},
KernelOp {
kind: KernelOpKind::Literal,
operands: vec![2],
result: Some(2),
},
KernelOp {
kind: KernelOpKind::Literal,
operands: vec![3],
result: Some(3),
},
KernelOp {
kind: KernelOpKind::BinOpKind(BinOp::Add),
operands: vec![2, 0],
result: Some(4),
},
KernelOp {
kind: KernelOpKind::BinOpKind(BinOp::Mul),
operands: vec![2, 1],
result: Some(5),
},
KernelOp {
kind: KernelOpKind::BinOpKind(BinOp::Mul),
operands: vec![2, 0],
result: Some(6),
},
KernelOp {
kind: KernelOpKind::BinOpKind(BinOp::Mul),
operands: vec![2, 3],
result: Some(7),
},
KernelOp {
kind: KernelOpKind::StoreGlobal,
operands: vec![0, 0, 4], result: None,
},
KernelOp {
kind: KernelOpKind::LoadGlobal,
operands: vec![0, 0],
result: Some(8),
},
KernelOp {
kind: KernelOpKind::StoreGlobal,
operands: vec![0, 0, 7],
result: None,
},
];
let desc = KernelDescriptor {
id: "kitchen_sink".into(),
bindings: BindingLayout { slots: bindings },
dispatch: Dispatch::new(64, 1, 1),
body: KernelBody {
ops,
child_bodies: vec![],
literals: vec![
LiteralValue::U32(0),
LiteralValue::U32(1),
LiteralValue::U32(7),
LiteralValue::U32(8),
],
},
};
println!("=== before ===");
println!("ops: {}", desc.body.ops.len());
println!("bindings: {}", desc.bindings.slots.len());
println!("literals: {}", desc.body.literals.len());
let (optimized, stats) = run_all_with_stats(&desc);
println!();
println!("=== after run_all_with_stats ===");
println!(
"ops: {} ({} eliminated)",
stats.ops_after,
stats.ops_eliminated()
);
println!(
"bindings: {} ({} dropped)",
stats.bindings_after,
stats.bindings_dropped()
);
println!(
"literals: {} -> {}",
stats.literals_before, stats.literals_after
);
println!("iterations: {}", stats.iterations);
println!("converged: {}", stats.converged);
println!();
println!("=== verify ===");
match verify(&optimized) {
Ok(()) => println!("OK"),
Err(errs) => {
println!("FAIL ({} errors)", errs.len());
for e in &errs {
println!(" {e:?}");
}
std::process::exit(1);
}
}
println!();
println!("=== surviving ops ===");
for (i, op) in optimized.body.ops.iter().enumerate() {
println!(
" [{i:2}] {:?} operands={:?} -> {:?}",
op.kind, op.operands, op.result
);
}
println!();
println!("=== surviving bindings ===");
for s in &optimized.bindings.slots {
println!(" slot={} name={}", s.slot, s.name);
}
println!();
println!("=== surviving literals ===");
for (i, l) in optimized.body.literals.iter().enumerate() {
println!(" pool[{i}] = {l:?}");
}
}