compiler: Publish initialized block tables

5d23c002b618d3e5bfba77ea28fed3e82bbc58433c1f9b0c91fd5c2674f347f9
Alexis Sellier committed ago 1 parent 8a2ef421
lib/std/lang/lower.rad +4 -7
2755 2755
    preds.append(*pred, alloc::arenaAllocator(self.arena));
2756 2756
}
2757 2757
2758 2758
/// Finalize all blocks and return the block array.
2759 2759
unsafe fn finalizeBlocks 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function) -> *unsafe [il::Block] throws (LowerError) where 'arena: 'phase, 'phase: 'function {
2760 -
    let blockCount = self.blockData.len;
2761 -
    let blocks = try! alloc::allocRawSlice(
2762 -
        self.arena, @sizeOf(il::Block), @alignOf(il::Block), blockCount
2763 -
    ) as *unsafe mut [il::Block];
2760 +
    let mut blocks: *mut [il::Block] = &mut [];
2764 2761
2765 2762
    for i in 0..self.blockData.len {
2766 2763
        let data = &self.blockData[i];
2767 2764
2768 -
        set blocks[i] = il::Block {
2765 +
        blocks.append(il::Block {
2769 2766
            label: data.label,
2770 2767
            params: &data.params[..],
2771 2768
            instrs: data.instrs,
2772 2769
            locs: &data.locs[..],
2773 2770
            preds: &data.preds[..],
2774 2771
            loopDepth: data.loopDepth,
2775 -
        };
2772 +
        }, alloc::arenaAllocator(self.arena));
2776 2773
    }
2777 -
    return &blocks[..self.blockData.len];
2774 +
    return (&blocks[..]) as *unsafe [il::Block];
2778 2775
}
2779 2776
2780 2777
/////////////////////
2781 2778
// Loop Management //
2782 2779
/////////////////////
test/tests/block.finalization.flow.rad added +67 -0
1 +
//! returns: 0
2 +
3 +
/// Carry several values through nested loop, continue, break, and match edges.
4 +
fn run(limit: u32) -> u32 {
5 +
    let mut total: u32 = 0;
6 +
    let mut count: u32 = 0;
7 +
    let mut left: u32 = 3;
8 +
    let mut right: u32 = 7;
9 +
    for outer in 0..limit {
10 +
        if outer == 2 {
11 +
            continue;
12 +
        }
13 +
        let mut inner: u32 = 0;
14 +
        loop {
15 +
            if inner == limit {
16 +
                break;
17 +
            }
18 +
            let current = inner;
19 +
            set inner += 1;
20 +
            if current == 1 {
21 +
                continue;
22 +
            }
23 +
            let saved = left;
24 +
            set left = right;
25 +
            set right = saved;
26 +
            match current % 3 {
27 +
                case 0 => set total += left,
28 +
                case 1 if outer > 0 => set total += right,
29 +
                else => set total += left + right,
30 +
            }
31 +
            set count += 1;
32 +
        }
33 +
    }
34 +
    return total + count * 100 + left * 10000 + right * 100000;
35 +
}
36 +
37 +
/// Compute the same result with bounded loops and explicit selection.
38 +
fn expected(limit: u32) -> u32 {
39 +
    let mut total: u32 = 0;
40 +
    let mut count: u32 = 0;
41 +
    for outer in 0..limit {
42 +
        for inner in 0..limit {
43 +
            if outer <> 2 and inner <> 1 {
44 +
                set count += 1;
45 +
                let left: u32 = 7 if count % 2 == 1 else 3;
46 +
                let right: u32 = 10 - left;
47 +
                if inner % 3 == 0 {
48 +
                    set total += left;
49 +
                } else if inner % 3 == 1 and outer > 0 {
50 +
                    set total += right;
51 +
                } else {
52 +
                    set total += 10;
53 +
                }
54 +
            }
55 +
        }
56 +
    }
57 +
    let left: u32 = 7 if count % 2 == 1 else 3;
58 +
    return total + count * 100 + left * 10000 + (10 - left) * 100000;
59 +
}
60 +
61 +
/// Check empty loops and repeated execution of every control-flow edge.
62 +
@default fn main() -> u32 {
63 +
    for limit in 0..9 {
64 +
        assert run(limit) == expected(limit);
65 +
    }
66 +
    return 0;
67 +
}