compiler: Publish initialized block tables
5d23c002b618d3e5bfba77ea28fed3e82bbc58433c1f9b0c91fd5c2674f347f9
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 | + | } |