use super::*;

#[test]
fn merge_consecutive_hints() {
    let ops = vec![
        TIROp::Hint(1),
        TIROp::Hint(1),
        TIROp::Hint(1),
        TIROp::Add,
        TIROp::Hint(1),
        TIROp::Hint(1),
    ];
    let result = optimize(ops);
    assert_eq!(result.len(), 3);
    assert!(matches!(result[0], TIROp::Hint(3)));
    assert!(matches!(result[1], TIROp::Add));
    assert!(matches!(result[2], TIROp::Hint(2)));
}

#[test]
fn merge_consecutive_pops() {
    let ops = vec![TIROp::Pop(2), TIROp::Pop(3), TIROp::Pop(1)];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Pop(5)));
    assert!(matches!(result[1], TIROp::Pop(1)));
}

#[test]
fn eliminate_swap_zero() {
    let ops = vec![TIROp::Push(1), TIROp::Swap(0), TIROp::Add];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Push(1)));
    assert!(matches!(result[1], TIROp::Add));
}

#[test]
fn eliminate_spill_reload_pair() {
    let addr = 1 << 30;
    let ops = vec![
        TIROp::Push(42),
        TIROp::Push(addr),
        TIROp::Swap(1),
        TIROp::WriteMem(1),
        TIROp::Pop(1),
        TIROp::Add,
        TIROp::Push(addr),
        TIROp::ReadMem(1),
        TIROp::Pop(1),
    ];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Push(42)));
    assert!(matches!(result[1], TIROp::Add));
}

#[test]
fn eliminate_dead_store() {
    let addr = 1 << 30;
    let ops = vec![
        TIROp::Push(42),
        TIROp::Push(addr),
        TIROp::Swap(1),
        TIROp::WriteMem(1),
        TIROp::Pop(1),
        TIROp::Add,
    ];
    let result = optimize(ops);
    assert!(result.iter().any(|op| matches!(op, TIROp::Pop(_))));
    assert!(!result.iter().any(|op| matches!(op, TIROp::WriteMem(_))));
}

#[test]
fn no_eliminate_when_multiple_reads() {
    let addr = 1 << 30;
    let ops = vec![
        TIROp::Push(addr),
        TIROp::Swap(1),
        TIROp::WriteMem(1),
        TIROp::Pop(1),
        TIROp::Push(addr),
        TIROp::ReadMem(1),
        TIROp::Pop(1),
        TIROp::Push(addr),
        TIROp::ReadMem(1),
        TIROp::Pop(1),
    ];
    let result = optimize(ops);
    assert_eq!(result.len(), 10);
}

#[test]
fn eliminate_dup0_pop1_nop() {
    let ops = vec![TIROp::Push(42), TIROp::Dup(0), TIROp::Pop(1), TIROp::Add];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Push(42)));
    assert!(matches!(result[1], TIROp::Add));
}

#[test]
fn eliminate_dup0_swap1_pop1_nop() {
    let ops = vec![
        TIROp::Push(42),
        TIROp::Dup(0),
        TIROp::Swap(1),
        TIROp::Pop(1),
        TIROp::Add,
    ];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Push(42)));
    assert!(matches!(result[1], TIROp::Add));
}

#[test]
fn eliminate_double_swap() {
    let ops = vec![TIROp::Push(1), TIROp::Swap(15), TIROp::Swap(15), TIROp::Add];
    let result = optimize(ops);
    assert_eq!(result.len(), 2);
    assert!(matches!(result[0], TIROp::Push(1)));
    assert!(matches!(result[1], TIROp::Add));
}

#[test]
fn eliminate_many_double_swaps() {
    let mut ops = Vec::new();
    for _ in 0..12 {
        ops.push(TIROp::Swap(15));
    }
    ops.push(TIROp::Return);
    let result = optimize(ops);
    assert_eq!(result.len(), 1);
    assert!(matches!(result[0], TIROp::Return));
}

#[test]
fn collapse_epilogue_swap_pop_chain() {
    let ops = vec![
        TIROp::Swap(5),
        TIROp::Pop(1),
        TIROp::Swap(4),
        TIROp::Pop(1),
        TIROp::Swap(3),
        TIROp::Pop(1),
        TIROp::Return,
    ];
    let result = optimize(ops);
    assert!(matches!(result[0], TIROp::Swap(5)));
    assert!(matches!(result[1], TIROp::Pop(3)));
    assert!(matches!(result[2], TIROp::Return));
}

#[test]
fn collapse_constant_depth_swap1_pop1_chain() {
    // 10x swap 1; pop 1 -> swap 10; pop 5; pop 5
    let mut ops = Vec::new();
    for _ in 0..10 {
        ops.push(TIROp::Swap(1));
        ops.push(TIROp::Pop(1));
    }
    ops.push(TIROp::Return);
    let result = optimize(ops);
    assert!(matches!(result[0], TIROp::Swap(10)));
    assert!(matches!(result[1], TIROp::Pop(5)));
    assert!(matches!(result[2], TIROp::Pop(5)));
    assert!(matches!(result[3], TIROp::Return));
    assert_eq!(result.len(), 4);
}

