compiler: Own lowering block storage
65bd5c224a104dccd0a2b1b755a2403a25764446d8afbd8cc737955a9d8ebc07
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 | + | } |