lib/std/lang/gen/regalloc/liveness/tests.rad 3.0 KiB raw
1
//! Tests for liveness analysis.
2
3
use std::testing;
4
use std::lang::alloc;
5
use std::lang::il;
6
use std::lang::gen::bitset;
7
8
9
/// Construct a block whose instruction storage belongs to the caller.
10
unsafe fn block(name: *[u8], instructions: *unsafe mut [il::Instr]) -> il::Block {
11
    return il::Block { label: name, params: &[], instrs: instructions,
12
        locs: &[], preds: &[], loopDepth: 0 };
13
}
14
15
/// Check one bit in each word of a three-word row.
16
fn check(words: &[u32], first: bool, second: bool, third: bool) throws (testing::TestError) {
17
    try testing::expect(words.len == 3);
18
    try testing::expect(bitset::contains(words, 0) == first);
19
    try testing::expect(bitset::contains(words, 33) == second);
20
    try testing::expect(bitset::contains(words, 66) == third);
21
}
22
23
@test unsafe fn testLoopLiveness() throws (testing::TestError) {
24
    let r0 = il::Reg { n: 0 };
25
    let r33 = il::Reg { n: 33 };
26
    let r66 = il::Reg { n: 66 };
27
    let mut entry = [
28
        il::Instr::Copy { dst: r0, val: il::Val::Imm(7) },
29
        il::Instr::Jmp { target: 1, args: &mut [] },
30
    ];
31
    let mut head = [
32
        il::Instr::Copy { dst: r33, val: il::Val::Reg(r0) },
33
        il::Instr::Br { op: il::CmpOp::Eq, typ: il::Type::W64,
34
            a: il::Val::Reg(r33), b: il::Val::Imm(0),
35
            thenTarget: 2, thenArgs: &mut [], elseTarget: 3, elseArgs: &mut [] },
36
    ];
37
    let mut body = [
38
        il::Instr::BinOp { op: il::BinOp::Add, typ: il::Type::W64,
39
            dst: r66, a: il::Val::Reg(r33), b: il::Val::Imm(1) },
40
        il::Instr::Jmp { target: 1, args: &mut [] },
41
    ];
42
    let mut exit = [il::Instr::Ret { val: il::Val::Reg(r33) }];
43
    let blocks = [block("entry", &mut entry[..]), block("head", &mut head[..]),
44
        block("body", &mut body[..]), block("exit", &mut exit[..])];
45
    let function = il::Fn { name: "loop", params: &[], returnType: il::Type::W64,
46
        isExtern: false, isLeaf: true, blocks: &blocks[..] };
47
    static DATA: [u8; 8192] = [0; 8192];
48
    let mut arena = alloc::new(&mut DATA[..]);
49
    let mut answer: u32 = 0;
50
    use arena as analysis in {
51
        let live = try! super::analyze(&function, &analysis);
52
        try testing::expect(live.blockCount == 4);
53
        try testing::expect(live.maxReg == 67);
54
        try testing::expect(live.words == 3);
55
        try check(super::liveInRow(&live, 0), false, false, false);
56
        try check(super::liveOutRow(&live, 0), true, false, false);
57
        try check(super::liveInRow(&live, 1), true, false, false);
58
        try check(super::liveOutRow(&live, 1), true, true, false);
59
        try check(super::liveInRow(&live, 2), true, true, false);
60
        try check(super::liveOutRow(&live, 2), true, false, false);
61
        try check(super::liveInRow(&live, 3), false, true, false);
62
        try check(super::liveOutRow(&live, 3), false, false, false);
63
        try check(&live.defs[6..9], false, false, true);
64
        try check(&live.uses[6..9], false, true, false);
65
        set answer = 42;
66
    }
67
    alloc::reset(&mut arena);
68
    try testing::expect(answer == 42);
69
}