#[test]
fn collapse_large_constant_depth_chain() {
    // 24x swap 1; pop 1 -> swap 15; pop 5; pop 5; pop 5; swap 9; pop 5; pop 4
    let mut ops = Vec::new();
    for _ in 0..24 {
        ops.push(TIROp::Swap(1));
        ops.push(TIROp::Pop(1));
    }
    ops.push(TIROp::Return);
    let result = optimize(ops);
    // First chunk: swap 15; pop 5; pop 5; pop 5
    assert!(matches!(result[0], TIROp::Swap(15)));
    assert!(matches!(result[1], TIROp::Pop(5)));
    assert!(matches!(result[2], TIROp::Pop(5)));
    assert!(matches!(result[3], TIROp::Pop(5)));
    // Second chunk: swap 9; pop 5; pop 4
    assert!(matches!(result[4], TIROp::Swap(9)));
    assert!(matches!(result[5], TIROp::Pop(5)));
    assert!(matches!(result[6], TIROp::Pop(4)));
    assert!(matches!(result[7], TIROp::Return));
    assert_eq!(result.len(), 8);
}

#[test]
fn collapse_constant_depth_swap_k_pop1_chain() {
    // 5x swap 3; pop 1 (width-3 return, 5 dead locals) ->
    // swap 7; swap 6; swap 5; swap 4; swap 3; pop 5 (batch pop)
    let mut ops = Vec::new();
    for _ in 0..5 {
        ops.push(TIROp::Swap(3));
        ops.push(TIROp::Pop(1));
    }
    ops.push(TIROp::Return);
    let result = optimize(ops);
    // D=3, count=5, total_depth = 3+5-1 = 7 (<=15)
    assert!(matches!(result[0], TIROp::Swap(7)));
    assert!(matches!(result[1], TIROp::Swap(6)));
    assert!(matches!(result[2], TIROp::Swap(5)));
    assert!(matches!(result[3], TIROp::Swap(4)));
    assert!(matches!(result[4], TIROp::Swap(3)));
    assert!(matches!(result[5], TIROp::Pop(5)));
    assert!(matches!(result[6], TIROp::Return));
    assert_eq!(result.len(), 7); // was 11
}

#[test]
fn collapse_constant_depth_swap_k_large_chain() {
    // 4x swap 5; pop 1 -- total_depth = 5+4-1 = 8 (<=15)
    let mut ops = Vec::new();
    for _ in 0..4 {
        ops.push(TIROp::Swap(5));
        ops.push(TIROp::Pop(1));
    }
    let result = optimize(ops);
    assert!(matches!(result[0], TIROp::Swap(8)));
    assert!(matches!(result[1], TIROp::Swap(7)));
    assert!(matches!(result[2], TIROp::Swap(6)));
    assert!(matches!(result[3], TIROp::Swap(5)));
    assert!(matches!(result[4], TIROp::Pop(4)));
    assert_eq!(result.len(), 5); // was 8
}

#[test]
fn optimize_nested_bodies() {
    let ops = vec![TIROp::IfElse {
        then_body: vec![TIROp::Hint(1), TIROp::Hint(1)],
        else_body: vec![TIROp::Pop(0)],
    }];
    let result = optimize(ops);
    if let TIROp::IfElse {
        then_body,
        else_body,
    } = &result[0]
    {
        assert_eq!(then_body.len(), 1);
        assert!(matches!(then_body[0], TIROp::Hint(2)));
        assert!(else_body.is_empty());
    } else {
        panic!("expected IfElse");
    }
}

Dimensions

trident/src/deploy/tests.rs
cw-cyber/contracts/hub-skills/src/tests.rs
trident/src/lsp/semantic/tests.rs
trident/src/syntax/format/tests.rs
cw-cyber/contracts/hub-libs/src/tests.rs
cw-cyber/contracts/hub-channels/src/tests.rs
trident/src/package/registry/tests.rs
trident/src/syntax/lexer/tests.rs
trident/src/cost/stack_verifier/tests.rs
cw-cyber/contracts/hub-networks/src/tests.rs
trident/src/verify/sym/tests.rs
cw-cyber/contracts/cw-cyber-subgraph/src/tests.rs
cw-cyber/contracts/cw-cyber-gift/src/tests.rs
trident/src/verify/report/tests.rs
trident/src/package/store/tests.rs
cw-cyber/contracts/hub-tokens/src/tests.rs
trident/src/config/scaffold/tests.rs
trident/src/verify/solve/tests.rs
trident/src/verify/smt/tests.rs
cw-cyber/contracts/graph-filter/src/tests.rs
trident/src/package/manifest/tests.rs
trident/src/verify/synthesize/tests.rs
cw-cyber/contracts/cw-cyber-passport/src/tests.rs
trident/src/verify/equiv/tests.rs
trident/src/lsp/util/tests.rs
trident/src/config/resolve/tests.rs
trident/src/package/hash/tests.rs
trident/src/ir/lir/tests.rs
cw-cyber/contracts/hub-protocols/src/tests.rs
trident/src/syntax/grammar/tests.rs
trident/src/neural/data/tir_graph/tests.rs
trident/src/ir/tir/lower/tests.rs
trident/src/ir/tir/stack/tests.rs

Local Graph