compiler: Own lowering block storage

65bd5c224a104dccd0a2b1b755a2403a25764446d8afbd8cc737955a9d8ebc07
Alexis Sellier committed ago 1 parent 3b4ce6f2
lib/std/lang/lower.rad +3 -2
743 743
    paramsLen: u32,
744 744
745 745
    // ~ Basic block management ~ //
746 746
747 747
    /// Block storage array, indexed by block id.
748 -
    blockData: *unsafe mut [BlockData],
748 +
    blockData: *mut [BlockData],
749 749
    /// The entry block for this function.
750 750
    entryBlock: ?BlockId,
751 751
    /// The block currently receiving new instructions.
752 752
    currentBlock: ?BlockId,
753 753
2765 2765
}
2766 2766
2767 2767
/// Finalize all blocks and return the block array.
2768 2768
unsafe fn finalizeBlocks 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function) -> *unsafe [il::Block] throws (LowerError) where 'arena: 'phase, 'phase: 'function {
2769 2769
    let mut blocks: *mut [il::Block] = &mut [];
2770 +
    let allocator = alloc::arenaAllocator(self.arena);
2770 2771
2771 2772
    for i in 0..self.blockData.len {
2772 2773
        let data = &self.blockData[i];
2773 2774
2774 2775
        blocks.append(il::Block {
2776 2777
            params: &data.params[..],
2777 2778
            instrs: data.instrs,
2778 2779
            locs: &data.locs[..],
2779 2780
            preds: &data.preds[..],
2780 2781
            loopDepth: data.loopDepth,
2781 -
        }, alloc::arenaAllocator(self.arena));
2782 +
        }, allocator);
2782 2783
    }
2783 2784
    return (&blocks[..]) as *unsafe [il::Block];
2784 2785
}
2785 2786
2786 2787
/////////////////////
test/tests/ssa.block.storage.rad added +46 -0
1 +
//! returns: 0
2 +
3 +
/// Exercise repeated block joins, loop back edges, and early exits.
4 +
fn run(limit: u32, skip: bool) -> u32 {
5 +
    let mut total: u32 = 7;
6 +
    let mut index: u32 = 0;
7 +
    while index < limit {
8 +
        set index += 1;
9 +
        if skip and index % 2 == 0 {
10 +
            continue;
11 +
        }
12 +
        let mut value: u32 = 0;
13 +
        match index % 4 {
14 +
            case 0 => set value = 11,
15 +
            case 1 => set value = 13,
16 +
            case 2 => set value = 17,
17 +
            else => set value = 19,
18 +
        }
19 +
        if index > 15 {
20 +
            break;
21 +
        }
22 +
        set total += value;
23 +
    }
24 +
    return total;
25 +
}
26 +
27 +
/// Compare repeated branch and loop execution with a straight-line reference.
28 +
@default fn main() -> u32 {
29 +
    let values = [11 as u32, 13, 17, 19];
30 +
    for limit in 0..24 {
31 +
        let mut all: u32 = 7;
32 +
        let mut odd: u32 = 7;
33 +
        for index in 1..16 {
34 +
            if index <= limit {
35 +
                set all += values[index % 4];
36 +
                if index % 2 <> 0 {
37 +
                    set odd += values[index % 4];
38 +
                }
39 +
            }
40 +
        }
41 +
        assert run(limit, false) == all;
42 +
        assert run(limit, true) == odd;
43 +
        assert run(limit, false) == all;
44 +
    }
45 +
    return 0;
46 +
}